am f3aca5f7: (-s ours) am 8418a309: am 89d16f75: am 9b7b4450: am 02eab434: am 4d87d91d: Merge "If in a mobile captive portal is detected enable fail fast." into jb-mr2-dev

* commit 'f3aca5f7ca94aad3f0fe7068762474e8e3f98894':
diff --git a/Android.mk b/Android.mk
index b0a27e4..8fcac91 100644
--- a/Android.mk
+++ b/Android.mk
@@ -31,6 +31,10 @@
 # So we first build the framework as a monolithic static library then split it
 # up into smaller pieces.
 # ============================================================
+
+# embedded builds use nothing in frameworks/base
+ifneq ($(ANDROID_BUILD_EMBEDDED),true)
+
 include $(CLEAR_VARS)
 
 # FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk
@@ -105,9 +109,9 @@
 	core/java/android/content/IIntentReceiver.aidl \
 	core/java/android/content/IIntentSender.aidl \
 	core/java/android/content/IOnPrimaryClipChangedListener.aidl \
-	core/java/android/content/IAnonymousSyncAdapter.aidl \
 	core/java/android/content/ISyncAdapter.aidl \
 	core/java/android/content/ISyncContext.aidl \
+	core/java/android/content/ISyncServiceAdapter.aidl \
 	core/java/android/content/ISyncStatusObserver.aidl \
 	core/java/android/content/pm/IPackageDataObserver.aidl \
 	core/java/android/content/pm/IPackageDeleteObserver.aidl \
@@ -264,6 +268,9 @@
 	telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
 	telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
 	telephony/java/com/android/internal/telephony/ITelephony.aidl \
+	telephony/java/com/android/internal/telephony/IThirdPartyCallListener.aidl \
+	telephony/java/com/android/internal/telephony/IThirdPartyCallProvider.aidl \
+	telephony/java/com/android/internal/telephony/IThirdPartyCallService.aidl \
 	telephony/java/com/android/internal/telephony/ISms.aidl \
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
@@ -286,7 +293,7 @@
 
 LOCAL_MODULE := framework-base
 
-LOCAL_JAR_EXCLUDE_FILES := none
+LOCAL_RMTYPEDEFS := true
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
@@ -462,8 +469,8 @@
 # Common sources for doc check and api check
 common_src_files := \
 	$(call find-other-html-files, $(html_dirs)) \
-	$(addprefix ../../libcore/, $(call libcore_to_document, $(LOCAL_PATH)/../../libcore)) \
-	$(addprefix ../../external/junit/, $(call junit_to_document, $(LOCAL_PATH)/../../external/junit))
+	$(addprefix ../../libcore/, $(libcore_to_document)) \
+	$(addprefix ../../external/junit/, $(junit_to_document))
 
 # These are relative to frameworks/base
 framework_docs_LOCAL_SRC_FILES := \
@@ -542,8 +549,7 @@
 framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES := \
     frameworks/base/docs/knowntags.txt
 
-sample_dir := development/samples/browseable
-new_sample_dir := developers/samples/android
+samples_dir := development/samples/browseable
 
 # Whitelist of valid groups, used for default TOC grouping. Each sample must
 # belong to one (and only one) group. Assign samples to groups by setting
@@ -558,161 +564,6 @@
                  -samplegroup UI \
                  -samplegroup Views
 
-# the list here should match the list of samples included in the sdk samples package
-# (see development/build/sdk.atree)
-# remove htmlified samples for now -- samples are still available through the SDK
-web_docs_sample_code_flags := \
-		-hdf android.hasSamples 1 \
-		-samplecode $(sample_dir)/BasicAccessibility \
- 		            samples/BasicAccessibility "" \
-		-samplecode $(sample_dir)/HorizontalPaging \
- 		            samples/HorizontalPaging "" \
-		-samplecode $(sample_dir)/ShareActionProvider \
- 		            samples/ShareActionProvider "" \
-		-samplecode $(sample_dir)/Styled \
- 		            samples/Styled "" \
-		-samplecode $(sample_dir)/BasicAndroidKeyStore \
- 		            samples/BasicAndroidKeyStore "" \
-		-samplecode $(sample_dir)/Basic \
- 		            samples/Basic "" \
-		-samplecode $(sample_dir)/ImmersiveMode \
- 		            samples/ImmersiveMode "" \
-		-samplecode $(sample_dir)/repeatingAlarm \
- 		            samples/repeatingAlarm "" \
-		-samplecode $(sample_dir)/TextLinkify \
- 		            samples/TextLinkify "" \
-		-samplecode $(sample_dir)/BasicMediaRouter \
- 		            samples/BasicMediaRouter "" \
-		-samplecode $(sample_dir)/BasicMultitouch \
- 		            samples/BasicMultitouch "" \
-		-samplecode $(sample_dir)/TextSwitcher \
- 		            samples/TextSwitcher "" \
-		-samplecode $(sample_dir)/ActivityInstrumentation \
- 		            samples/ActivityInstrumentation "" \
-		-samplecode $(sample_dir)/BorderlessButtons \
- 		            samples/BorderlessButtons "" \
-		-samplecode $(sample_dir)/BasicNotifications \
- 		            samples/BasicNotifications "" \
-		-samplecode $(sample_dir)/AdvancedImmersiveMode \
- 		            samples/AdvancedImmersiveMode "" \
-		-samplecode $(sample_dir)/BluetoothLeGatt \
- 		            samples/BluetoothLeGatt "" \
-		-samplecode $(sample_dir)/NetworkConnect \
- 		            samples/NetworkConnect "" \
-		-samplecode $(sample_dir)/BasicNetworking \
- 		            samples/BasicNetworking "" \
-		-samplecode $(sample_dir)/BasicMediaDecoder \
- 		            samples/BasicMediaDecoder "" \
-		-samplecode $(sample_dir)/BasicImmersiveMode \
- 		            samples/BasicImmersiveMode "" \
-		-samplecode $(sample_dir)/CustomChoiceList \
- 		            samples/CustomChoiceList "" \
-		-samplecode $(sample_dir)/BasicContactables \
- 		            samples/BasicContactables "" \
-		-samplecode $(sample_dir)/BasicGestureDetect \
- 		            samples/BasicGestureDetect "" \
-		-samplecode $(sample_dir)/DoneBar \
- 		            samples/DoneBar "" \
-		-samplecode $(sample_dir)/ListPopupMenu \
- 		            samples/ListPopupMenu "" \
-		-samplecode $(sample_dir)/AppRestrictions \
- 		            samples/AppRestrictions "" \
-		-samplecode $(sample_dir)/CustomNotifications \
- 		            samples/CustomNotifications "" \
-		-samplecode $(sample_dir)/BasicSyncAdapter \
- 		            samples/BasicSyncAdapter "" \
-		-samplecode $(sample_dir)/StorageClient \
- 		            samples/StorageClient "" 
-#		-samplecode $(sample_dir)/StorageProvider \
-# 		            samples/StorageProvider "" 
-#       -samplecode $(sample_dir)/AndroidBeamDemo \
-# 		            samples/AndroidBeamDemo "Android Beam Demo" \
-# 		-samplecode $(sample_dir)/ApiDemos \
-# 		            samples/ApiDemos "API Demos" \
-# 		-samplecode $(sample_dir)/Support4Demos \
-# 		            samples/Support4Demos "API 4+ Support Demos" \
-# 		-samplecode $(sample_dir)/Support13Demos \
-# 		            samples/Support13Demos "API 13+ Support Demos" \
-# 		-samplecode $(sample_dir)/BackupRestore \
-# 		            samples/BackupRestore "Backup and Restore" \
-#		-samplecode $(sample_dir)/BluetoothChat \
-# 		            samples/BluetoothChat "Bluetooth Chat" \
-# 		-samplecode $(sample_dir)/BusinessCard \
-# 		            samples/BusinessCard "Business Card" \
-# 		-samplecode $(sample_dir)/ContactManager \
-# 		            samples/ContactManager "Contact Manager" \
-# 		-samplecode $(sample_dir)/CubeLiveWallpaper \
-# 		            samples/CubeLiveWallpaper "Cube Live Wallpaper" \
-# 		-samplecode $(sample_dir)/Home \
-# 		            samples/Home "Home" \
-# 		-samplecode $(sample_dir)/HoneycombGallery \
-# 		            samples/HoneycombGallery "Honeycomb Gallery" \
-# 		-samplecode $(sample_dir)/JetBoy \
-# 		            samples/JetBoy "JetBoy" \
-# 		-samplecode $(sample_dir)/KeyChainDemo \
-# 		            samples/KeyChainDemo "KeyChain Demo" \
-# 		-samplecode $(sample_dir)/LunarLander \
-# 		            samples/LunarLander "Lunar Lander" \
-# 		-samplecode $(sample_dir)/training/ads-and-ux \
-# 		            samples/training/ads-and-ux "Mobile Advertisement Integration" \
-# 		-samplecode $(sample_dir)/MultiResolution \
-# 		            samples/MultiResolution "Multiple Resolutions" \
-# 		-samplecode $(sample_dir)/training/multiscreen/newsreader \
-# 		            samples/newsreader "News Reader" \
-# 		-samplecode $(sample_dir)/NotePad \
-# 		            samples/NotePad "Note Pad" \
-# 		-samplecode $(sample_dir)/SpellChecker/SampleSpellCheckerService \
-# 		            samples/SpellChecker/SampleSpellCheckerService "Spell Checker Service" \
-# 		-samplecode $(sample_dir)/SpellChecker/HelloSpellChecker \
-# 		            samples/SpellChecker/HelloSpellChecker "Spell Checker Client" \
-# 		-samplecode $(sample_dir)/SampleSyncAdapter \
-# 		            samples/SampleSyncAdapter "Sample Sync Adapter" \
-# 		-samplecode $(sample_dir)/RandomMusicPlayer \
-# 		            samples/RandomMusicPlayer "Random Music Player" \
-# 		-samplecode $(sample_dir)/RenderScript \
-# 		            samples/RenderScript "RenderScript" \
-# 		-samplecode $(sample_dir)/SearchableDictionary \
-# 		            samples/SearchableDictionary "Searchable Dictionary v2" \
-# 		-samplecode $(sample_dir)/SipDemo \
-# 		            samples/SipDemo "SIP Demo" \
-# 		-samplecode $(sample_dir)/Snake \
-# 		            samples/Snake "Snake" \
-# 		-samplecode $(sample_dir)/SoftKeyboard \
-# 		            samples/SoftKeyboard "Soft Keyboard" \
-# 		-samplecode $(sample_dir)/Spinner  \
-# 		            samples/Spinner "Spinner" \
-# 		-samplecode $(sample_dir)/SpinnerTest \
-# 		            samples/SpinnerTest "SpinnerTest" \
-# 		-samplecode $(sample_dir)/StackWidget \
-# 		            samples/StackWidget "StackView Widget" \
-# 		-samplecode $(sample_dir)/TicTacToeLib  \
-# 		            samples/TicTacToeLib "TicTacToeLib" \
-# 		-samplecode $(sample_dir)/TicTacToeMain \
-# 		            samples/TicTacToeMain "TicTacToeMain" \
-# 		-samplecode $(sample_dir)/ToyVpn \
-# 		            samples/ToyVpn "Toy VPN Client" \
-# 		-samplecode $(sample_dir)/USB \
-# 		            samples/USB "USB" \
-# 		-samplecode $(sample_dir)/WeatherListWidget \
-# 		            samples/WeatherListWidget "Weather List Widget" \
-# 		-samplecode $(sample_dir)/WiFiDirectDemo \
-#                   samples/WiFiDirectDemo "Wi-Fi Direct Demo" \
-# 		-samplecode $(sample_dir)/Wiktionary \
-# 		            samples/Wiktionary "Wiktionary" \
-# 		-samplecode $(sample_dir)/WiktionarySimple \
-# 		            samples/WiktionarySimple "Wiktionary (Simplified)" \
-# 		-samplecode $(sample_dir)/VoiceRecognitionService \
-# 		            samples/VoiceRecognitionService "Voice Recognition Service" \
-# 		-samplecode $(sample_dir)/VoicemailProviderDemo \
-# 		            samples/VoicemailProviderDemo "Voicemail Provider Demo" \
-# 		-samplecode $(sample_dir)/XmlAdapters \
-# 		            samples/XmlAdapters "XML Adapters" \
-# 		-samplecode $(sample_dir)/TtsEngine \
-# 		            samples/TtsEngine "Text To Speech Engine" \
-# 		-samplecode $(sample_dir)/training/device-management-policy \
-# 		            samples/training/device-management-policy "Device Management Policy"
-
-
 ## SDK version identifiers used in the published docs
   # major[.minor] version for current SDK. (full releases only)
 framework_docs_SDK_VERSION:=4.4
@@ -722,7 +573,7 @@
 framework_docs_LOCAL_DROIDDOC_OPTIONS += \
 		-hdf sdk.version $(framework_docs_SDK_VERSION) \
 		-hdf sdk.rel.id $(framework_docs_SDK_REL_ID) \
-		-hdf sdk.preview 0 \
+		-hdf sdk.preview 0
 
 # ====  the api stubs and current.xml ===========================
 include $(CLEAR_VARS)
@@ -808,8 +659,6 @@
 		-todo $(OUT_DOCS)/$(LOCAL_MODULE)-docs-todo.html \
 		-sdkvalues $(OUT_DOCS) \
 		-hdf android.whichdoc offline
-#		$(web_docs_sample_code_flags)
-
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
 
@@ -836,7 +685,7 @@
 LOCAL_DROIDDOC_HTML_DIR:=$(framework_docs_LOCAL_DROIDDOC_HTML_DIR)
 LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_ADDITIONAL_JAVA_DIR)
 LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES)
-LOCAL_ADDITIONAL_HTML_DIR:=docs/html-intl /intl/
+LOCAL_ADDITIONAL_HTML_DIR:=docs/html-intl /
 
 LOCAL_MODULE := online-sdk
 
@@ -845,7 +694,8 @@
 		-toroot / \
 		-hdf android.whichdoc online \
 		$(sample_groups) \
-		$(web_docs_sample_code_flags)
+		-hdf android.hasSamples true \
+		-samplesdir $(samples_dir)
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
 
@@ -863,7 +713,7 @@
 LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_ADDITIONAL_JAVA_DIR)
 LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES)
 # specify a second html input dir and an output path relative to OUT_DIR)
-LOCAL_ADDITIONAL_HTML_DIR:=docs/html-intl /
+LOCAL_ADDITIONAL_HTML_DIR:=docs/html-intl/intl /
 
 LOCAL_MODULE := ds
 
@@ -873,7 +723,6 @@
 		-toroot / \
 		-hdf android.whichdoc online \
 		-hdf devsite true
-#		$(web_docs_sample_code_flags)
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
 
@@ -943,3 +792,5 @@
 ifeq (,$(ONE_SHOT_MAKEFILE))
 include $(call first-makefiles-under,$(LOCAL_PATH))
 endif
+
+endif # ANDROID_BUILD_EMBEDDED
diff --git a/CleanSpec.mk b/CleanSpec.mk
index cfa8be9..2fa195c 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -171,6 +171,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/printservice/)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/packages/services/Proxy/)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrinterDiscoverySessionObserver.*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrinterDiscoverySessionClient.*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/os/IBattery*)
diff --git a/api/current.txt b/api/current.txt
index 8e69592..11a5f77 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9,6 +9,7 @@
     field public static final java.lang.String ACCESS_CHECKIN_PROPERTIES = "android.permission.ACCESS_CHECKIN_PROPERTIES";
     field public static final java.lang.String ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION";
     field public static final java.lang.String ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION";
+    field public static final java.lang.String ACCESS_INPUT_FLINGER = "android.permission.ACCESS_INPUT_FLINGER";
     field public static final java.lang.String ACCESS_LOCATION_EXTRA_COMMANDS = "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS";
     field public static final java.lang.String ACCESS_MOCK_LOCATION = "android.permission.ACCESS_MOCK_LOCATION";
     field public static final java.lang.String ACCESS_NETWORK_STATE = "android.permission.ACCESS_NETWORK_STATE";
@@ -497,6 +498,7 @@
     field public static final int fastScrollOverlayPosition = 16843578; // 0x101033a
     field public static final int fastScrollPreviewBackgroundLeft = 16843575; // 0x1010337
     field public static final int fastScrollPreviewBackgroundRight = 16843576; // 0x1010338
+    field public static final int fastScrollStyle = 16843763; // 0x10103f3
     field public static final int fastScrollTextColor = 16843609; // 0x1010359
     field public static final int fastScrollThumbDrawable = 16843574; // 0x1010336
     field public static final int fastScrollTrackDrawable = 16843577; // 0x1010339
@@ -522,6 +524,7 @@
     field public static final int format12Hour = 16843722; // 0x10103ca
     field public static final int format24Hour = 16843723; // 0x10103cb
     field public static final int fragment = 16843491; // 0x10102e3
+    field public static final int fragmentBreadCrumbsStyle = 16843762; // 0x10103f2
     field public static final int fragmentCloseEnterAnimation = 16843495; // 0x10102e7
     field public static final int fragmentCloseExitAnimation = 16843496; // 0x10102e8
     field public static final int fragmentFadeEnterAnimation = 16843497; // 0x10102e9
@@ -1204,6 +1207,8 @@
     field public static final int windowBackground = 16842836; // 0x1010054
     field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b
     field public static final int windowContentOverlay = 16842841; // 0x1010059
+    field public static final int windowContentTransitionManager = 16843765; // 0x10103f5
+    field public static final int windowContentTransitions = 16843764; // 0x10103f4
     field public static final int windowDisablePreview = 16843298; // 0x1010222
     field public static final int windowEnableSplitTouch = 16843543; // 0x1010317
     field public static final int windowEnterAnimation = 16842932; // 0x10100b4
@@ -1807,6 +1812,7 @@
     field public static final int Theme_NoTitleBar_Fullscreen = 16973831; // 0x1030007
     field public static final int Theme_NoTitleBar_OverlayActionModes = 16973930; // 0x103006a
     field public static final int Theme_Panel = 16973913; // 0x1030059
+    field public static final int Theme_Quantum = 16974318; // 0x10301ee
     field public static final int Theme_Translucent = 16973839; // 0x103000f
     field public static final int Theme_Translucent_NoTitleBar = 16973840; // 0x1030010
     field public static final int Theme_Translucent_NoTitleBar_Fullscreen = 16973841; // 0x1030011
@@ -1863,6 +1869,8 @@
     field public static final int Widget_DeviceDefault_DropDownItem_Spinner = 16974178; // 0x1030162
     field public static final int Widget_DeviceDefault_EditText = 16974154; // 0x103014a
     field public static final int Widget_DeviceDefault_ExpandableListView = 16974155; // 0x103014b
+    field public static final int Widget_DeviceDefault_FastScroll = 16974316; // 0x10301ec
+    field public static final int Widget_DeviceDefault_FragmentBreadCrumbs = 16974311; // 0x10301e7
     field public static final int Widget_DeviceDefault_GridView = 16974156; // 0x103014c
     field public static final int Widget_DeviceDefault_HorizontalScrollView = 16974171; // 0x103015b
     field public static final int Widget_DeviceDefault_ImageButton = 16974157; // 0x103014d
@@ -1896,6 +1904,8 @@
     field public static final int Widget_DeviceDefault_Light_DropDownItem_Spinner = 16974233; // 0x1030199
     field public static final int Widget_DeviceDefault_Light_EditText = 16974206; // 0x103017e
     field public static final int Widget_DeviceDefault_Light_ExpandableListView = 16974207; // 0x103017f
+    field public static final int Widget_DeviceDefault_Light_FastScroll = 16974317; // 0x10301ed
+    field public static final int Widget_DeviceDefault_Light_FragmentBreadCrumbs = 16974312; // 0x10301e8
     field public static final int Widget_DeviceDefault_Light_GridView = 16974208; // 0x1030180
     field public static final int Widget_DeviceDefault_Light_HorizontalScrollView = 16974226; // 0x1030192
     field public static final int Widget_DeviceDefault_Light_ImageButton = 16974209; // 0x1030181
@@ -1952,6 +1962,7 @@
     field public static final int Widget_DropDownItem_Spinner = 16973868; // 0x103002c
     field public static final int Widget_EditText = 16973859; // 0x1030023
     field public static final int Widget_ExpandableListView = 16973860; // 0x1030024
+    field public static final int Widget_FastScroll = 16974313; // 0x10301e9
     field public static final int Widget_FragmentBreadCrumbs = 16973961; // 0x1030089
     field public static final int Widget_Gallery = 16973877; // 0x1030035
     field public static final int Widget_GridView = 16973874; // 0x1030032
@@ -1983,6 +1994,8 @@
     field public static final int Widget_Holo_DropDownItem_Spinner = 16973995; // 0x10300ab
     field public static final int Widget_Holo_EditText = 16973971; // 0x1030093
     field public static final int Widget_Holo_ExpandableListView = 16973972; // 0x1030094
+    field public static final int Widget_Holo_FastScroll = 16974314; // 0x10301ea
+    field public static final int Widget_Holo_FragmentBreadCrumbs = 16974309; // 0x10301e5
     field public static final int Widget_Holo_GridView = 16973973; // 0x1030095
     field public static final int Widget_Holo_HorizontalScrollView = 16973988; // 0x10300a4
     field public static final int Widget_Holo_ImageButton = 16973974; // 0x1030096
@@ -2016,6 +2029,8 @@
     field public static final int Widget_Holo_Light_DropDownItem_Spinner = 16974041; // 0x10300d9
     field public static final int Widget_Holo_Light_EditText = 16974014; // 0x10300be
     field public static final int Widget_Holo_Light_ExpandableListView = 16974015; // 0x10300bf
+    field public static final int Widget_Holo_Light_FastScroll = 16974315; // 0x10301eb
+    field public static final int Widget_Holo_Light_FragmentBreadCrumbs = 16974310; // 0x10301e6
     field public static final int Widget_Holo_Light_GridView = 16974016; // 0x10300c0
     field public static final int Widget_Holo_Light_HorizontalScrollView = 16974034; // 0x10300d2
     field public static final int Widget_Holo_Light_ImageButton = 16974017; // 0x10300c1
@@ -2434,11 +2449,23 @@
     method public java.lang.Object evaluate(float, java.lang.Object, java.lang.Object);
   }
 
+  public class FloatArrayEvaluator implements android.animation.TypeEvaluator {
+    ctor public FloatArrayEvaluator();
+    ctor public FloatArrayEvaluator(float[]);
+    method public float[] evaluate(float, float[], float[]);
+  }
+
   public class FloatEvaluator implements android.animation.TypeEvaluator {
     ctor public FloatEvaluator();
     method public java.lang.Float evaluate(float, java.lang.Number, java.lang.Number);
   }
 
+  public class IntArrayEvaluator implements android.animation.TypeEvaluator {
+    ctor public IntArrayEvaluator();
+    ctor public IntArrayEvaluator(int[]);
+    method public int[] evaluate(float, int[], int[]);
+  }
+
   public class IntEvaluator implements android.animation.TypeEvaluator {
     ctor public IntEvaluator();
     method public java.lang.Integer evaluate(float, java.lang.Integer, java.lang.Integer);
@@ -2507,18 +2534,39 @@
     ctor public ObjectAnimator();
     method public java.lang.String getPropertyName();
     method public java.lang.Object getTarget();
+    method public static android.animation.ObjectAnimator ofArgb(java.lang.Object, java.lang.String, int...);
+    method public static android.animation.ObjectAnimator ofArgb(T, android.util.Property<T, java.lang.Integer>, int...);
     method public static android.animation.ObjectAnimator ofFloat(java.lang.Object, java.lang.String, float...);
+    method public static android.animation.ObjectAnimator ofFloat(java.lang.Object, java.lang.String, java.lang.String, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofFloat(T, android.util.Property<T, java.lang.Float>, float...);
+    method public static android.animation.ObjectAnimator ofFloat(T, android.util.Property<T, java.lang.Float>, android.util.Property<T, java.lang.Float>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofInt(java.lang.Object, java.lang.String, int...);
+    method public static android.animation.ObjectAnimator ofInt(java.lang.Object, java.lang.String, java.lang.String, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofInt(T, android.util.Property<T, java.lang.Integer>, int...);
+    method public static android.animation.ObjectAnimator ofInt(T, android.util.Property<T, java.lang.Integer>, android.util.Property<T, java.lang.Integer>, android.graphics.Path);
+    method public static android.animation.ObjectAnimator ofMultiFloat(java.lang.Object, java.lang.String, float[][]);
+    method public static android.animation.ObjectAnimator ofMultiFloat(java.lang.Object, java.lang.String, android.graphics.Path);
+    method public static android.animation.ObjectAnimator ofMultiFloat(java.lang.Object, java.lang.String, android.animation.TypeConverter<T, float[]>, android.animation.TypeEvaluator<T>, T...);
+    method public static android.animation.ObjectAnimator ofMultiInt(java.lang.Object, java.lang.String, int[][]);
+    method public static android.animation.ObjectAnimator ofMultiInt(java.lang.Object, java.lang.String, android.graphics.Path);
+    method public static android.animation.ObjectAnimator ofMultiInt(java.lang.Object, java.lang.String, android.animation.TypeConverter<T, int[]>, android.animation.TypeEvaluator<T>, T...);
     method public static android.animation.ObjectAnimator ofObject(java.lang.Object, java.lang.String, android.animation.TypeEvaluator, java.lang.Object...);
+    method public static android.animation.ObjectAnimator ofObject(java.lang.Object, java.lang.String, android.animation.TypeConverter<android.graphics.PointF, ?>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.ObjectAnimator ofObject(T, android.util.Property<T, P>, android.animation.TypeConverter<V, P>, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
     method public void setAutoCancel(boolean);
     method public void setProperty(android.util.Property);
     method public void setPropertyName(java.lang.String);
   }
 
+  public class PointFEvaluator implements android.animation.TypeEvaluator {
+    ctor public PointFEvaluator();
+    ctor public PointFEvaluator(android.graphics.PointF);
+    method public android.graphics.PointF evaluate(float, android.graphics.PointF, android.graphics.PointF);
+  }
+
   public class PropertyValuesHolder implements java.lang.Cloneable {
     method public android.animation.PropertyValuesHolder clone();
     method public java.lang.String getPropertyName();
@@ -2528,8 +2576,20 @@
     method public static android.animation.PropertyValuesHolder ofInt(android.util.Property<?, java.lang.Integer>, int...);
     method public static android.animation.PropertyValuesHolder ofKeyframe(java.lang.String, android.animation.Keyframe...);
     method public static android.animation.PropertyValuesHolder ofKeyframe(android.util.Property, android.animation.Keyframe...);
+    method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, float[][]);
+    method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, android.graphics.Path);
+    method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, android.animation.TypeConverter<V, float[]>, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, android.animation.TypeConverter<T, float[]>, android.animation.TypeEvaluator<T>, android.animation.Keyframe...);
+    method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, int[][]);
+    method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, android.graphics.Path);
+    method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, android.animation.TypeConverter<V, int[]>, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, android.animation.TypeConverter<T, int[]>, android.animation.TypeEvaluator<T>, android.animation.Keyframe...);
     method public static android.animation.PropertyValuesHolder ofObject(java.lang.String, android.animation.TypeEvaluator, java.lang.Object...);
+    method public static android.animation.PropertyValuesHolder ofObject(java.lang.String, android.animation.TypeConverter<android.graphics.PointF, ?>, android.graphics.Path);
     method public static android.animation.PropertyValuesHolder ofObject(android.util.Property, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.PropertyValuesHolder ofObject(android.util.Property<?, V>, android.animation.TypeConverter<T, V>, android.animation.TypeEvaluator<T>, T...);
+    method public static android.animation.PropertyValuesHolder ofObject(android.util.Property<?, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
+    method public void setConverter(android.animation.TypeConverter);
     method public void setEvaluator(android.animation.TypeEvaluator);
     method public void setFloatValues(float...);
     method public void setIntValues(int...);
@@ -2541,6 +2601,7 @@
 
   public class RectEvaluator implements android.animation.TypeEvaluator {
     ctor public RectEvaluator();
+    ctor public RectEvaluator(android.graphics.Rect);
     method public android.graphics.Rect evaluate(float, android.graphics.Rect, android.graphics.Rect);
   }
 
@@ -2557,6 +2618,12 @@
     method public abstract float getInterpolation(float);
   }
 
+  public abstract class TypeConverter {
+    ctor public TypeConverter(java.lang.Class<T>, java.lang.Class<V>);
+    method public abstract V convert(T);
+    method public T convertBack(V);
+  }
+
   public abstract interface TypeEvaluator {
     method public abstract T evaluate(float, T, T);
   }
@@ -2575,6 +2642,7 @@
     method public long getStartDelay();
     method public android.animation.PropertyValuesHolder[] getValues();
     method public boolean isRunning();
+    method public static android.animation.ValueAnimator ofArgb(int...);
     method public static android.animation.ValueAnimator ofFloat(float...);
     method public static android.animation.ValueAnimator ofInt(int...);
     method public static android.animation.ValueAnimator ofObject(android.animation.TypeEvaluator, java.lang.Object...);
@@ -2607,6 +2675,12 @@
 
 package android.annotation {
 
+  public abstract class NonNull implements java.lang.annotation.Annotation {
+  }
+
+  public abstract class Nullable implements java.lang.annotation.Annotation {
+  }
+
   public abstract class SuppressLint implements java.lang.annotation.Annotation {
   }
 
@@ -2756,6 +2830,8 @@
     method public java.lang.String getCallingPackage();
     method public int getChangingConfigurations();
     method public android.content.ComponentName getComponentName();
+    method public android.transition.Scene getContentScene();
+    method public android.transition.TransitionManager getContentTransitionManager();
     method public android.view.View getCurrentFocus();
     method public android.app.FragmentManager getFragmentManager();
     method public android.content.Intent getIntent();
@@ -2861,6 +2937,7 @@
     method public void reportFullyDrawn();
     method public final boolean requestWindowFeature(int);
     method public final void runOnUiThread(java.lang.Runnable);
+    method public void setContentTransitionManager(android.transition.TransitionManager);
     method public void setContentView(int);
     method public void setContentView(android.view.View);
     method public void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
@@ -2882,7 +2959,7 @@
     method public final void setSecondaryProgress(int);
     method public void setTitle(java.lang.CharSequence);
     method public void setTitle(int);
-    method public void setTitleColor(int);
+    method public deprecated void setTitleColor(int);
     method public void setVisible(boolean);
     method public final void setVolumeControlStream(int);
     method public boolean shouldUpRecreateTask(android.content.Intent);
@@ -3165,6 +3242,7 @@
     method public android.app.AlertDialog.Builder setSingleChoiceItems(android.widget.ListAdapter, int, android.content.DialogInterface.OnClickListener);
     method public android.app.AlertDialog.Builder setTitle(int);
     method public android.app.AlertDialog.Builder setTitle(java.lang.CharSequence);
+    method public android.app.AlertDialog.Builder setView(int);
     method public android.app.AlertDialog.Builder setView(android.view.View);
     method public android.app.AlertDialog show();
   }
@@ -3600,6 +3678,7 @@
     ctor public FragmentBreadCrumbs(android.content.Context);
     ctor public FragmentBreadCrumbs(android.content.Context, android.util.AttributeSet);
     ctor public FragmentBreadCrumbs(android.content.Context, android.util.AttributeSet, int);
+    ctor public FragmentBreadCrumbs(android.content.Context, android.util.AttributeSet, int, int);
     method public void onBackStackChanged();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setActivity(android.app.Activity);
@@ -3886,6 +3965,7 @@
     ctor public MediaRouteButton(android.content.Context);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet, int, int);
     method public int getRouteTypes();
     method public void onAttachedToWindow();
     method public void onDetachedFromWindow();
@@ -5753,6 +5833,8 @@
     method public final android.os.Bundle call(android.net.Uri, java.lang.String, java.lang.String, android.os.Bundle);
     method public deprecated void cancelSync(android.net.Uri);
     method public static void cancelSync(android.accounts.Account, java.lang.String);
+    method public static void cancelSync(android.content.ComponentName);
+    method public static void cancelSync(android.content.SyncRequest);
     method public final android.net.Uri canonicalize(android.net.Uri);
     method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public static deprecated android.content.SyncInfo getCurrentSync();
@@ -5761,14 +5843,18 @@
     method public static boolean getMasterSyncAutomatically();
     method public java.util.List<android.content.UriPermission> getOutgoingPersistedUriPermissions();
     method public static java.util.List<android.content.PeriodicSync> getPeriodicSyncs(android.accounts.Account, java.lang.String);
+    method public static java.util.List<android.content.PeriodicSync> getPeriodicSyncs(android.content.ComponentName);
     method public java.util.List<android.content.UriPermission> getPersistedUriPermissions();
     method public java.lang.String[] getStreamTypes(android.net.Uri, java.lang.String);
     method public static android.content.SyncAdapterType[] getSyncAdapterTypes();
     method public static boolean getSyncAutomatically(android.accounts.Account, java.lang.String);
     method public final java.lang.String getType(android.net.Uri);
     method public final android.net.Uri insert(android.net.Uri, android.content.ContentValues);
+    method public static boolean isServiceActive(android.content.ComponentName);
     method public static boolean isSyncActive(android.accounts.Account, java.lang.String);
+    method public static boolean isSyncActive(android.content.ComponentName);
     method public static boolean isSyncPending(android.accounts.Account, java.lang.String);
+    method public static boolean isSyncPending(android.content.ComponentName);
     method public void notifyChange(android.net.Uri, android.database.ContentObserver);
     method public void notifyChange(android.net.Uri, android.database.ContentObserver, boolean);
     method public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
@@ -5790,6 +5876,7 @@
     method public static void requestSync(android.content.SyncRequest);
     method public static void setIsSyncable(android.accounts.Account, java.lang.String, int);
     method public static void setMasterSyncAutomatically(boolean);
+    method public static void setServiceActive(android.content.ComponentName, boolean);
     method public static void setSyncAutomatically(android.accounts.Account, java.lang.String, boolean);
     method public deprecated void startSync(android.net.Uri, android.os.Bundle);
     method public void takePersistableUriPermission(android.net.Uri, int);
@@ -5976,6 +6063,7 @@
     field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
     field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
     field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
+    field public static final java.lang.String CAMERA_SERVICE = "camera";
     field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
     field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
     field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
@@ -6733,7 +6821,9 @@
     field public final android.accounts.Account account;
     field public final java.lang.String authority;
     field public final android.os.Bundle extras;
+    field public final boolean isService;
     field public final long period;
+    field public final android.content.ComponentName service;
   }
 
   public class ReceiverCallNotAllowedException extends android.util.AndroidRuntimeException {
@@ -6849,11 +6939,13 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public final android.accounts.Account account;
     field public final java.lang.String authority;
+    field public final android.content.ComponentName service;
     field public final long startTime;
   }
 
   public class SyncRequest implements android.os.Parcelable {
     method public int describeContents();
+    method public boolean isExpedited();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
@@ -6868,7 +6960,10 @@
     method public android.content.SyncRequest.Builder setIgnoreSettings(boolean);
     method public android.content.SyncRequest.Builder setManual(boolean);
     method public android.content.SyncRequest.Builder setNoRetry(boolean);
+    method public android.content.SyncRequest.Builder setPriority(int);
     method public android.content.SyncRequest.Builder setSyncAdapter(android.accounts.Account, java.lang.String);
+    method public android.content.SyncRequest.Builder setSyncAdapter(android.content.ComponentName);
+    method public android.content.SyncRequest.Builder setTransferSize(long, long);
     method public android.content.SyncRequest.Builder syncOnce();
     method public android.content.SyncRequest.Builder syncPeriodic(long, long);
   }
@@ -6896,6 +6991,13 @@
     field public boolean tooManyRetries;
   }
 
+  public abstract class SyncService extends android.app.Service {
+    ctor public SyncService();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public abstract void onPerformSync(android.os.Bundle, android.content.SyncResult);
+    method protected boolean parallelSyncsEnabled();
+  }
+
   public class SyncStats implements android.os.Parcelable {
     ctor public SyncStats();
     ctor public SyncStats(android.os.Parcel);
@@ -7559,6 +7661,7 @@
     method public int describeContents();
     method public int getColorForState(int[], int);
     method public int getDefaultColor();
+    method public boolean isOpaque();
     method public boolean isStateful();
     method public static android.content.res.ColorStateList valueOf(int);
     method public android.content.res.ColorStateList withAlpha(int);
@@ -8748,6 +8851,7 @@
     ctor public GestureOverlayView(android.content.Context);
     ctor public GestureOverlayView(android.content.Context, android.util.AttributeSet);
     ctor public GestureOverlayView(android.content.Context, android.util.AttributeSet, int);
+    ctor public GestureOverlayView(android.content.Context, android.util.AttributeSet, int, int);
     method public void addOnGestureListener(android.gesture.GestureOverlayView.OnGestureListener);
     method public void addOnGesturePerformedListener(android.gesture.GestureOverlayView.OnGesturePerformedListener);
     method public void addOnGesturingListener(android.gesture.GestureOverlayView.OnGesturingListener);
@@ -9216,6 +9320,9 @@
   public class ColorMatrixColorFilter extends android.graphics.ColorFilter {
     ctor public ColorMatrixColorFilter(android.graphics.ColorMatrix);
     ctor public ColorMatrixColorFilter(float[]);
+    method public android.graphics.ColorMatrix getColorMatrix();
+    method public void setColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrix(float[]);
   }
 
   public class ComposePathEffect extends android.graphics.PathEffect {
@@ -9253,6 +9360,7 @@
     field public static final int JPEG = 256; // 0x100
     field public static final int NV16 = 16; // 0x10
     field public static final int NV21 = 17; // 0x11
+    field public static final int RAW_SENSOR = 32; // 0x20
     field public static final int RGB_565 = 4; // 0x4
     field public static final int UNKNOWN = 0; // 0x0
     field public static final int YUV_420_888 = 35; // 0x23
@@ -9290,6 +9398,10 @@
 
   public class LightingColorFilter extends android.graphics.ColorFilter {
     ctor public LightingColorFilter(int, int);
+    method public int getColorAdd();
+    method public int getColorMultiply();
+    method public void setColorAdd(int);
+    method public void setColorMultiply(int);
   }
 
   public class LinearGradient extends android.graphics.Shader {
@@ -9764,6 +9876,10 @@
 
   public class PorterDuffColorFilter extends android.graphics.ColorFilter {
     ctor public PorterDuffColorFilter(int, android.graphics.PorterDuff.Mode);
+    method public int getColor();
+    method public android.graphics.PorterDuff.Mode getMode();
+    method public void setColor(int);
+    method public void setMode(android.graphics.PorterDuff.Mode);
   }
 
   public class PorterDuffXfermode extends android.graphics.Xfermode {
@@ -10191,8 +10307,10 @@
     method public void draw(android.graphics.Canvas);
     method public int getOpacity();
     method public android.graphics.drawable.GradientDrawable.Orientation getOrientation();
+    method public boolean onStateChange(int[]);
     method public void setAlpha(int);
     method public void setColor(int);
+    method public void setColor(android.content.res.ColorStateList);
     method public void setColorFilter(android.graphics.ColorFilter);
     method public void setColors(int[]);
     method public void setCornerRadii(float[]);
@@ -10204,7 +10322,9 @@
     method public void setShape(int);
     method public void setSize(int, int);
     method public void setStroke(int, int);
+    method public void setStroke(int, android.content.res.ColorStateList);
     method public void setStroke(int, int, float, float);
+    method public void setStroke(int, android.content.res.ColorStateList, float, float);
     method public void setUseLevel(boolean);
     field public static final int LINE = 2; // 0x2
     field public static final int LINEAR_GRADIENT = 0; // 0x0
@@ -10249,6 +10369,7 @@
     method public int getId(int);
     method public int getNumberOfLayers();
     method public int getOpacity();
+    method public int getPaddingMode();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
@@ -10257,7 +10378,10 @@
     method public void setId(int, int);
     method public void setLayerInset(int, int, int, int, int);
     method public void setOpacity(int);
+    method public void setPaddingMode(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
+    field public static final int PADDING_MODE_NEST = 0; // 0x0
+    field public static final int PADDING_MODE_STACK = 1; // 0x1
   }
 
   public class LevelListDrawable extends android.graphics.drawable.DrawableContainer {
@@ -10860,6 +10984,402 @@
 
 }
 
+package android.hardware.camera2 {
+
+  public class CameraAccessException extends android.util.AndroidException {
+    ctor public CameraAccessException(int);
+    ctor public CameraAccessException(int, java.lang.String);
+    ctor public CameraAccessException(int, java.lang.String, java.lang.Throwable);
+    ctor public CameraAccessException(int, java.lang.Throwable);
+    method public final int getReason();
+    field public static final int CAMERA_DISABLED = 1; // 0x1
+    field public static final int CAMERA_DISCONNECTED = 2; // 0x2
+    field public static final int CAMERA_ERROR = 3; // 0x3
+  }
+
+  public final class CameraCharacteristics extends android.hardware.camera2.CameraMetadata {
+    method public T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    method public java.util.List<android.hardware.camera2.CameraMetadata.Key<?>> getAvailableCaptureRequestKeys();
+    method public java.util.List<android.hardware.camera2.CameraMetadata.Key<?>> getAvailableCaptureResultKeys();
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_COMPENSATION_RANGE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_COMPENSATION_STEP;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_AVAILABLE_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AVAILABLE_EFFECTS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AVAILABLE_SCENE_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_AVAILABLE_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_MAX_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key FLASH_INFO_AVAILABLE;
+    field public static final android.hardware.camera2.CameraMetadata.Key INFO_SUPPORTED_HARDWARE_LEVEL;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_AVAILABLE_THUMBNAIL_SIZES;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FACING;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_AVAILABLE_APERTURES;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_AVAILABLE_FILTER_DENSITIES;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_AVAILABLE_FOCAL_LENGTHS;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_HYPERFOCAL_DISTANCE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_MINIMUM_FOCUS_DISTANCE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_SHADING_MAP_SIZE;
+    field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_MAX_NUM_OUTPUT_STREAMS;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_FORMATS;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_JPEG_MIN_DURATIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_JPEG_SIZES;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_MAX_DIGITAL_ZOOM;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_PROCESSED_SIZES;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_BASE_GAIN_FACTOR;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_ACTIVE_ARRAY_SIZE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_EXPOSURE_TIME_RANGE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_MAX_FRAME_DURATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_PHYSICAL_SIZE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_SENSITIVITY_RANGE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_MAX_ANALOG_SENSITIVITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_ORIENTATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_MAX_FACE_COUNT;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MAX_CURVE_POINTS;
+  }
+
+  public abstract interface CameraDevice implements java.lang.AutoCloseable {
+    method public abstract int capture(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract int captureBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void close();
+    method public abstract void configureOutputs(java.util.List<android.view.Surface>) throws android.hardware.camera2.CameraAccessException;
+    method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void flush() throws android.hardware.camera2.CameraAccessException;
+    method public abstract java.lang.String getId();
+    method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract int setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void stopRepeating() throws android.hardware.camera2.CameraAccessException;
+    method public abstract void waitUntilIdle() throws android.hardware.camera2.CameraAccessException;
+    field public static final int TEMPLATE_PREVIEW = 1; // 0x1
+    field public static final int TEMPLATE_RECORD = 3; // 0x3
+    field public static final int TEMPLATE_STILL_CAPTURE = 2; // 0x2
+    field public static final int TEMPLATE_VIDEO_SNAPSHOT = 4; // 0x4
+  }
+
+  public static abstract class CameraDevice.CaptureListener {
+    ctor public CameraDevice.CaptureListener();
+    method public void onCaptureCompleted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult);
+    method public void onCaptureFailed(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureFailure);
+    method public void onCaptureSequenceCompleted(android.hardware.camera2.CameraDevice, int, int);
+    method public void onCaptureStarted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, long);
+  }
+
+  public static abstract class CameraDevice.StateListener {
+    ctor public CameraDevice.StateListener();
+    method public void onActive(android.hardware.camera2.CameraDevice);
+    method public void onBusy(android.hardware.camera2.CameraDevice);
+    method public void onClosed(android.hardware.camera2.CameraDevice);
+    method public abstract void onDisconnected(android.hardware.camera2.CameraDevice);
+    method public abstract void onError(android.hardware.camera2.CameraDevice, int);
+    method public void onIdle(android.hardware.camera2.CameraDevice);
+    method public abstract void onOpened(android.hardware.camera2.CameraDevice);
+    method public void onUnconfigured(android.hardware.camera2.CameraDevice);
+    field public static final int ERROR_CAMERA_DEVICE = 4; // 0x4
+    field public static final int ERROR_CAMERA_DISABLED = 3; // 0x3
+    field public static final int ERROR_CAMERA_IN_USE = 1; // 0x1
+    field public static final int ERROR_CAMERA_SERVICE = 5; // 0x5
+    field public static final int ERROR_MAX_CAMERAS_IN_USE = 2; // 0x2
+  }
+
+  public final class CameraManager {
+    method public void addAvailabilityListener(android.hardware.camera2.CameraManager.AvailabilityListener, android.os.Handler);
+    method public android.hardware.camera2.CameraCharacteristics getCameraCharacteristics(java.lang.String) throws android.hardware.camera2.CameraAccessException;
+    method public java.lang.String[] getCameraIdList() throws android.hardware.camera2.CameraAccessException;
+    method public void openCamera(java.lang.String, android.hardware.camera2.CameraDevice.StateListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public void removeAvailabilityListener(android.hardware.camera2.CameraManager.AvailabilityListener);
+  }
+
+  public static abstract class CameraManager.AvailabilityListener {
+    ctor public CameraManager.AvailabilityListener();
+    method public void onCameraAvailable(java.lang.String);
+    method public void onCameraUnavailable(java.lang.String);
+  }
+
+  public abstract class CameraMetadata {
+    method public abstract T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    method public java.util.List<android.hardware.camera2.CameraMetadata.Key<?>> getKeys();
+    field public static final int COLOR_CORRECTION_MODE_FAST = 1; // 0x1
+    field public static final int COLOR_CORRECTION_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0; // 0x0
+    field public static final int CONTROL_AE_ANTIBANDING_MODE_50HZ = 1; // 0x1
+    field public static final int CONTROL_AE_ANTIBANDING_MODE_60HZ = 2; // 0x2
+    field public static final int CONTROL_AE_ANTIBANDING_MODE_AUTO = 3; // 0x3
+    field public static final int CONTROL_AE_ANTIBANDING_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_AE_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_AE_MODE_ON = 1; // 0x1
+    field public static final int CONTROL_AE_MODE_ON_ALWAYS_FLASH = 3; // 0x3
+    field public static final int CONTROL_AE_MODE_ON_AUTO_FLASH = 2; // 0x2
+    field public static final int CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4; // 0x4
+    field public static final int CONTROL_AE_PRECAPTURE_TRIGGER_IDLE = 0; // 0x0
+    field public static final int CONTROL_AE_PRECAPTURE_TRIGGER_START = 1; // 0x1
+    field public static final int CONTROL_AE_STATE_CONVERGED = 2; // 0x2
+    field public static final int CONTROL_AE_STATE_FLASH_REQUIRED = 4; // 0x4
+    field public static final int CONTROL_AE_STATE_INACTIVE = 0; // 0x0
+    field public static final int CONTROL_AE_STATE_LOCKED = 3; // 0x3
+    field public static final int CONTROL_AE_STATE_PRECAPTURE = 5; // 0x5
+    field public static final int CONTROL_AE_STATE_SEARCHING = 1; // 0x1
+    field public static final int CONTROL_AF_MODE_AUTO = 1; // 0x1
+    field public static final int CONTROL_AF_MODE_CONTINUOUS_PICTURE = 4; // 0x4
+    field public static final int CONTROL_AF_MODE_CONTINUOUS_VIDEO = 3; // 0x3
+    field public static final int CONTROL_AF_MODE_EDOF = 5; // 0x5
+    field public static final int CONTROL_AF_MODE_MACRO = 2; // 0x2
+    field public static final int CONTROL_AF_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_AF_STATE_ACTIVE_SCAN = 3; // 0x3
+    field public static final int CONTROL_AF_STATE_FOCUSED_LOCKED = 4; // 0x4
+    field public static final int CONTROL_AF_STATE_INACTIVE = 0; // 0x0
+    field public static final int CONTROL_AF_STATE_NOT_FOCUSED_LOCKED = 5; // 0x5
+    field public static final int CONTROL_AF_STATE_PASSIVE_FOCUSED = 2; // 0x2
+    field public static final int CONTROL_AF_STATE_PASSIVE_SCAN = 1; // 0x1
+    field public static final int CONTROL_AF_STATE_PASSIVE_UNFOCUSED = 6; // 0x6
+    field public static final int CONTROL_AF_TRIGGER_CANCEL = 2; // 0x2
+    field public static final int CONTROL_AF_TRIGGER_IDLE = 0; // 0x0
+    field public static final int CONTROL_AF_TRIGGER_START = 1; // 0x1
+    field public static final int CONTROL_AWB_MODE_AUTO = 1; // 0x1
+    field public static final int CONTROL_AWB_MODE_CLOUDY_DAYLIGHT = 6; // 0x6
+    field public static final int CONTROL_AWB_MODE_DAYLIGHT = 5; // 0x5
+    field public static final int CONTROL_AWB_MODE_FLUORESCENT = 3; // 0x3
+    field public static final int CONTROL_AWB_MODE_INCANDESCENT = 2; // 0x2
+    field public static final int CONTROL_AWB_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_AWB_MODE_SHADE = 8; // 0x8
+    field public static final int CONTROL_AWB_MODE_TWILIGHT = 7; // 0x7
+    field public static final int CONTROL_AWB_MODE_WARM_FLUORESCENT = 4; // 0x4
+    field public static final int CONTROL_AWB_STATE_CONVERGED = 2; // 0x2
+    field public static final int CONTROL_AWB_STATE_INACTIVE = 0; // 0x0
+    field public static final int CONTROL_AWB_STATE_LOCKED = 3; // 0x3
+    field public static final int CONTROL_AWB_STATE_SEARCHING = 1; // 0x1
+    field public static final int CONTROL_CAPTURE_INTENT_CUSTOM = 0; // 0x0
+    field public static final int CONTROL_CAPTURE_INTENT_PREVIEW = 1; // 0x1
+    field public static final int CONTROL_CAPTURE_INTENT_STILL_CAPTURE = 2; // 0x2
+    field public static final int CONTROL_CAPTURE_INTENT_VIDEO_RECORD = 3; // 0x3
+    field public static final int CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT = 4; // 0x4
+    field public static final int CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG = 5; // 0x5
+    field public static final int CONTROL_EFFECT_MODE_AQUA = 8; // 0x8
+    field public static final int CONTROL_EFFECT_MODE_BLACKBOARD = 7; // 0x7
+    field public static final int CONTROL_EFFECT_MODE_MONO = 1; // 0x1
+    field public static final int CONTROL_EFFECT_MODE_NEGATIVE = 2; // 0x2
+    field public static final int CONTROL_EFFECT_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_EFFECT_MODE_POSTERIZE = 5; // 0x5
+    field public static final int CONTROL_EFFECT_MODE_SEPIA = 4; // 0x4
+    field public static final int CONTROL_EFFECT_MODE_SOLARIZE = 3; // 0x3
+    field public static final int CONTROL_EFFECT_MODE_WHITEBOARD = 6; // 0x6
+    field public static final int CONTROL_MODE_AUTO = 1; // 0x1
+    field public static final int CONTROL_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_MODE_USE_SCENE_MODE = 2; // 0x2
+    field public static final int CONTROL_SCENE_MODE_ACTION = 2; // 0x2
+    field public static final int CONTROL_SCENE_MODE_BARCODE = 16; // 0x10
+    field public static final int CONTROL_SCENE_MODE_BEACH = 8; // 0x8
+    field public static final int CONTROL_SCENE_MODE_CANDLELIGHT = 15; // 0xf
+    field public static final int CONTROL_SCENE_MODE_FACE_PRIORITY = 1; // 0x1
+    field public static final int CONTROL_SCENE_MODE_FIREWORKS = 12; // 0xc
+    field public static final int CONTROL_SCENE_MODE_LANDSCAPE = 4; // 0x4
+    field public static final int CONTROL_SCENE_MODE_NIGHT = 5; // 0x5
+    field public static final int CONTROL_SCENE_MODE_NIGHT_PORTRAIT = 6; // 0x6
+    field public static final int CONTROL_SCENE_MODE_PARTY = 14; // 0xe
+    field public static final int CONTROL_SCENE_MODE_PORTRAIT = 3; // 0x3
+    field public static final int CONTROL_SCENE_MODE_SNOW = 9; // 0x9
+    field public static final int CONTROL_SCENE_MODE_SPORTS = 13; // 0xd
+    field public static final int CONTROL_SCENE_MODE_STEADYPHOTO = 11; // 0xb
+    field public static final int CONTROL_SCENE_MODE_SUNSET = 10; // 0xa
+    field public static final int CONTROL_SCENE_MODE_THEATRE = 7; // 0x7
+    field public static final int CONTROL_SCENE_MODE_UNSUPPORTED = 0; // 0x0
+    field public static final int EDGE_MODE_FAST = 1; // 0x1
+    field public static final int EDGE_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int EDGE_MODE_OFF = 0; // 0x0
+    field public static final int FLASH_MODE_OFF = 0; // 0x0
+    field public static final int FLASH_MODE_SINGLE = 1; // 0x1
+    field public static final int FLASH_MODE_TORCH = 2; // 0x2
+    field public static final int FLASH_STATE_CHARGING = 1; // 0x1
+    field public static final int FLASH_STATE_FIRED = 3; // 0x3
+    field public static final int FLASH_STATE_READY = 2; // 0x2
+    field public static final int FLASH_STATE_UNAVAILABLE = 0; // 0x0
+    field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1; // 0x1
+    field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0; // 0x0
+    field public static final int LENS_FACING_BACK = 1; // 0x1
+    field public static final int LENS_FACING_FRONT = 0; // 0x0
+    field public static final int LENS_OPTICAL_STABILIZATION_MODE_OFF = 0; // 0x0
+    field public static final int LENS_OPTICAL_STABILIZATION_MODE_ON = 1; // 0x1
+    field public static final int LENS_STATE_MOVING = 1; // 0x1
+    field public static final int LENS_STATE_STATIONARY = 0; // 0x0
+    field public static final int NOISE_REDUCTION_MODE_FAST = 1; // 0x1
+    field public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int NOISE_REDUCTION_MODE_OFF = 0; // 0x0
+    field public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2; // 0x2
+    field public static final int STATISTICS_FACE_DETECT_MODE_OFF = 0; // 0x0
+    field public static final int STATISTICS_FACE_DETECT_MODE_SIMPLE = 1; // 0x1
+    field public static final int STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0; // 0x0
+    field public static final int STATISTICS_LENS_SHADING_MAP_MODE_ON = 1; // 0x1
+    field public static final int STATISTICS_SCENE_FLICKER_50HZ = 1; // 0x1
+    field public static final int STATISTICS_SCENE_FLICKER_60HZ = 2; // 0x2
+    field public static final int STATISTICS_SCENE_FLICKER_NONE = 0; // 0x0
+    field public static final int TONEMAP_MODE_CONTRAST_CURVE = 0; // 0x0
+    field public static final int TONEMAP_MODE_FAST = 1; // 0x1
+    field public static final int TONEMAP_MODE_HIGH_QUALITY = 2; // 0x2
+  }
+
+  public static class CameraMetadata.Key {
+    method public final boolean equals(java.lang.Object);
+    method public final java.lang.String getName();
+    method public final int hashCode();
+  }
+
+  public class CaptureFailure {
+    method public int getFrameNumber();
+    method public int getReason();
+    method public android.hardware.camera2.CaptureRequest getRequest();
+    method public int getSequenceId();
+    method public boolean wasImageCaptured();
+    field public static final int REASON_ERROR = 0; // 0x0
+    field public static final int REASON_FLUSHED = 1; // 0x1
+  }
+
+  public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
+    method public int describeContents();
+    method public T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    method public java.lang.Object getTag();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.hardware.camera2.CameraMetadata.Key BLACK_LEVEL_LOCK;
+    field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_GAINS;
+    field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_TRANSFORM;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_ANTIBANDING_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_EXPOSURE_COMPENSATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_LOCK;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_PRECAPTURE_TRIGGER;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_TARGET_FPS_RANGE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_TRIGGER;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_LOCK;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_CAPTURE_INTENT;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_EFFECT_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_SCENE_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_VIDEO_STABILIZATION_MODE;
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final android.hardware.camera2.CameraMetadata.Key EDGE_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key FLASH_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_COORDINATES;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_PROCESSING_METHOD;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_TIMESTAMP;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_ORIENTATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_QUALITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_THUMBNAIL_QUALITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_THUMBNAIL_SIZE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_APERTURE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FILTER_DENSITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCAL_LENGTH;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCUS_DISTANCE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_OPTICAL_STABILIZATION_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key NOISE_REDUCTION_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_CROP_REGION;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_EXPOSURE_TIME;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FRAME_DURATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_SENSITIVITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_BLUE;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_GREEN;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_RED;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MODE;
+  }
+
+  public static final class CaptureRequest.Builder {
+    method public void addTarget(android.view.Surface);
+    method public android.hardware.camera2.CaptureRequest build();
+    method public T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    method public void removeTarget(android.view.Surface);
+    method public void set(android.hardware.camera2.CameraMetadata.Key<T>, T);
+    method public void setTag(java.lang.Object);
+  }
+
+  public final class CaptureResult extends android.hardware.camera2.CameraMetadata {
+    method public T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    method public int getFrameNumber();
+    method public android.hardware.camera2.CaptureRequest getRequest();
+    method public int getSequenceId();
+    field public static final android.hardware.camera2.CameraMetadata.Key BLACK_LEVEL_LOCK;
+    field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_GAINS;
+    field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_TRANSFORM;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_STATE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_STATE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_STATE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key EDGE_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key FLASH_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key FLASH_STATE;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_COORDINATES;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_PROCESSING_METHOD;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_TIMESTAMP;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_ORIENTATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_QUALITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_THUMBNAIL_QUALITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_THUMBNAIL_SIZE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_APERTURE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FILTER_DENSITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCAL_LENGTH;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCUS_DISTANCE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCUS_RANGE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_OPTICAL_STABILIZATION_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_STATE;
+    field public static final android.hardware.camera2.CameraMetadata.Key NOISE_REDUCTION_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_FRAME_COUNT;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_CROP_REGION;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_EXPOSURE_TIME;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FRAME_DURATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_SENSITIVITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEMPERATURE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TIMESTAMP;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACES;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_PREDICTED_COLOR_GAINS;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_PREDICTED_COLOR_TRANSFORM;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_SCENE_FLICKER;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_BLUE;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_GREEN;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_RED;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MODE;
+  }
+
+  public final class Face {
+    method public android.graphics.Rect getBounds();
+    method public int getId();
+    method public android.graphics.Point getLeftEyePosition();
+    method public android.graphics.Point getMouthPosition();
+    method public android.graphics.Point getRightEyePosition();
+    method public int getScore();
+    field public static final int ID_UNSUPPORTED = -1; // 0xffffffff
+    field public static final int SCORE_MAX = 100; // 0x64
+    field public static final int SCORE_MIN = 1; // 0x1
+  }
+
+  public final class Rational {
+    ctor public Rational(int, int);
+    method public int getDenominator();
+    method public int getNumerator();
+  }
+
+  public final class Size {
+    ctor public Size(int, int);
+    method public final int getHeight();
+    method public final int getWidth();
+  }
+
+}
+
 package android.hardware.display {
 
   public final class DisplayManager {
@@ -11137,6 +11657,7 @@
     ctor public ExtractEditText(android.content.Context);
     ctor public ExtractEditText(android.content.Context, android.util.AttributeSet);
     ctor public ExtractEditText(android.content.Context, android.util.AttributeSet, int);
+    ctor public ExtractEditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void finishInternalChanges();
     method public boolean hasVerticalScrollBar();
     method public void startInternalChanges();
@@ -11151,6 +11672,7 @@
     method public android.view.inputmethod.InputConnection getCurrentInputConnection();
     method public android.view.inputmethod.EditorInfo getCurrentInputEditorInfo();
     method public boolean getCurrentInputStarted();
+    method public int getInputMethodWindowRecommendedHeight();
     method public android.view.LayoutInflater getLayoutInflater();
     method public int getMaxWidth();
     method public java.lang.CharSequence getTextForImeAction(int);
@@ -11333,6 +11855,7 @@
   public class KeyboardView extends android.view.View implements android.view.View.OnClickListener {
     ctor public KeyboardView(android.content.Context, android.util.AttributeSet);
     ctor public KeyboardView(android.content.Context, android.util.AttributeSet, int);
+    ctor public KeyboardView(android.content.Context, android.util.AttributeSet, int, int);
     method public void closing();
     method public android.inputmethodservice.Keyboard getKeyboard();
     method protected android.inputmethodservice.KeyboardView.OnKeyboardActionListener getOnKeyboardActionListener();
@@ -18430,13 +18953,16 @@
 
   public class CheckBoxPreference extends android.preference.TwoStatePreference {
     ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet, int);
+    ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet);
     ctor public CheckBoxPreference(android.content.Context);
   }
 
   public abstract class DialogPreference extends android.preference.Preference implements android.content.DialogInterface.OnClickListener android.content.DialogInterface.OnDismissListener android.preference.PreferenceManager.OnActivityDestroyListener {
+    ctor public DialogPreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public DialogPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public DialogPreference(android.content.Context, android.util.AttributeSet);
+    ctor public DialogPreference(android.content.Context);
     method public android.app.Dialog getDialog();
     method public android.graphics.drawable.Drawable getDialogIcon();
     method public int getDialogLayoutResource();
@@ -18466,6 +18992,7 @@
   }
 
   public class EditTextPreference extends android.preference.DialogPreference {
+    ctor public EditTextPreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public EditTextPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public EditTextPreference(android.content.Context, android.util.AttributeSet);
     ctor public EditTextPreference(android.content.Context);
@@ -18476,6 +19003,8 @@
   }
 
   public class ListPreference extends android.preference.DialogPreference {
+    ctor public ListPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public ListPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public ListPreference(android.content.Context, android.util.AttributeSet);
     ctor public ListPreference(android.content.Context);
     method public int findIndexOfValue(java.lang.String);
@@ -18492,6 +19021,8 @@
   }
 
   public class MultiSelectListPreference extends android.preference.DialogPreference {
+    ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet);
     ctor public MultiSelectListPreference(android.content.Context);
     method public int findIndexOfValue(java.lang.String);
@@ -18506,6 +19037,7 @@
   }
 
   public class Preference implements java.lang.Comparable {
+    ctor public Preference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public Preference(android.content.Context, android.util.AttributeSet, int);
     ctor public Preference(android.content.Context, android.util.AttributeSet);
     ctor public Preference(android.content.Context);
@@ -18671,6 +19203,7 @@
   }
 
   public class PreferenceCategory extends android.preference.PreferenceGroup {
+    ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet, int, int);
     ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet, int);
     ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet);
     ctor public PreferenceCategory(android.content.Context);
@@ -18692,6 +19225,7 @@
   }
 
   public abstract class PreferenceGroup extends android.preference.Preference {
+    ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet, int, int);
     ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet, int);
     ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet);
     method public void addItemFromInflater(android.preference.Preference);
@@ -18746,6 +19280,7 @@
   }
 
   public class RingtonePreference extends android.preference.Preference implements android.preference.PreferenceManager.OnActivityResultListener {
+    ctor public RingtonePreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public RingtonePreference(android.content.Context, android.util.AttributeSet, int);
     ctor public RingtonePreference(android.content.Context, android.util.AttributeSet);
     ctor public RingtonePreference(android.content.Context);
@@ -18762,6 +19297,7 @@
   }
 
   public class SwitchPreference extends android.preference.TwoStatePreference {
+    ctor public SwitchPreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public SwitchPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public SwitchPreference(android.content.Context, android.util.AttributeSet);
     ctor public SwitchPreference(android.content.Context);
@@ -18774,6 +19310,7 @@
   }
 
   public abstract class TwoStatePreference extends android.preference.Preference {
+    ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet, int);
     ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet);
     ctor public TwoStatePreference(android.content.Context);
@@ -21699,15 +22236,18 @@
 package android.renderscript {
 
   public class Allocation extends android.renderscript.BaseObj {
+    method public void copy1DRangeFrom(int, int, java.lang.Object);
     method public void copy1DRangeFrom(int, int, int[]);
     method public void copy1DRangeFrom(int, int, short[]);
     method public void copy1DRangeFrom(int, int, byte[]);
     method public void copy1DRangeFrom(int, int, float[]);
     method public void copy1DRangeFrom(int, int, android.renderscript.Allocation, int);
+    method public void copy1DRangeFromUnchecked(int, int, java.lang.Object);
     method public void copy1DRangeFromUnchecked(int, int, int[]);
     method public void copy1DRangeFromUnchecked(int, int, short[]);
     method public void copy1DRangeFromUnchecked(int, int, byte[]);
     method public void copy1DRangeFromUnchecked(int, int, float[]);
+    method public void copy2DRangeFrom(int, int, int, int, java.lang.Object);
     method public void copy2DRangeFrom(int, int, int, int, byte[]);
     method public void copy2DRangeFrom(int, int, int, int, short[]);
     method public void copy2DRangeFrom(int, int, int, int, int[]);
@@ -21715,17 +22255,20 @@
     method public void copy2DRangeFrom(int, int, int, int, android.renderscript.Allocation, int, int);
     method public void copy2DRangeFrom(int, int, android.graphics.Bitmap);
     method public void copyFrom(android.renderscript.BaseObj[]);
+    method public void copyFrom(java.lang.Object);
     method public void copyFrom(int[]);
     method public void copyFrom(short[]);
     method public void copyFrom(byte[]);
     method public void copyFrom(float[]);
     method public void copyFrom(android.graphics.Bitmap);
     method public void copyFrom(android.renderscript.Allocation);
+    method public void copyFromUnchecked(java.lang.Object);
     method public void copyFromUnchecked(int[]);
     method public void copyFromUnchecked(short[]);
     method public void copyFromUnchecked(byte[]);
     method public void copyFromUnchecked(float[]);
     method public void copyTo(android.graphics.Bitmap);
+    method public void copyTo(java.lang.Object);
     method public void copyTo(byte[]);
     method public void copyTo(short[]);
     method public void copyTo(int[]);
@@ -22514,6 +23057,9 @@
   }
 
   public class Type extends android.renderscript.BaseObj {
+    method public static android.renderscript.Type createX(android.renderscript.RenderScript, android.renderscript.Element, int);
+    method public static android.renderscript.Type createXY(android.renderscript.RenderScript, android.renderscript.Element, int, int);
+    method public static android.renderscript.Type createXYZ(android.renderscript.RenderScript, android.renderscript.Element, int, int, int);
     method public int getCount();
     method public android.renderscript.Element getElement();
     method public int getX();
@@ -22901,11 +23447,52 @@
 
 package android.speech.tts {
 
+  public final class RequestConfig {
+    method public android.os.Bundle getAudioParams();
+    method public android.speech.tts.VoiceInfo getVoice();
+    method public android.os.Bundle getVoiceParams();
+  }
+
+  public static final class RequestConfig.Builder {
+    method public android.speech.tts.RequestConfig build();
+    method public static android.speech.tts.RequestConfig.Builder newBuilder();
+    method public static android.speech.tts.RequestConfig.Builder newBuilder(android.speech.tts.RequestConfig);
+    method public android.speech.tts.RequestConfig.Builder setAudioParam(java.lang.String, java.lang.Object);
+    method public void setAudioParamPan(float);
+    method public void setAudioParamStream(int);
+    method public void setAudioParamVolume(float);
+    method public android.speech.tts.RequestConfig.Builder setVoice(android.speech.tts.VoiceInfo);
+    method public android.speech.tts.RequestConfig.Builder setVoiceParam(java.lang.String, java.lang.Object);
+  }
+
+  public final class RequestConfigHelper {
+    method public static android.speech.tts.RequestConfig highestQuality(android.speech.tts.TextToSpeechClient.EngineStatus, boolean, android.speech.tts.RequestConfigHelper.VoiceScorer);
+    method public static android.speech.tts.RequestConfig highestQuality(android.speech.tts.TextToSpeechClient.EngineStatus, boolean);
+  }
+
+  public static final class RequestConfigHelper.ExactLocaleMatcher implements android.speech.tts.RequestConfigHelper.VoiceScorer {
+    ctor public RequestConfigHelper.ExactLocaleMatcher(java.util.Locale);
+    method public int scoreVoice(android.speech.tts.VoiceInfo);
+  }
+
+  public static final class RequestConfigHelper.LanguageMatcher implements android.speech.tts.RequestConfigHelper.VoiceScorer {
+    ctor public RequestConfigHelper.LanguageMatcher(java.util.Locale);
+    method public int scoreVoice(android.speech.tts.VoiceInfo);
+  }
+
+  public static abstract interface RequestConfigHelper.VoiceScorer {
+    method public abstract int scoreVoice(android.speech.tts.VoiceInfo);
+  }
+
   public abstract interface SynthesisCallback {
     method public abstract int audioAvailable(byte[], int, int);
     method public abstract int done();
     method public abstract void error();
+    method public abstract void error(int);
+    method public abstract int fallback();
     method public abstract int getMaxBufferSize();
+    method public abstract boolean hasFinished();
+    method public abstract boolean hasStarted();
     method public abstract int start(int, int, int);
   }
 
@@ -22921,7 +23508,17 @@
     method public java.lang.String getVariant();
   }
 
-  public class TextToSpeech {
+  public final class SynthesisRequestV2 implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.os.Bundle getAudioParams();
+    method public java.lang.String getText();
+    method public java.lang.String getUtteranceId();
+    method public java.lang.String getVoiceName();
+    method public android.os.Bundle getVoiceParams();
+    method public void writeToParcel(android.os.Parcel, int);
+  }
+
+  public deprecated class TextToSpeech {
     ctor public TextToSpeech(android.content.Context, android.speech.tts.TextToSpeech.OnInitListener);
     ctor public TextToSpeech(android.content.Context, android.speech.tts.TextToSpeech.OnInitListener, java.lang.String);
     method public int addEarcon(java.lang.String, java.lang.String, int);
@@ -23006,8 +23603,80 @@
     method public abstract void onUtteranceCompleted(java.lang.String);
   }
 
+  public final class TextToSpeechClient {
+    ctor public TextToSpeechClient(android.content.Context, java.lang.String, boolean, android.speech.tts.TextToSpeechClient.RequestCallbacks, android.speech.tts.TextToSpeechClient.ConnectionCallbacks);
+    ctor public TextToSpeechClient(android.content.Context, android.speech.tts.TextToSpeechClient.RequestCallbacks, android.speech.tts.TextToSpeechClient.ConnectionCallbacks);
+    method public void connect();
+    method public void disconnect();
+    method public android.speech.tts.TextToSpeechClient.EngineStatus getEngineStatus();
+    method public boolean isConnected();
+    method public void queueAudio(android.net.Uri, android.speech.tts.TextToSpeechClient.UtteranceId, android.speech.tts.RequestConfig, android.speech.tts.TextToSpeechClient.RequestCallbacks);
+    method public void queueSilence(long, android.speech.tts.TextToSpeechClient.UtteranceId, android.speech.tts.TextToSpeechClient.RequestCallbacks);
+    method public void queueSpeak(java.lang.String, android.speech.tts.TextToSpeechClient.UtteranceId, android.speech.tts.RequestConfig, android.speech.tts.TextToSpeechClient.RequestCallbacks);
+    method public void queueSynthesizeToFile(java.lang.String, android.speech.tts.TextToSpeechClient.UtteranceId, java.io.File, android.speech.tts.RequestConfig, android.speech.tts.TextToSpeechClient.RequestCallbacks);
+    method public void stop();
+  }
+
+  public static abstract interface TextToSpeechClient.ConnectionCallbacks {
+    method public abstract void onConnectionFailure();
+    method public abstract void onConnectionSuccess();
+    method public abstract void onEngineStatusChange(android.speech.tts.TextToSpeechClient.EngineStatus);
+    method public abstract void onServiceDisconnected();
+  }
+
+  public static final class TextToSpeechClient.EngineStatus {
+    method public java.lang.String getEnginePackage();
+    method public java.util.List<android.speech.tts.VoiceInfo> getVoices();
+  }
+
+  public static final class TextToSpeechClient.Params {
+    field public static final java.lang.String AUDIO_PARAM_PAN = "pan";
+    field public static final java.lang.String AUDIO_PARAM_STREAM = "streamType";
+    field public static final java.lang.String AUDIO_PARAM_VOLUME = "volume";
+    field public static final java.lang.String FALLBACK_VOICE_NAME = "fallbackVoiceName";
+    field public static final java.lang.String NETWORK_RETRIES_COUNT = "networkRetriesCount";
+    field public static final java.lang.String NETWORK_TIMEOUT_MS = "networkTimeoutMs";
+    field public static final java.lang.String SPEECH_PITCH = "speechPitch";
+    field public static final java.lang.String SPEECH_SPEED = "speechSpeed";
+    field public static final java.lang.String TRACK_SUBUTTERANCE_PROGRESS = "trackSubutteranceProgress";
+  }
+
+  public static abstract class TextToSpeechClient.RequestCallbacks {
+    ctor public TextToSpeechClient.RequestCallbacks();
+    method public void onSynthesisFailure(android.speech.tts.TextToSpeechClient.UtteranceId, int);
+    method public void onSynthesisFallback(android.speech.tts.TextToSpeechClient.UtteranceId);
+    method public void onSynthesisProgress(android.speech.tts.TextToSpeechClient.UtteranceId, int, int);
+    method public void onSynthesisStart(android.speech.tts.TextToSpeechClient.UtteranceId);
+    method public void onSynthesisStop(android.speech.tts.TextToSpeechClient.UtteranceId);
+    method public void onSynthesisSuccess(android.speech.tts.TextToSpeechClient.UtteranceId);
+  }
+
+  public static final class TextToSpeechClient.Status {
+    field public static final int ERROR_DOWNLOADING_ADDITIONAL_DATA = 17; // 0x11
+    field public static final int ERROR_INVALID_REQUEST = 15; // 0xf
+    field public static final int ERROR_NETWORK = 13; // 0xd
+    field public static final int ERROR_NETWORK_TIMEOUT = 14; // 0xe
+    field public static final int ERROR_NON_UNIQUE_UTTERANCE_ID = 16; // 0x10
+    field public static final int ERROR_OUTPUT = 12; // 0xc
+    field public static final int ERROR_SERVICE = 11; // 0xb
+    field public static final int ERROR_SYNTHESIS = 10; // 0xa
+    field public static final int ERROR_UNKNOWN = -1; // 0xffffffff
+    field public static final int STOPPED = 100; // 0x64
+    field public static final int SUCCESS = 0; // 0x0
+  }
+
+  public static final class TextToSpeechClient.UtteranceId {
+    ctor public TextToSpeechClient.UtteranceId();
+    ctor public TextToSpeechClient.UtteranceId(java.lang.String);
+    method public java.lang.String toUniqueString();
+  }
+
   public abstract class TextToSpeechService extends android.app.Service {
     ctor public TextToSpeechService();
+    method protected java.util.List<android.speech.tts.VoiceInfo> checkVoicesInfo();
+    method public void forceVoicesInfoCheck();
+    method public android.speech.tts.VoiceInfo getVoicesInfoWithName(java.lang.String);
+    method protected boolean implementsV2API();
     method public android.os.IBinder onBind(android.content.Intent);
     method protected java.util.Set<java.lang.String> onGetFeaturesForLanguage(java.lang.String, java.lang.String, java.lang.String);
     method protected abstract java.lang.String[] onGetLanguage();
@@ -23015,6 +23684,8 @@
     method protected abstract int onLoadLanguage(java.lang.String, java.lang.String, java.lang.String);
     method protected abstract void onStop();
     method protected abstract void onSynthesizeText(android.speech.tts.SynthesisRequest, android.speech.tts.SynthesisCallback);
+    method protected void onSynthesizeTextV2(android.speech.tts.SynthesisRequestV2, android.speech.tts.VoiceInfo, android.speech.tts.SynthesisCallback);
+    method protected void onVoicesInfoChange();
   }
 
   public abstract class UtteranceProgressListener {
@@ -23024,6 +23695,44 @@
     method public abstract void onStart(java.lang.String);
   }
 
+  public final class VoiceInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.os.Bundle getAdditionalFeatures();
+    method public int getLatency();
+    method public java.util.Locale getLocale();
+    method public java.lang.String getName();
+    method public android.os.Bundle getParamsWithDefaults();
+    method public int getQuality();
+    method public boolean getRequiresNetworkConnection();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String FEATURE_MAY_AUTOINSTALL = "mayAutoInstall";
+    field public static final java.lang.String FEATURE_SPEAKER_GENDER = "speakerGender";
+    field public static final java.lang.String FEATURE_WORDS_PER_MINUTE = "wordsPerMinute";
+    field public static final int LATENCY_HIGH = 400; // 0x190
+    field public static final int LATENCY_LOW = 200; // 0xc8
+    field public static final int LATENCY_NORMAL = 300; // 0x12c
+    field public static final int LATENCY_VERY_HIGH = 500; // 0x1f4
+    field public static final int LATENCY_VERY_LOW = 100; // 0x64
+    field public static final int QUALITY_HIGH = 400; // 0x190
+    field public static final int QUALITY_LOW = 200; // 0xc8
+    field public static final int QUALITY_NORMAL = 300; // 0x12c
+    field public static final int QUALITY_VERY_HIGH = 500; // 0x1f4
+    field public static final int QUALITY_VERY_LOW = 100; // 0x64
+  }
+
+  public static final class VoiceInfo.Builder {
+    ctor public VoiceInfo.Builder();
+    ctor public VoiceInfo.Builder(android.speech.tts.VoiceInfo);
+    method public android.speech.tts.VoiceInfo build();
+    method public android.speech.tts.VoiceInfo.Builder setAdditionalFeatures(android.os.Bundle);
+    method public android.speech.tts.VoiceInfo.Builder setLatency(int);
+    method public android.speech.tts.VoiceInfo.Builder setLocale(java.util.Locale);
+    method public android.speech.tts.VoiceInfo.Builder setName(java.lang.String);
+    method public android.speech.tts.VoiceInfo.Builder setParamsWithDefaults(android.os.Bundle);
+    method public android.speech.tts.VoiceInfo.Builder setQuality(int);
+    method public android.speech.tts.VoiceInfo.Builder setRequiresNetworkConnection(boolean);
+  }
+
 }
 
 package android.telephony {
@@ -23458,6 +24167,32 @@
     field public static final int SIM_STATE_UNKNOWN = 0; // 0x0
   }
 
+  public class ThirdPartyCallListener {
+    ctor public ThirdPartyCallListener(com.android.internal.telephony.IThirdPartyCallListener);
+    method public void onCallEnded(int);
+    method public void onCallEstablished();
+    method public void onCallProviderAttached(android.telephony.ThirdPartyCallProvider);
+    method public void onRingingStarted();
+    field public static final int CALL_END_INCOMING_MISSED = 2; // 0x2
+    field public static final int CALL_END_NORMAL = 1; // 0x1
+    field public static final int CALL_END_OTHER = 3; // 0x3
+  }
+
+  public class ThirdPartyCallProvider {
+    ctor public ThirdPartyCallProvider();
+    method public void hangup();
+    method public void incomingCallAccept();
+    method public void mute(boolean);
+    method public void sendDtmf(char);
+  }
+
+  public class ThirdPartyCallService {
+    ctor public ThirdPartyCallService();
+    method public android.os.IBinder getBinder();
+    method public void incomingCallAttach(android.telephony.ThirdPartyCallListener, java.lang.String);
+    method public void outgoingCallInitiate(android.telephony.ThirdPartyCallListener, java.lang.String);
+  }
+
 }
 
 package android.telephony.cdma {
@@ -25577,7 +26312,8 @@
 
   public final class Scene {
     ctor public Scene(android.view.ViewGroup);
-    ctor public Scene(android.view.ViewGroup, android.view.ViewGroup);
+    ctor public Scene(android.view.ViewGroup, android.view.View);
+    ctor public deprecated Scene(android.view.ViewGroup, android.view.ViewGroup);
     method public void enter();
     method public void exit();
     method public static android.transition.Scene getSceneForLayout(android.view.ViewGroup, int, android.content.Context);
@@ -25635,10 +26371,15 @@
     ctor public TransitionManager();
     method public static void beginDelayedTransition(android.view.ViewGroup);
     method public static void beginDelayedTransition(android.view.ViewGroup, android.transition.Transition);
+    method public android.transition.Transition getNamedTransition(java.lang.String, android.transition.Scene);
+    method public android.transition.Transition getNamedTransition(android.transition.Scene, java.lang.String);
+    method public java.lang.String[] getTargetSceneNames(android.transition.Scene);
     method public static void go(android.transition.Scene);
     method public static void go(android.transition.Scene, android.transition.Transition);
     method public void setTransition(android.transition.Scene, android.transition.Transition);
     method public void setTransition(android.transition.Scene, android.transition.Scene, android.transition.Transition);
+    method public void setTransition(android.transition.Scene, java.lang.String, android.transition.Transition);
+    method public void setTransition(java.lang.String, android.transition.Scene, android.transition.Transition);
     method public void transitionTo(android.transition.Scene);
   }
 
@@ -26472,6 +27213,7 @@
   }
 
   public class HapticFeedbackConstants {
+    field public static final int CLOCK_TICK = 4; // 0x4
     field public static final int FLAG_IGNORE_GLOBAL_SETTING = 2; // 0x2
     field public static final int FLAG_IGNORE_VIEW_SETTING = 1; // 0x1
     field public static final int KEYBOARD_TAP = 3; // 0x3
@@ -27422,6 +28164,7 @@
     ctor public SurfaceView(android.content.Context);
     ctor public SurfaceView(android.content.Context, android.util.AttributeSet);
     ctor public SurfaceView(android.content.Context, android.util.AttributeSet, int);
+    ctor public SurfaceView(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean gatherTransparentRegion(android.graphics.Region);
     method public android.view.SurfaceHolder getHolder();
     method public void setSecure(boolean);
@@ -27433,6 +28176,7 @@
     ctor public TextureView(android.content.Context);
     ctor public TextureView(android.content.Context, android.util.AttributeSet);
     ctor public TextureView(android.content.Context, android.util.AttributeSet, int);
+    ctor public TextureView(android.content.Context, android.util.AttributeSet, int, int);
     method public final void draw(android.graphics.Canvas);
     method public android.graphics.Bitmap getBitmap();
     method public android.graphics.Bitmap getBitmap(int, int);
@@ -27484,6 +28228,7 @@
     ctor public View(android.content.Context);
     ctor public View(android.content.Context, android.util.AttributeSet);
     ctor public View(android.content.Context, android.util.AttributeSet, int);
+    ctor public View(android.content.Context, android.util.AttributeSet, int, int);
     method public void addChildrenForAccessibility(java.util.ArrayList<android.view.View>);
     method public void addFocusables(java.util.ArrayList<android.view.View>, int);
     method public void addFocusables(java.util.ArrayList<android.view.View>, int, int);
@@ -28222,6 +28967,7 @@
     ctor public ViewGroup(android.content.Context);
     ctor public ViewGroup(android.content.Context, android.util.AttributeSet);
     ctor public ViewGroup(android.content.Context, android.util.AttributeSet, int);
+    ctor public ViewGroup(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean addStatesFromChildren();
     method public void addView(android.view.View);
     method public void addView(android.view.View, int);
@@ -28473,6 +29219,7 @@
     ctor public ViewStub(android.content.Context, int);
     ctor public ViewStub(android.content.Context, android.util.AttributeSet);
     ctor public ViewStub(android.content.Context, android.util.AttributeSet, int);
+    ctor public ViewStub(android.content.Context, android.util.AttributeSet, int, int);
     method public int getInflatedId();
     method public android.view.LayoutInflater getLayoutInflater();
     method public int getLayoutResource();
@@ -28555,6 +29302,7 @@
     method public final android.view.WindowManager.LayoutParams getAttributes();
     method public final android.view.Window.Callback getCallback();
     method public final android.view.Window getContainer();
+    method public android.transition.Scene getContentScene();
     method public final android.content.Context getContext();
     method public abstract android.view.View getCurrentFocus();
     method public abstract android.view.View getDecorView();
@@ -28562,6 +29310,7 @@
     method protected final int getForcedWindowFlags();
     method public abstract android.view.LayoutInflater getLayoutInflater();
     method protected final int getLocalFeatures();
+    method public android.transition.TransitionManager getTransitionManager();
     method public abstract int getVolumeControlStream();
     method public android.view.WindowManager getWindowManager();
     method public final android.content.res.TypedArray getWindowStyle();
@@ -28610,7 +29359,9 @@
     method public void setLogo(int);
     method public void setSoftInputMode(int);
     method public abstract void setTitle(java.lang.CharSequence);
-    method public abstract void setTitleColor(int);
+    method public abstract deprecated void setTitleColor(int);
+    method public void setTransitionManager(android.transition.TransitionManager);
+    method public void setTransitionOptions(android.os.Bundle);
     method public void setType(int);
     method public void setUiOptions(int);
     method public void setUiOptions(int, int);
@@ -28631,6 +29382,7 @@
     field public static final int FEATURE_ACTION_BAR = 8; // 0x8
     field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
     field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+    field public static final int FEATURE_CONTENT_TRANSITIONS = 11; // 0xb
     field public static final int FEATURE_CONTEXT_MENU = 6; // 0x6
     field public static final int FEATURE_CUSTOM_TITLE = 7; // 0x7
     field public static final int FEATURE_INDETERMINATE_PROGRESS = 5; // 0x5
@@ -28981,6 +29733,9 @@
     method public boolean performAction(int, android.os.Bundle);
     method public void recycle();
     method public boolean refresh();
+    method public void removeAction(int);
+    method public boolean removeChild(android.view.View);
+    method public boolean removeChild(android.view.View, int);
     method public void setAccessibilityFocused(boolean);
     method public void setBoundsInParent(android.graphics.Rect);
     method public void setBoundsInScreen(android.graphics.Rect);
@@ -30234,6 +30989,7 @@
     ctor public WebView(android.content.Context);
     ctor public WebView(android.content.Context, android.util.AttributeSet);
     ctor public WebView(android.content.Context, android.util.AttributeSet, int);
+    ctor public WebView(android.content.Context, android.util.AttributeSet, int, int);
     ctor public deprecated WebView(android.content.Context, android.util.AttributeSet, int, boolean);
     method public void addJavascriptInterface(java.lang.Object, java.lang.String);
     method public boolean canGoBack();
@@ -30408,6 +31164,7 @@
     ctor public AbsListView(android.content.Context);
     ctor public AbsListView(android.content.Context, android.util.AttributeSet);
     ctor public AbsListView(android.content.Context, android.util.AttributeSet, int);
+    ctor public AbsListView(android.content.Context, android.util.AttributeSet, int, int);
     method public void afterTextChanged(android.text.Editable);
     method public void beforeTextChanged(java.lang.CharSequence, int, int, int);
     method public boolean canScrollList(int);
@@ -30459,6 +31216,7 @@
     method public void setDrawSelectorOnTop(boolean);
     method public void setFastScrollAlwaysVisible(boolean);
     method public void setFastScrollEnabled(boolean);
+    method public void setFastScrollStyle(int);
     method public void setFilterText(java.lang.String);
     method public void setFriction(float);
     method public void setItemChecked(int, boolean);
@@ -30521,6 +31279,7 @@
     ctor public AbsSeekBar(android.content.Context);
     ctor public AbsSeekBar(android.content.Context, android.util.AttributeSet);
     ctor public AbsSeekBar(android.content.Context, android.util.AttributeSet, int);
+    ctor public AbsSeekBar(android.content.Context, android.util.AttributeSet, int, int);
     method public int getKeyProgressIncrement();
     method public android.graphics.drawable.Drawable getThumb();
     method public int getThumbOffset();
@@ -30533,6 +31292,7 @@
     ctor public AbsSpinner(android.content.Context);
     ctor public AbsSpinner(android.content.Context, android.util.AttributeSet);
     ctor public AbsSpinner(android.content.Context, android.util.AttributeSet, int);
+    ctor public AbsSpinner(android.content.Context, android.util.AttributeSet, int, int);
     method public android.widget.SpinnerAdapter getAdapter();
     method public android.view.View getSelectedView();
     method public void onRestoreInstanceState(android.os.Parcelable);
@@ -30547,6 +31307,7 @@
     ctor public AbsoluteLayout(android.content.Context);
     ctor public AbsoluteLayout(android.content.Context, android.util.AttributeSet);
     ctor public AbsoluteLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public AbsoluteLayout(android.content.Context, android.util.AttributeSet, int, int);
     method protected void onLayout(boolean, int, int, int, int);
   }
 
@@ -30578,6 +31339,7 @@
     ctor public AdapterView(android.content.Context);
     ctor public AdapterView(android.content.Context, android.util.AttributeSet);
     ctor public AdapterView(android.content.Context, android.util.AttributeSet, int);
+    ctor public AdapterView(android.content.Context, android.util.AttributeSet, int, int);
     method public abstract T getAdapter();
     method public int getCount();
     method public android.view.View getEmptyView();
@@ -30631,6 +31393,7 @@
     ctor public AdapterViewAnimator(android.content.Context);
     ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet);
     ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet, int);
+    ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet, int, int);
     method public void advance();
     method public void deferNotifyDataSetChanged();
     method public void fyiWillBeAdvancedByHostKThx();
@@ -30660,6 +31423,8 @@
   public class AdapterViewFlipper extends android.widget.AdapterViewAnimator {
     ctor public AdapterViewFlipper(android.content.Context);
     ctor public AdapterViewFlipper(android.content.Context, android.util.AttributeSet);
+    ctor public AdapterViewFlipper(android.content.Context, android.util.AttributeSet, int);
+    ctor public AdapterViewFlipper(android.content.Context, android.util.AttributeSet, int, int);
     method public int getFlipInterval();
     method public boolean isAutoStart();
     method public boolean isFlipping();
@@ -30690,6 +31455,7 @@
     ctor public AnalogClock(android.content.Context);
     ctor public AnalogClock(android.content.Context, android.util.AttributeSet);
     ctor public AnalogClock(android.content.Context, android.util.AttributeSet, int);
+    ctor public AnalogClock(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class ArrayAdapter extends android.widget.BaseAdapter implements android.widget.Filterable {
@@ -30722,6 +31488,7 @@
     ctor public AutoCompleteTextView(android.content.Context);
     ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet);
     ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet, int);
+    ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet, int, int);
     method public void clearListSelection();
     method protected java.lang.CharSequence convertSelectionToString(java.lang.Object);
     method public void dismissDropDown();
@@ -30814,12 +31581,14 @@
     ctor public Button(android.content.Context);
     ctor public Button(android.content.Context, android.util.AttributeSet);
     ctor public Button(android.content.Context, android.util.AttributeSet, int);
+    ctor public Button(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class CalendarView extends android.widget.FrameLayout {
     ctor public CalendarView(android.content.Context);
     ctor public CalendarView(android.content.Context, android.util.AttributeSet);
     ctor public CalendarView(android.content.Context, android.util.AttributeSet, int);
+    ctor public CalendarView(android.content.Context, android.util.AttributeSet, int, int);
     method public long getDate();
     method public int getDateTextAppearance();
     method public int getFirstDayOfWeek();
@@ -30861,6 +31630,7 @@
     ctor public CheckBox(android.content.Context);
     ctor public CheckBox(android.content.Context, android.util.AttributeSet);
     ctor public CheckBox(android.content.Context, android.util.AttributeSet, int);
+    ctor public CheckBox(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public abstract interface Checkable {
@@ -30873,6 +31643,7 @@
     ctor public CheckedTextView(android.content.Context);
     ctor public CheckedTextView(android.content.Context, android.util.AttributeSet);
     ctor public CheckedTextView(android.content.Context, android.util.AttributeSet, int);
+    ctor public CheckedTextView(android.content.Context, android.util.AttributeSet, int, int);
     method public android.graphics.drawable.Drawable getCheckMarkDrawable();
     method public boolean isChecked();
     method public void setCheckMarkDrawable(int);
@@ -30885,6 +31656,7 @@
     ctor public Chronometer(android.content.Context);
     ctor public Chronometer(android.content.Context, android.util.AttributeSet);
     ctor public Chronometer(android.content.Context, android.util.AttributeSet, int);
+    ctor public Chronometer(android.content.Context, android.util.AttributeSet, int, int);
     method public long getBase();
     method public java.lang.String getFormat();
     method public android.widget.Chronometer.OnChronometerTickListener getOnChronometerTickListener();
@@ -30903,6 +31675,7 @@
     ctor public CompoundButton(android.content.Context);
     ctor public CompoundButton(android.content.Context, android.util.AttributeSet);
     ctor public CompoundButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public CompoundButton(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean isChecked();
     method public void setButtonDrawable(int);
     method public void setButtonDrawable(android.graphics.drawable.Drawable);
@@ -30974,6 +31747,7 @@
     ctor public DatePicker(android.content.Context);
     ctor public DatePicker(android.content.Context, android.util.AttributeSet);
     ctor public DatePicker(android.content.Context, android.util.AttributeSet, int);
+    ctor public DatePicker(android.content.Context, android.util.AttributeSet, int, int);
     method public android.widget.CalendarView getCalendarView();
     method public boolean getCalendarViewShown();
     method public int getDayOfMonth();
@@ -31037,6 +31811,7 @@
     ctor public EditText(android.content.Context);
     ctor public EditText(android.content.Context, android.util.AttributeSet);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
+    ctor public EditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void extendSelection(int);
     method public void selectAll();
     method public void setSelection(int, int);
@@ -31068,6 +31843,7 @@
     ctor public ExpandableListView(android.content.Context);
     ctor public ExpandableListView(android.content.Context, android.util.AttributeSet);
     ctor public ExpandableListView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ExpandableListView(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean collapseGroup(int);
     method public boolean expandGroup(int);
     method public boolean expandGroup(int, boolean);
@@ -31157,6 +31933,7 @@
     ctor public FrameLayout(android.content.Context);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int, int);
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public android.graphics.drawable.Drawable getForeground();
     method public int getForegroundGravity();
@@ -31181,6 +31958,7 @@
     ctor public Gallery(android.content.Context);
     ctor public Gallery(android.content.Context, android.util.AttributeSet);
     ctor public Gallery(android.content.Context, android.util.AttributeSet, int);
+    ctor public Gallery(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean onDown(android.view.MotionEvent);
     method public boolean onFling(android.view.MotionEvent, android.view.MotionEvent, float, float);
     method public void onLongPress(android.view.MotionEvent);
@@ -31201,9 +31979,10 @@
   }
 
   public class GridLayout extends android.view.ViewGroup {
-    ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
-    ctor public GridLayout(android.content.Context, android.util.AttributeSet);
     ctor public GridLayout(android.content.Context);
+    ctor public GridLayout(android.content.Context, android.util.AttributeSet);
+    ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public GridLayout(android.content.Context, android.util.AttributeSet, int, int);
     method public int getAlignmentMode();
     method public int getColumnCount();
     method public int getOrientation();
@@ -31261,6 +32040,7 @@
     ctor public GridView(android.content.Context);
     ctor public GridView(android.content.Context, android.util.AttributeSet);
     ctor public GridView(android.content.Context, android.util.AttributeSet, int);
+    ctor public GridView(android.content.Context, android.util.AttributeSet, int, int);
     method public android.widget.ListAdapter getAdapter();
     method public int getColumnWidth();
     method public int getGravity();
@@ -31318,6 +32098,7 @@
     ctor public HorizontalScrollView(android.content.Context);
     ctor public HorizontalScrollView(android.content.Context, android.util.AttributeSet);
     ctor public HorizontalScrollView(android.content.Context, android.util.AttributeSet, int);
+    ctor public HorizontalScrollView(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean arrowScroll(int);
     method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect);
     method public boolean executeKeyEvent(android.view.KeyEvent);
@@ -31337,6 +32118,7 @@
     ctor public ImageButton(android.content.Context);
     ctor public ImageButton(android.content.Context, android.util.AttributeSet);
     ctor public ImageButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public ImageButton(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class ImageSwitcher extends android.widget.ViewSwitcher {
@@ -31351,6 +32133,7 @@
     ctor public ImageView(android.content.Context);
     ctor public ImageView(android.content.Context, android.util.AttributeSet);
     ctor public ImageView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ImageView(android.content.Context, android.util.AttributeSet, int, int);
     method public final void clearColorFilter();
     method public boolean getAdjustViewBounds();
     method public boolean getBaselineAlignBottom();
@@ -31402,6 +32185,7 @@
     ctor public LinearLayout(android.content.Context);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int, int);
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
@@ -31512,6 +32296,7 @@
     ctor public ListView(android.content.Context);
     ctor public ListView(android.content.Context, android.util.AttributeSet);
     ctor public ListView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ListView(android.content.Context, android.util.AttributeSet, int, int);
     method public void addFooterView(android.view.View, java.lang.Object, boolean);
     method public void addFooterView(android.view.View);
     method public void addHeaderView(android.view.View, java.lang.Object, boolean);
@@ -31584,6 +32369,7 @@
     ctor public MultiAutoCompleteTextView(android.content.Context);
     ctor public MultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet);
     ctor public MultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet, int);
+    ctor public MultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet, int, int);
     method protected void performFiltering(java.lang.CharSequence, int, int, int);
     method public void setTokenizer(android.widget.MultiAutoCompleteTextView.Tokenizer);
   }
@@ -31605,6 +32391,7 @@
     ctor public NumberPicker(android.content.Context);
     ctor public NumberPicker(android.content.Context, android.util.AttributeSet);
     ctor public NumberPicker(android.content.Context, android.util.AttributeSet, int);
+    ctor public NumberPicker(android.content.Context, android.util.AttributeSet, int, int);
     method public java.lang.String[] getDisplayedValues();
     method public int getMaxValue();
     method public int getMinValue();
@@ -31750,6 +32537,7 @@
     ctor public ProgressBar(android.content.Context);
     ctor public ProgressBar(android.content.Context, android.util.AttributeSet);
     ctor public ProgressBar(android.content.Context, android.util.AttributeSet, int);
+    ctor public ProgressBar(android.content.Context, android.util.AttributeSet, int, int);
     method public android.graphics.drawable.Drawable getIndeterminateDrawable();
     method public android.view.animation.Interpolator getInterpolator();
     method public synchronized int getMax();
@@ -31763,11 +32551,13 @@
     method public android.os.Parcelable onSaveInstanceState();
     method public synchronized void setIndeterminate(boolean);
     method public void setIndeterminateDrawable(android.graphics.drawable.Drawable);
+    method public void setIndeterminateDrawableTiled(android.graphics.drawable.Drawable);
     method public void setInterpolator(android.content.Context, int);
     method public void setInterpolator(android.view.animation.Interpolator);
     method public synchronized void setMax(int);
     method public synchronized void setProgress(int);
     method public void setProgressDrawable(android.graphics.drawable.Drawable);
+    method public void setProgressDrawableTiled(android.graphics.drawable.Drawable);
     method public synchronized void setSecondaryProgress(int);
   }
 
@@ -31775,6 +32565,7 @@
     ctor public QuickContactBadge(android.content.Context);
     ctor public QuickContactBadge(android.content.Context, android.util.AttributeSet);
     ctor public QuickContactBadge(android.content.Context, android.util.AttributeSet, int);
+    ctor public QuickContactBadge(android.content.Context, android.util.AttributeSet, int, int);
     method public void assignContactFromEmail(java.lang.String, boolean);
     method public void assignContactFromEmail(java.lang.String, boolean, android.os.Bundle);
     method public void assignContactFromPhone(java.lang.String, boolean);
@@ -31791,6 +32582,7 @@
     ctor public RadioButton(android.content.Context);
     ctor public RadioButton(android.content.Context, android.util.AttributeSet);
     ctor public RadioButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public RadioButton(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class RadioGroup extends android.widget.LinearLayout {
@@ -31816,6 +32608,7 @@
 
   public class RatingBar extends android.widget.AbsSeekBar {
     ctor public RatingBar(android.content.Context, android.util.AttributeSet, int);
+    ctor public RatingBar(android.content.Context, android.util.AttributeSet, int, int);
     ctor public RatingBar(android.content.Context, android.util.AttributeSet);
     ctor public RatingBar(android.content.Context);
     method public int getNumStars();
@@ -31838,6 +32631,7 @@
     ctor public RelativeLayout(android.content.Context);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
     method public int getGravity();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setGravity(int);
@@ -31986,6 +32780,7 @@
     ctor public ScrollView(android.content.Context);
     ctor public ScrollView(android.content.Context, android.util.AttributeSet);
     ctor public ScrollView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ScrollView(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean arrowScroll(int);
     method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect);
     method public boolean executeKeyEvent(android.view.KeyEvent);
@@ -32030,6 +32825,8 @@
   public class SearchView extends android.widget.LinearLayout implements android.view.CollapsibleActionView {
     ctor public SearchView(android.content.Context);
     ctor public SearchView(android.content.Context, android.util.AttributeSet);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet, int);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet, int, int);
     method public int getImeOptions();
     method public int getInputType();
     method public int getMaxWidth();
@@ -32084,6 +32881,7 @@
     ctor public SeekBar(android.content.Context);
     ctor public SeekBar(android.content.Context, android.util.AttributeSet);
     ctor public SeekBar(android.content.Context, android.util.AttributeSet, int);
+    ctor public SeekBar(android.content.Context, android.util.AttributeSet, int, int);
     method public void setOnSeekBarChangeListener(android.widget.SeekBar.OnSeekBarChangeListener);
   }
 
@@ -32185,6 +32983,7 @@
   public deprecated class SlidingDrawer extends android.view.ViewGroup {
     ctor public SlidingDrawer(android.content.Context, android.util.AttributeSet);
     ctor public SlidingDrawer(android.content.Context, android.util.AttributeSet, int);
+    ctor public SlidingDrawer(android.content.Context, android.util.AttributeSet, int, int);
     method public void animateClose();
     method public void animateOpen();
     method public void animateToggle();
@@ -32219,6 +33018,7 @@
   }
 
   public final class Space extends android.view.View {
+    ctor public Space(android.content.Context, android.util.AttributeSet, int, int);
     ctor public Space(android.content.Context, android.util.AttributeSet, int);
     ctor public Space(android.content.Context, android.util.AttributeSet);
     ctor public Space(android.content.Context);
@@ -32230,6 +33030,7 @@
     ctor public Spinner(android.content.Context, android.util.AttributeSet);
     ctor public Spinner(android.content.Context, android.util.AttributeSet, int);
     ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int, int);
     method public int getDropDownHorizontalOffset();
     method public int getDropDownVerticalOffset();
     method public int getDropDownWidth();
@@ -32257,12 +33058,14 @@
     ctor public StackView(android.content.Context);
     ctor public StackView(android.content.Context, android.util.AttributeSet);
     ctor public StackView(android.content.Context, android.util.AttributeSet, int);
+    ctor public StackView(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class Switch extends android.widget.CompoundButton {
     ctor public Switch(android.content.Context);
     ctor public Switch(android.content.Context, android.util.AttributeSet);
     ctor public Switch(android.content.Context, android.util.AttributeSet, int);
+    ctor public Switch(android.content.Context, android.util.AttributeSet, int, int);
     method public int getSwitchMinWidth();
     method public int getSwitchPadding();
     method public java.lang.CharSequence getTextOff();
@@ -32288,6 +33091,8 @@
   public class TabHost extends android.widget.FrameLayout implements android.view.ViewTreeObserver.OnTouchModeChangeListener {
     ctor public TabHost(android.content.Context);
     ctor public TabHost(android.content.Context, android.util.AttributeSet);
+    ctor public TabHost(android.content.Context, android.util.AttributeSet, int);
+    ctor public TabHost(android.content.Context, android.util.AttributeSet, int, int);
     method public void addTab(android.widget.TabHost.TabSpec);
     method public void clearAllTabs();
     method public int getCurrentTab();
@@ -32327,6 +33132,7 @@
     ctor public TabWidget(android.content.Context);
     ctor public TabWidget(android.content.Context, android.util.AttributeSet);
     ctor public TabWidget(android.content.Context, android.util.AttributeSet, int);
+    ctor public TabWidget(android.content.Context, android.util.AttributeSet, int, int);
     method public void dispatchDraw(android.graphics.Canvas);
     method public void focusCurrentTab(int);
     method public android.view.View getChildTabViewAt(int);
@@ -32389,6 +33195,7 @@
     ctor public TextClock(android.content.Context);
     ctor public TextClock(android.content.Context, android.util.AttributeSet);
     ctor public TextClock(android.content.Context, android.util.AttributeSet, int);
+    ctor public TextClock(android.content.Context, android.util.AttributeSet, int, int);
     method public java.lang.CharSequence getFormat12Hour();
     method public java.lang.CharSequence getFormat24Hour();
     method public java.lang.String getTimeZone();
@@ -32411,6 +33218,7 @@
     ctor public TextView(android.content.Context);
     ctor public TextView(android.content.Context, android.util.AttributeSet);
     ctor public TextView(android.content.Context, android.util.AttributeSet, int);
+    ctor public TextView(android.content.Context, android.util.AttributeSet, int, int);
     method public void addTextChangedListener(android.text.TextWatcher);
     method public final void append(java.lang.CharSequence);
     method public void append(java.lang.CharSequence, int, int);
@@ -32618,6 +33426,7 @@
     ctor public TimePicker(android.content.Context);
     ctor public TimePicker(android.content.Context, android.util.AttributeSet);
     ctor public TimePicker(android.content.Context, android.util.AttributeSet, int);
+    ctor public TimePicker(android.content.Context, android.util.AttributeSet, int, int);
     method public java.lang.Integer getCurrentHour();
     method public java.lang.Integer getCurrentMinute();
     method public boolean is24HourView();
@@ -32655,6 +33464,7 @@
   }
 
   public class ToggleButton extends android.widget.CompoundButton {
+    ctor public ToggleButton(android.content.Context, android.util.AttributeSet, int, int);
     ctor public ToggleButton(android.content.Context, android.util.AttributeSet, int);
     ctor public ToggleButton(android.content.Context, android.util.AttributeSet);
     ctor public ToggleButton(android.content.Context);
@@ -32668,6 +33478,7 @@
     ctor public TwoLineListItem(android.content.Context);
     ctor public TwoLineListItem(android.content.Context, android.util.AttributeSet);
     ctor public TwoLineListItem(android.content.Context, android.util.AttributeSet, int);
+    ctor public TwoLineListItem(android.content.Context, android.util.AttributeSet, int, int);
     method public android.widget.TextView getText1();
     method public android.widget.TextView getText2();
   }
@@ -32676,6 +33487,7 @@
     ctor public VideoView(android.content.Context);
     ctor public VideoView(android.content.Context, android.util.AttributeSet);
     ctor public VideoView(android.content.Context, android.util.AttributeSet, int);
+    ctor public VideoView(android.content.Context, android.util.AttributeSet, int, int);
     method public void addSubtitleSource(java.io.InputStream, android.media.MediaFormat);
     method public boolean canPause();
     method public boolean canSeekBackward();
@@ -32750,6 +33562,7 @@
     ctor public ZoomButton(android.content.Context);
     ctor public ZoomButton(android.content.Context, android.util.AttributeSet);
     ctor public ZoomButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public ZoomButton(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean onLongClick(android.view.View);
     method public void setZoomSpeed(long);
   }
@@ -32789,6 +33602,24 @@
 
 }
 
+package com.android.internal.telephony {
+
+  public abstract interface IThirdPartyCallListener implements android.os.IInterface {
+    method public abstract void onCallEnded(int) throws android.os.RemoteException;
+    method public abstract void onCallEstablished() throws android.os.RemoteException;
+    method public abstract void onCallProviderAttached(com.android.internal.telephony.IThirdPartyCallProvider) throws android.os.RemoteException;
+    method public abstract void onRingingStarted() throws android.os.RemoteException;
+  }
+
+  public abstract interface IThirdPartyCallProvider implements android.os.IInterface {
+    method public abstract void hangup() throws android.os.RemoteException;
+    method public abstract void incomingCallAccept() throws android.os.RemoteException;
+    method public abstract void mute(boolean) throws android.os.RemoteException;
+    method public abstract void sendDtmf(char) throws android.os.RemoteException;
+  }
+
+}
+
 package com.android.internal.util {
 
   public abstract interface Predicate {
@@ -42716,11 +43547,11 @@
   }
 
   public class ConcurrentHashMap extends java.util.AbstractMap implements java.util.concurrent.ConcurrentMap java.io.Serializable {
-    ctor public ConcurrentHashMap(int, float, int);
-    ctor public ConcurrentHashMap(int, float);
-    ctor public ConcurrentHashMap(int);
     ctor public ConcurrentHashMap();
+    ctor public ConcurrentHashMap(int);
     ctor public ConcurrentHashMap(java.util.Map<? extends K, ? extends V>);
+    ctor public ConcurrentHashMap(int, float);
+    ctor public ConcurrentHashMap(int, float, int);
     method public boolean contains(java.lang.Object);
     method public java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index f3432a0..0344d26 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -19,7 +19,7 @@
 package com.android.commands.am;
 
 import android.app.ActivityManager;
-import android.app.ActivityManager.StackInfo;
+import android.app.ActivityManager.StackBoxInfo;
 import android.app.ActivityManagerNative;
 import android.app.IActivityController;
 import android.app.IActivityManager;
@@ -31,7 +31,6 @@
 import android.content.Intent;
 import android.content.pm.IPackageManager;
 import android.content.pm.ResolveInfo;
-import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -107,11 +106,11 @@
                 "       am to-intent-uri [INTENT]\n" +
                 "       am switch-user <USER_ID>\n" +
                 "       am stop-user <USER_ID>\n" +
-                "       am stack create <TASK_ID>\n" +
+                "       am stack create <TASK_ID> <RELATIVE_STACK_BOX_ID> <POSITION> <WEIGHT>\n" +
                 "       am stack movetask <TASK_ID> <STACK_ID> [true|false]\n" +
-                "       am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
-                "       am stack list\n" +
-                "       am stack info <STACK_ID>\n" +
+                "       am stack resize <STACK_ID> <WEIGHT>\n" +
+                "       am stack boxes\n" +
+                "       am stack box <STACK_BOX_ID>\n" +
                 "\n" +
                 "am start: start an Activity.  Options are:\n" +
                 "    -D: enable debugging\n" +
@@ -205,16 +204,24 @@
                 "am stop-user: stop execution of USER_ID, not allowing it to run any\n" +
                 "  code until a later explicit switch to it.\n" +
                 "\n" +
-                "am stack create: create a new stack containing <TASK_ID> which must exist\n" +
+                "am stack create: create a new stack relative to an existing one.\n" +
+                "   <TASK_ID>: the task to populate the new stack with. Must exist.\n" +
+                "   <RELATIVE_STACK_BOX_ID>: existing stack box's id.\n" +
+                "   <POSITION>: 0: before <RELATIVE_STACK_BOX_ID>, per RTL/LTR configuration,\n" +
+                "               1: after <RELATIVE_STACK_BOX_ID>, per RTL/LTR configuration,\n" +
+                "               2: to left of <RELATIVE_STACK_BOX_ID>,\n" +
+                "               3: to right of <RELATIVE_STACK_BOX_ID>," +
+                "               4: above <RELATIVE_STACK_BOX_ID>, 5: below <RELATIVE_STACK_BOX_ID>\n" +
+                "   <WEIGHT>: float between 0.2 and 0.8 inclusive.\n" +
                 "\n" +
                 "am stack movetask: move <TASK_ID> from its current stack to the top (true) or" +
                 "   bottom (false) of <STACK_ID>.\n" +
                 "\n" +
-                "am stack resize: change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.\n" +
+                "am stack resize: change <STACK_ID> relative size to new <WEIGHT>.\n" +
                 "\n" +
-                "am stack list: list all of the activity stacks and their sizes.\n" +
+                "am stack boxes: list the hierarchy of stack boxes and their contents.\n" +
                 "\n" +
-                "am stack info: display the information about activity stack <STACK_ID>.\n" +
+                "am stack box: list the hierarchy of stack boxes rooted at <STACK_BOX_ID>.\n" +
                 "\n" +
                 "<INTENT> specifications include these flags and arguments:\n" +
                 "    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
@@ -1544,11 +1551,11 @@
         } else if (op.equals("movetask")) {
             runStackMoveTask();
         } else if (op.equals("resize")) {
-            runStackResize();
-        } else if (op.equals("list")) {
-            runStackList();
-        } else if (op.equals("info")) {
-            runStackInfo();
+            runStackBoxResize();
+        } else if (op.equals("boxes")) {
+            runStackBoxes();
+        } else if (op.equals("box")) {
+            runStackBoxInfo();
         } else {
             showError("Error: unknown command '" + op + "'");
             return;
@@ -1558,9 +1565,15 @@
     private void runStackCreate() throws Exception {
         String taskIdStr = nextArgRequired();
         int taskId = Integer.valueOf(taskIdStr);
+        String relativeToStr = nextArgRequired();
+        int relativeTo = Integer.valueOf(relativeToStr);
+        String positionStr = nextArgRequired();
+        int position = Integer.valueOf(positionStr);
+        String weightStr = nextArgRequired();
+        float weight = Float.valueOf(weightStr);
 
         try {
-            int stackId = mAm.createStack(taskId);
+            int stackId = mAm.createStack(taskId, relativeTo, position, weight);
             System.out.println("createStack returned new stackId=" + stackId + "\n\n");
         } catch (RemoteException e) {
         }
@@ -1588,40 +1601,34 @@
         }
     }
 
-    private void runStackResize() throws Exception {
-        String stackIdStr = nextArgRequired();
-        int stackId = Integer.valueOf(stackIdStr);
-        String leftStr = nextArgRequired();
-        int left = Integer.valueOf(leftStr);
-        String topStr = nextArgRequired();
-        int top = Integer.valueOf(topStr);
-        String rightStr = nextArgRequired();
-        int right = Integer.valueOf(rightStr);
-        String bottomStr = nextArgRequired();
-        int bottom = Integer.valueOf(bottomStr);
+    private void runStackBoxResize() throws Exception {
+        String stackBoxIdStr = nextArgRequired();
+        int stackBoxId = Integer.valueOf(stackBoxIdStr);
+        String weightStr = nextArgRequired();
+        float weight = Float.valueOf(weightStr);
 
         try {
-            mAm.resizeStack(stackId, new Rect(left, top, right, bottom));
+            mAm.resizeStackBox(stackBoxId, weight);
         } catch (RemoteException e) {
         }
     }
 
-    private void runStackList() throws Exception {
+    private void runStackBoxes() throws Exception {
         try {
-            List<StackInfo> stacks = mAm.getAllStackInfos();
-            for (StackInfo info : stacks) {
+            List<StackBoxInfo> stackBoxes = mAm.getStackBoxes();
+            for (StackBoxInfo info : stackBoxes) {
                 System.out.println(info);
             }
         } catch (RemoteException e) {
         }
     }
 
-    private void runStackInfo() throws Exception {
+    private void runStackBoxInfo() throws Exception {
         try {
-            String stackIdStr = nextArgRequired();
-            int stackId = Integer.valueOf(stackIdStr);
-            StackInfo info = mAm.getStackInfo(stackId);
-            System.out.println(info);
+            String stackBoxIdStr = nextArgRequired();
+            int stackBoxId = Integer.valueOf(stackBoxIdStr);
+            StackBoxInfo stackBoxInfo = mAm.getStackBoxInfo(stackBoxId); 
+            System.out.println(stackBoxInfo);
         } catch (RemoteException e) {
         }
     }
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 28752a5..8d2b739 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -7,7 +7,6 @@
 
 #define LOG_TAG "appproc"
 
-#include <cutils/properties.h>
 #include <binder/IPCThreadState.h>
 #include <binder/ProcessState.h>
 #include <utils/Log.h>
@@ -15,7 +14,6 @@
 #include <cutils/memory.h>
 #include <cutils/trace.h>
 #include <android_runtime/AndroidRuntime.h>
-#include <sys/personality.h>
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -137,33 +135,6 @@
 
 int main(int argc, char* const argv[])
 {
-#ifdef __arm__
-    /*
-     * b/7188322 - Temporarily revert to the compat memory layout
-     * to avoid breaking third party apps.
-     *
-     * THIS WILL GO AWAY IN A FUTURE ANDROID RELEASE.
-     *
-     * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=7dbaa466
-     * changes the kernel mapping from bottom up to top-down.
-     * This breaks some programs which improperly embed
-     * an out of date copy of Android's linker.
-     */
-    char value[PROPERTY_VALUE_MAX];
-    property_get("ro.kernel.qemu", value, "");
-    bool is_qemu = (strcmp(value, "1") == 0);
-    if ((getenv("NO_ADDR_COMPAT_LAYOUT_FIXUP") == NULL) && !is_qemu) {
-        int current = personality(0xFFFFFFFF);
-        if ((current & ADDR_COMPAT_LAYOUT) == 0) {
-            personality(current | ADDR_COMPAT_LAYOUT);
-            setenv("NO_ADDR_COMPAT_LAYOUT_FIXUP", "1", 1);
-            execv("/system/bin/app_process", argv);
-            return -1;
-        }
-    }
-    unsetenv("NO_ADDR_COMPAT_LAYOUT_FIXUP");
-#endif
-
     // These are global variables in ProcessState.cpp
     mArgC = argc;
     mArgV = argv;
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index ad4e4c8..8c2931f 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -123,7 +123,7 @@
     glGenTextures(1, &texture->name);
     glBindTexture(GL_TEXTURE_2D, texture->name);
 
-    switch (bitmap.getConfig()) {
+    switch (bitmap.config()) {
         case SkBitmap::kA8_Config:
             glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA,
                     GL_UNSIGNED_BYTE, p);
@@ -159,8 +159,8 @@
     SkBitmap bitmap;
     SkMemoryStream  stream(buffer, len);
     SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
-    codec->setDitherImage(false);
     if (codec) {
+        codec->setDitherImage(false);
         codec->decode(&stream, &bitmap,
                 SkBitmap::kARGB_8888_Config,
                 SkImageDecoder::kDecodePixels_Mode);
@@ -181,7 +181,7 @@
     if (tw < w) tw <<= 1;
     if (th < h) th <<= 1;
 
-    switch (bitmap.getConfig()) {
+    switch (bitmap.config()) {
         case SkBitmap::kARGB_8888_Config:
             if (tw != w || th != h) {
                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
@@ -270,7 +270,7 @@
 
     mAndroidAnimation = true;
 
-    // If the device has encryption turned on or is in process 
+    // If the device has encryption turned on or is in process
     // of being encrypted we show the encrypted boot animation.
     char decrypt[PROPERTY_VALUE_MAX];
     property_get("vold.decrypt", decrypt, "");
diff --git a/core/java/android/accounts/AccountAuthenticatorActivity.java b/core/java/android/accounts/AccountAuthenticatorActivity.java
index 6a55ddf..f9284e6 100644
--- a/core/java/android/accounts/AccountAuthenticatorActivity.java
+++ b/core/java/android/accounts/AccountAuthenticatorActivity.java
@@ -17,7 +17,6 @@
 package android.accounts;
 
 import android.app.Activity;
-import android.content.Intent;
 import android.os.Bundle;
 
 /**
diff --git a/core/java/android/accounts/AccountManagerFuture.java b/core/java/android/accounts/AccountManagerFuture.java
index a1ab00c..af00a08 100644
--- a/core/java/android/accounts/AccountManagerFuture.java
+++ b/core/java/android/accounts/AccountManagerFuture.java
@@ -15,10 +15,7 @@
  */
 package android.accounts;
 
-import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
 import java.io.IOException;
 
 /**
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index 8b01c6a..12b2b9c 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -16,7 +16,6 @@
 package android.accounts;
 
 import android.app.Activity;
-import android.content.pm.RegisteredServicesCache;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.widget.TextView;
@@ -30,7 +29,6 @@
 import com.android.internal.R;
 
 import java.io.IOException;
-import java.net.Authenticator;
 
 /**
  * @hide
diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java
index d753e32..20236aa 100644
--- a/core/java/android/animation/AnimatorInflater.java
+++ b/core/java/android/animation/AnimatorInflater.java
@@ -215,7 +215,7 @@
                 (toType <= TypedValue.TYPE_LAST_COLOR_INT))) {
             // special case for colors: ignore valueType and get ints
             getFloats = false;
-            anim.setEvaluator(new ArgbEvaluator());
+            evaluator = ArgbEvaluator.getInstance();
         }
 
         if (getFloats) {
diff --git a/core/java/android/animation/ArgbEvaluator.java b/core/java/android/animation/ArgbEvaluator.java
index 717a3d9..ed07195 100644
--- a/core/java/android/animation/ArgbEvaluator.java
+++ b/core/java/android/animation/ArgbEvaluator.java
@@ -21,6 +21,19 @@
  * values that represent ARGB colors.
  */
 public class ArgbEvaluator implements TypeEvaluator {
+    private static final ArgbEvaluator sInstance = new ArgbEvaluator();
+
+    /**
+     * Returns an instance of <code>ArgbEvaluator</code> that may be used in
+     * {@link ValueAnimator#setEvaluator(TypeEvaluator)}. The same instance may
+     * be used in multiple <code>Animator</code>s because it holds no state.
+     * @return An instance of <code>ArgbEvalutor</code>.
+     *
+     * @hide
+     */
+    public static ArgbEvaluator getInstance() {
+        return sInstance;
+    }
 
     /**
      * This function returns the calculated in-between value for a color
diff --git a/core/java/android/animation/FloatArrayEvaluator.java b/core/java/android/animation/FloatArrayEvaluator.java
new file mode 100644
index 0000000..9ae1197
--- /dev/null
+++ b/core/java/android/animation/FloatArrayEvaluator.java
@@ -0,0 +1,77 @@
+/*
+ * 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.animation;
+
+/**
+ * This evaluator can be used to perform type interpolation between <code>float[]</code> values.
+ * Each index into the array is treated as a separate value to interpolate. For example,
+ * evaluating <code>{100, 200}</code> and <code>{300, 400}</code> will interpolate the value at
+ * the first index between 100 and 300 and the value at the second index value between 200 and 400.
+ */
+public class FloatArrayEvaluator implements TypeEvaluator<float[]> {
+
+    private float[] mArray;
+
+    /**
+     * Create a FloatArrayEvaluator that does not reuse the animated value. Care must be taken
+     * when using this option because on every evaluation a new <code>float[]</code> will be
+     * allocated.
+     *
+     * @see #FloatArrayEvaluator(float[])
+     */
+    public FloatArrayEvaluator() {
+    }
+
+    /**
+     * Create a FloatArrayEvaluator that reuses <code>reuseArray</code> for every evaluate() call.
+     * Caution must be taken to ensure that the value returned from
+     * {@link android.animation.ValueAnimator#getAnimatedValue()} is not cached, modified, or
+     * used across threads. The value will be modified on each <code>evaluate()</code> call.
+     *
+     * @param reuseArray The array to modify and return from <code>evaluate</code>.
+     */
+    public FloatArrayEvaluator(float[] reuseArray) {
+        mArray = reuseArray;
+    }
+
+    /**
+     * Interpolates the value at each index by the fraction. If
+     * {@link #FloatArrayEvaluator(float[])} was used to construct this object,
+     * <code>reuseArray</code> will be returned, otherwise a new <code>float[]</code>
+     * will be returned.
+     *
+     * @param fraction   The fraction from the starting to the ending values
+     * @param startValue The start value.
+     * @param endValue   The end value.
+     * @return A <code>float[]</code> where each element is an interpolation between
+     *         the same index in startValue and endValue.
+     */
+    @Override
+    public float[] evaluate(float fraction, float[] startValue, float[] endValue) {
+        float[] array = mArray;
+        if (array == null) {
+            array = new float[startValue.length];
+        }
+
+        for (int i = 0; i < array.length; i++) {
+            float start = startValue[i];
+            float end = endValue[i];
+            array[i] = start + (fraction * (end - start));
+        }
+        return array;
+    }
+}
diff --git a/core/java/android/animation/IntArrayEvaluator.java b/core/java/android/animation/IntArrayEvaluator.java
new file mode 100644
index 0000000..d7f10f3
--- /dev/null
+++ b/core/java/android/animation/IntArrayEvaluator.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 android.animation;
+
+/**
+ * This evaluator can be used to perform type interpolation between <code>int[]</code> values.
+ * Each index into the array is treated as a separate value to interpolate. For example,
+ * evaluating <code>{100, 200}</code> and <code>{300, 400}</code> will interpolate the value at
+ * the first index between 100 and 300 and the value at the second index value between 200 and 400.
+ */
+public class IntArrayEvaluator implements TypeEvaluator<int[]> {
+
+    private int[] mArray;
+
+    /**
+     * Create an IntArrayEvaluator that does not reuse the animated value. Care must be taken
+     * when using this option because on every evaluation a new <code>int[]</code> will be
+     * allocated.
+     *
+     * @see #IntArrayEvaluator(int[])
+     */
+    public IntArrayEvaluator() {
+    }
+
+    /**
+     * Create an IntArrayEvaluator that reuses <code>reuseArray</code> for every evaluate() call.
+     * Caution must be taken to ensure that the value returned from
+     * {@link android.animation.ValueAnimator#getAnimatedValue()} is not cached, modified, or
+     * used across threads. The value will be modified on each <code>evaluate()</code> call.
+     *
+     * @param reuseArray The array to modify and return from <code>evaluate</code>.
+     */
+    public IntArrayEvaluator(int[] reuseArray) {
+        mArray = reuseArray;
+    }
+
+    /**
+     * Interpolates the value at each index by the fraction. If {@link #IntArrayEvaluator(int[])}
+     * was used to construct this object, <code>reuseArray</code> will be returned, otherwise
+     * a new <code>int[]</code> will be returned.
+     *
+     * @param fraction   The fraction from the starting to the ending values
+     * @param startValue The start value.
+     * @param endValue   The end value.
+     * @return An <code>int[]</code> where each element is an interpolation between
+     *         the same index in startValue and endValue.
+     */
+    @Override
+    public int[] evaluate(float fraction, int[] startValue, int[] endValue) {
+        int[] array = mArray;
+        if (array == null) {
+            array = new int[startValue.length];
+        }
+        for (int i = 0; i < array.length; i++) {
+            int start = startValue[i];
+            int end = endValue[i];
+            array[i] = (int) (start + (fraction * (end - start)));
+        }
+        return array;
+    }
+}
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index 9c88ccf..c0ce795 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -16,6 +16,8 @@
 
 package android.animation;
 
+import android.graphics.Path;
+import android.graphics.PointF;
 import android.util.Log;
 import android.util.Property;
 
@@ -191,7 +193,7 @@
 
     /**
      * Constructs and returns an ObjectAnimator that animates between int values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -210,8 +212,33 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
+     * using two properties. A <code>Path</code></> animation moves in two dimensions, animating
+     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are integers that are set to separate properties designated by
+     * <code>xPropertyName</code> and <code>yPropertyName</code>.
+     *
+     * @param target The object whose properties are to be animated. This object should
+     *               have public methods on it called <code>setNameX()</code> and
+     *               <code>setNameY</code>, where <code>nameX</code> and <code>nameY</code>
+     *               are the value of <code>xPropertyName</code> and <code>yPropertyName</code>
+     *               parameters, respectively.
+     * @param xPropertyName The name of the property for the x coordinate being animated.
+     * @param yPropertyName The name of the property for the y coordinate being animated.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofInt(Object target, String xPropertyName, String yPropertyName,
+            Path path) {
+        Keyframe[][] keyframes = PropertyValuesHolder.createKeyframes(path, true);
+        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframe(xPropertyName, keyframes[0]);
+        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframe(yPropertyName, keyframes[1]);
+        return ofPropertyValuesHolder(target, x, y);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between int values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -228,8 +255,135 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
+     * using two properties.  A <code>Path</code></> animation moves in two dimensions, animating
+     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are integers that are set to separate properties, <code>xProperty</code> and
+     * <code>yProperty</code>.
+     *
+     * @param target The object whose properties are to be animated.
+     * @param xProperty The property for the x coordinate being animated.
+     * @param yProperty The property for the y coordinate being animated.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static <T> ObjectAnimator ofInt(T target, Property<T, Integer> xProperty,
+            Property<T, Integer> yProperty, Path path) {
+        Keyframe[][] keyframes = PropertyValuesHolder.createKeyframes(path, true);
+        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframe(xProperty, keyframes[0]);
+        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframe(yProperty, keyframes[1]);
+        return ofPropertyValuesHolder(target, x, y);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates over int values for a multiple
+     * parameters setter. Only public methods that take only int parameters are supported.
+     * Each <code>int[]</code> contains a complete set of parameters to the setter method.
+     * At least two <code>int[]</code> values must be provided, a start and end. More than two
+     * values imply a starting value, values to animate through along the way, and an ending
+     * value (these values will be distributed evenly across the duration of the animation).
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static ObjectAnimator ofMultiInt(Object target, String propertyName, int[][] values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, values);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates the target using a multi-int setter
+     * along the given <code>Path</code>. A <code>Path</code></> animation moves in two dimensions,
+     * animating coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are integer x and y coordinates used in the first and second parameter of the
+     * setter, respectively.
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofMultiInt(Object target, String propertyName, Path path) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, path);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates over values for a multiple int
+     * parameters setter. Only public methods that take only int parameters are supported.
+     * <p>At least two values must be provided, a start and end. More than two
+     * values imply a starting value, values to animate through along the way, and an ending
+     * value (these values will be distributed evenly across the duration of the animation).</p>
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param converter Converts T objects into int parameters for the multi-value setter.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static <T> ObjectAnimator ofMultiInt(Object target, String propertyName,
+            TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, T... values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, converter,
+                evaluator, values);
+        return ObjectAnimator.ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates between color values. A single
+     * value implies that that value is the one being animated to. Two values imply starting
+     * and ending values. More than two values imply a starting value, values to animate through
+     * along the way, and an ending value (these values will be distributed evenly across
+     * the duration of the animation).
+     *
+     * @param target The object whose property is to be animated. This object should
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter.
+     * @param propertyName The name of the property being animated.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static ObjectAnimator ofArgb(Object target, String propertyName, int... values) {
+        ObjectAnimator animator = ofInt(target, propertyName, values);
+        animator.setEvaluator(ArgbEvaluator.getInstance());
+        return animator;
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates between color values. A single
+     * value implies that that value is the one being animated to. Two values imply starting
+     * and ending values. More than two values imply a starting value, values to animate through
+     * along the way, and an ending value (these values will be distributed evenly across
+     * the duration of the animation).
+     *
+     * @param target The object whose property is to be animated.
+     * @param property The property being animated.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static <T> ObjectAnimator ofArgb(T target, Property<T, Integer> property,
+            int... values) {
+        ObjectAnimator animator = ofInt(target, property, values);
+        animator.setEvaluator(ArgbEvaluator.getInstance());
+        return animator;
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between float values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -248,8 +402,33 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
+     * using two properties. A <code>Path</code></> animation moves in two dimensions, animating
+     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are floats that are set to separate properties designated by
+     * <code>xPropertyName</code> and <code>yPropertyName</code>.
+     *
+     * @param target The object whose properties are to be animated. This object should
+     *               have public methods on it called <code>setNameX()</code> and
+     *               <code>setNameY</code>, where <code>nameX</code> and <code>nameY</code>
+     *               are the value of the <code>xPropertyName</code> and <code>yPropertyName</code>
+     *               parameters, respectively.
+     * @param xPropertyName The name of the property for the x coordinate being animated.
+     * @param yPropertyName The name of the property for the y coordinate being animated.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofFloat(Object target, String xPropertyName, String yPropertyName,
+            Path path) {
+        Keyframe[][] keyframes = PropertyValuesHolder.createKeyframes(path, false);
+        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframe(xPropertyName, keyframes[0]);
+        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframe(yPropertyName, keyframes[1]);
+        return ofPropertyValuesHolder(target, x, y);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between float values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -267,8 +446,94 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
+     * using two properties. A <code>Path</code></> animation moves in two dimensions, animating
+     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are floats that are set to separate properties, <code>xProperty</code> and
+     * <code>yProperty</code>.
+     *
+     * @param target The object whose properties are to be animated.
+     * @param xProperty The property for the x coordinate being animated.
+     * @param yProperty The property for the y coordinate being animated.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static <T> ObjectAnimator ofFloat(T target, Property<T, Float> xProperty,
+            Property<T, Float> yProperty, Path path) {
+        return ofFloat(target, xProperty.getName(), yProperty.getName(), path);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates over float values for a multiple
+     * parameters setter. Only public methods that take only float parameters are supported.
+     * Each <code>float[]</code> contains a complete set of parameters to the setter method.
+     * At least two <code>float[]</code> values must be provided, a start and end. More than two
+     * values imply a starting value, values to animate through along the way, and an ending
+     * value (these values will be distributed evenly across the duration of the animation).
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static ObjectAnimator ofMultiFloat(Object target, String propertyName,
+            float[][] values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, values);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates the target using a multi-float setter
+     * along the given <code>Path</code>. A <code>Path</code></> animation moves in two dimensions,
+     * animating coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are float x and y coordinates used in the first and second parameter of the
+     * setter, respectively.
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofMultiFloat(Object target, String propertyName, Path path) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, path);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates over values for a multiple float
+     * parameters setter. Only public methods that take only float parameters are supported.
+     * <p>At least two values must be provided, a start and end. More than two
+     * values imply a starting value, values to animate through along the way, and an ending
+     * value (these values will be distributed evenly across the duration of the animation).</p>
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param converter Converts T objects into float parameters for the multi-value setter.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static <T> ObjectAnimator ofMultiFloat(Object target, String propertyName,
+            TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, T... values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, converter,
+                evaluator, values);
+        return ObjectAnimator.ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between Object values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -292,8 +557,32 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates a property along a <code>Path</code>.
+     * A <code>Path</code></> animation moves in two dimensions, animating coordinates
+     * <code>(x, y)</code> together to follow the line. This variant animates the coordinates
+     * in a <code>PointF</code> to follow the <code>Path</code>. If the <code>Property</code>
+     * associated with <code>propertyName</code> uses a type other than <code>PointF</code>,
+     * <code>converter</code> can be used to change from <code>PointF</code> to the type
+     * associated with the <code>Property</code>.
+     *
+     * @param target The object whose property is to be animated. This object should
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter.
+     * @param propertyName The name of the property being animated.
+     * @param converter Converts a PointF to the type associated with the setter. May be
+     *                  null if conversion is unnecessary.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofObject(Object target, String propertyName,
+            TypeConverter<PointF, ?> converter, Path path) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(propertyName, converter, path);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between Object values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -315,6 +604,53 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates between Object values. A single
+     * value implies that that value is the one being animated to. Two values imply starting
+     * and ending values. More than two values imply a starting value, values to animate through
+     * along the way, and an ending value (these values will be distributed evenly across
+     * the duration of the animation). This variant supplies a <code>TypeConverter</code> to
+     * convert from the animated values to the type of the property. If only one value is
+     * supplied, the <code>TypeConverter</code> must implement
+     * {@link TypeConverter#convertBack(Object)} to retrieve the current value.
+     *
+     * @param target The object whose property is to be animated.
+     * @param property The property being animated.
+     * @param converter Converts the animated object to the Property type.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static <T, V, P> ObjectAnimator ofObject(T target, Property<T, P> property,
+            TypeConverter<V, P> converter, TypeEvaluator<V> evaluator, V... values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(property, converter, evaluator,
+                values);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates a property along a <code>Path</code>.
+     * A <code>Path</code></> animation moves in two dimensions, animating coordinates
+     * <code>(x, y)</code> together to follow the line. This variant animates the coordinates
+     * in a <code>PointF</code> to follow the <code>Path</code>. If <code>property</code>
+     * uses a type other than <code>PointF</code>, <code>converter</code> can be used to change
+     * from <code>PointF</code> to the type associated with the <code>Property</code>.
+     *
+     * @param target The object whose property is to be animated.
+     * @param property The property being animated. Should not be null.
+     * @param converter Converts a PointF to the type associated with the setter. May be
+     *                  null if conversion is unnecessary.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static <T, V> ObjectAnimator ofObject(T target, Property<T, V> property,
+            TypeConverter<PointF, V> converter, Path path) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(property, converter, path);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between the sets of values specified
      * in <code>PropertyValueHolder</code> objects. This variant should be used when animating
      * several properties at once with the same ObjectAnimator, since PropertyValuesHolder allows
diff --git a/core/java/android/animation/PointFEvaluator.java b/core/java/android/animation/PointFEvaluator.java
new file mode 100644
index 0000000..91d501f
--- /dev/null
+++ b/core/java/android/animation/PointFEvaluator.java
@@ -0,0 +1,83 @@
+/*
+ * 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.animation;
+
+import android.graphics.PointF;
+
+/**
+ * This evaluator can be used to perform type interpolation between <code>PointF</code> values.
+ */
+public class PointFEvaluator implements TypeEvaluator<PointF> {
+
+    /**
+     * When null, a new PointF is returned on every evaluate call. When non-null,
+     * mPoint will be modified and returned on every evaluate.
+     */
+    private PointF mPoint;
+
+    /**
+     * Construct a PointFEvaluator that returns a new PointF on every evaluate call.
+     * To avoid creating an object for each evaluate call,
+     * {@link PointFEvaluator#PointFEvaluator(android.graphics.PointF)} should be used
+     * whenever possible.
+     */
+    public PointFEvaluator() {
+    }
+
+    /**
+     * Constructs a PointFEvaluator that modifies and returns <code>reuse</code>
+     * in {@link #evaluate(float, android.graphics.PointF, android.graphics.PointF)} calls.
+     * The value returned from
+     * {@link #evaluate(float, android.graphics.PointF, android.graphics.PointF)} should
+     * not be cached because it will change over time as the object is reused on each
+     * call.
+     *
+     * @param reuse A PointF to be modified and returned by evaluate.
+     */
+    public PointFEvaluator(PointF reuse) {
+        mPoint = reuse;
+    }
+
+    /**
+     * This function returns the result of linearly interpolating the start and
+     * end PointF values, with <code>fraction</code> representing the proportion
+     * between the start and end values. The calculation is a simple parametric
+     * calculation on each of the separate components in the PointF objects
+     * (x, y).
+     *
+     * <p>If {@link #PointFEvaluator(android.graphics.PointF)} was used to construct
+     * this PointFEvaluator, the object returned will be the <code>reuse</code>
+     * passed into the constructor.</p>
+     *
+     * @param fraction   The fraction from the starting to the ending values
+     * @param startValue The start PointF
+     * @param endValue   The end PointF
+     * @return A linear interpolation between the start and end values, given the
+     *         <code>fraction</code> parameter.
+     */
+    @Override
+    public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
+        float x = startValue.x + (fraction * (endValue.x - startValue.x));
+        float y = startValue.y + (fraction * (endValue.y - startValue.y));
+
+        if (mPoint != null) {
+            mPoint.set(x, y);
+            return mPoint;
+        } else {
+            return new PointF(x, y);
+        }
+    }
+}
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 43014ad..1b028e0 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -16,6 +16,9 @@
 
 package android.animation;
 
+import android.graphics.Path;
+import android.graphics.PointF;
+import android.util.FloatMath;
 import android.util.FloatProperty;
 import android.util.IntProperty;
 import android.util.Log;
@@ -124,6 +127,11 @@
     private Object mAnimatedValue;
 
     /**
+     * Converts from the source Object type to the setter Object type.
+     */
+    private TypeConverter mConverter;
+
+    /**
      * Internal utility constructor, used by the factory methods to set the property name.
      * @param propertyName The name of the property for this holder.
      */
@@ -166,6 +174,104 @@
 
     /**
      * Constructs and returns a PropertyValuesHolder with a given property name and
+     * set of <code>int[]</code> values. At least two <code>int[]</code> values must be supplied,
+     * a start and end value. If more values are supplied, the values will be animated from the
+     * start, through all intermediate values to the end value. When used with ObjectAnimator,
+     * the elements of the array represent the parameters of the setter function.
+     *
+     * @param propertyName The name of the property being animated. Can also be the
+     *                     case-sensitive name of the entire setter method. Should not be null.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see IntArrayEvaluator#IntArrayEvaluator(int[])
+     * @see ObjectAnimator#ofMultiInt(Object, String, TypeConverter, TypeEvaluator, Object[])
+     */
+    public static PropertyValuesHolder ofMultiInt(String propertyName, int[][] values) {
+        if (values.length < 2) {
+            throw new IllegalArgumentException("At least 2 values must be supplied");
+        }
+        int numParameters = 0;
+        for (int i = 0; i < values.length; i++) {
+            if (values[i] == null) {
+                throw new IllegalArgumentException("values must not be null");
+            }
+            int length = values[i].length;
+            if (i == 0) {
+                numParameters = length;
+            } else if (length != numParameters) {
+                throw new IllegalArgumentException("Values must all have the same length");
+            }
+        }
+        IntArrayEvaluator evaluator = new IntArrayEvaluator(new int[numParameters]);
+        return new MultiIntValuesHolder(propertyName, null, evaluator, (Object[]) values);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property name to use
+     * as a multi-int setter. The values are animated along the path, with the first
+     * parameter of the setter set to the x coordinate and the second set to the y coordinate.
+     *
+     * @param propertyName The name of the property being animated. Can also be the
+     *                     case-sensitive name of the entire setter method. Should not be null.
+     *                     The setter must take exactly two <code>int</code> parameters.
+     * @param path The Path along which the values should be animated.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see ObjectAnimator#ofPropertyValuesHolder(Object, PropertyValuesHolder...)
+     */
+    public static PropertyValuesHolder ofMultiInt(String propertyName, Path path) {
+        Keyframe[] keyframes = createKeyframes(path);
+        KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(keyframes);
+        TypeEvaluator<PointF> evaluator = new PointFEvaluator(new PointF());
+        PointFToIntArray converter = new PointFToIntArray();
+        return new MultiIntValuesHolder(propertyName, converter, evaluator, keyframeSet);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property and
+     * set of Object values for use with ObjectAnimator multi-value setters. The Object
+     * values are converted to <code>int[]</code> using the converter.
+     *
+     * @param propertyName The property being animated or complete name of the setter.
+     *                     Should not be null.
+     * @param converter Used to convert the animated value to setter parameters.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see ObjectAnimator#ofMultiInt(Object, String, TypeConverter, TypeEvaluator, Object[])
+     * @see ObjectAnimator#ofPropertyValuesHolder(Object, PropertyValuesHolder...)
+     */
+    public static <V> PropertyValuesHolder ofMultiInt(String propertyName,
+            TypeConverter<V, int[]> converter, TypeEvaluator<V> evaluator, V... values) {
+        return new MultiIntValuesHolder(propertyName, converter, evaluator, values);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder object with the specified property name or
+     * setter name for use in a multi-int setter function using ObjectAnimator. The values can be
+     * of any type, but the type should be consistent so that the supplied
+     * {@link android.animation.TypeEvaluator} can be used to to evaluate the animated value. The
+     * <code>converter</code> converts the values to parameters in the setter function.
+     *
+     * <p>At least two values must be supplied, a start and an end value.</p>
+     *
+     * @param propertyName The name of the property to associate with the set of values. This
+     *                     may also be the complete name of a setter function.
+     * @param converter    Converts <code>values</code> into int parameters for the setter.
+     *                     Can be null if the Keyframes have int[] values.
+     * @param evaluator    Used to interpolate between values.
+     * @param values       The values at specific fractional times to evaluate between
+     * @return A PropertyValuesHolder for a multi-int parameter setter.
+     */
+    public static <T> PropertyValuesHolder ofMultiInt(String propertyName,
+            TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, Keyframe... values) {
+        KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
+        return new MultiIntValuesHolder(propertyName, converter, evaluator, keyframeSet);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property name and
      * set of float values.
      * @param propertyName The name of the property being animated.
      * @param values The values that the named property will animate between.
@@ -188,6 +294,103 @@
 
     /**
      * Constructs and returns a PropertyValuesHolder with a given property name and
+     * set of <code>float[]</code> values. At least two <code>float[]</code> values must be supplied,
+     * a start and end value. If more values are supplied, the values will be animated from the
+     * start, through all intermediate values to the end value. When used with ObjectAnimator,
+     * the elements of the array represent the parameters of the setter function.
+     *
+     * @param propertyName The name of the property being animated. Can also be the
+     *                     case-sensitive name of the entire setter method. Should not be null.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see FloatArrayEvaluator#FloatArrayEvaluator(float[])
+     * @see ObjectAnimator#ofMultiFloat(Object, String, TypeConverter, TypeEvaluator, Object[])
+     */
+    public static PropertyValuesHolder ofMultiFloat(String propertyName, float[][] values) {
+        if (values.length < 2) {
+            throw new IllegalArgumentException("At least 2 values must be supplied");
+        }
+        int numParameters = 0;
+        for (int i = 0; i < values.length; i++) {
+            if (values[i] == null) {
+                throw new IllegalArgumentException("values must not be null");
+            }
+            int length = values[i].length;
+            if (i == 0) {
+                numParameters = length;
+            } else if (length != numParameters) {
+                throw new IllegalArgumentException("Values must all have the same length");
+            }
+        }
+        FloatArrayEvaluator evaluator = new FloatArrayEvaluator(new float[numParameters]);
+        return new MultiFloatValuesHolder(propertyName, null, evaluator, (Object[]) values);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property name to use
+     * as a multi-float setter. The values are animated along the path, with the first
+     * parameter of the setter set to the x coordinate and the second set to the y coordinate.
+     *
+     * @param propertyName The name of the property being animated. Can also be the
+     *                     case-sensitive name of the entire setter method. Should not be null.
+     *                     The setter must take exactly two <code>float</code> parameters.
+     * @param path The Path along which the values should be animated.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see ObjectAnimator#ofPropertyValuesHolder(Object, PropertyValuesHolder...)
+     */
+    public static PropertyValuesHolder ofMultiFloat(String propertyName, Path path) {
+        Keyframe[] keyframes = createKeyframes(path);
+        KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(keyframes);
+        TypeEvaluator<PointF> evaluator = new PointFEvaluator(new PointF());
+        PointFToFloatArray converter = new PointFToFloatArray();
+        return new MultiFloatValuesHolder(propertyName, converter, evaluator, keyframeSet);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property and
+     * set of Object values for use with ObjectAnimator multi-value setters. The Object
+     * values are converted to <code>float[]</code> using the converter.
+     *
+     * @param propertyName The property being animated or complete name of the setter.
+     *                     Should not be null.
+     * @param converter Used to convert the animated value to setter parameters.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see ObjectAnimator#ofMultiFloat(Object, String, TypeConverter, TypeEvaluator, Object[])
+     */
+    public static <V> PropertyValuesHolder ofMultiFloat(String propertyName,
+            TypeConverter<V, float[]> converter, TypeEvaluator<V> evaluator, V... values) {
+        return new MultiFloatValuesHolder(propertyName, converter, evaluator, values);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder object with the specified property name or
+     * setter name for use in a multi-float setter function using ObjectAnimator. The values can be
+     * of any type, but the type should be consistent so that the supplied
+     * {@link android.animation.TypeEvaluator} can be used to to evaluate the animated value. The
+     * <code>converter</code> converts the values to parameters in the setter function.
+     *
+     * <p>At least two values must be supplied, a start and an end value.</p>
+     *
+     * @param propertyName The name of the property to associate with the set of values. This
+     *                     may also be the complete name of a setter function.
+     * @param converter    Converts <code>values</code> into float parameters for the setter.
+     *                     Can be null if the Keyframes have float[] values.
+     * @param evaluator    Used to interpolate between values.
+     * @param values       The values at specific fractional times to evaluate between
+     * @return A PropertyValuesHolder for a multi-float parameter setter.
+     */
+    public static <T> PropertyValuesHolder ofMultiFloat(String propertyName,
+            TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, Keyframe... values) {
+        KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
+        return new MultiFloatValuesHolder(propertyName, converter, evaluator, keyframeSet);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property name and
      * set of Object values. This variant also takes a TypeEvaluator because the system
      * cannot automatically interpolate between objects of unknown type.
      *
@@ -207,6 +410,27 @@
     }
 
     /**
+     * Constructs and returns a PropertyValuesHolder with a given property name and
+     * a Path along which the values should be animated. This variant supports a
+     * <code>TypeConverter</code> to convert from <code>PointF</code> to the target
+     * type.
+     *
+     * @param propertyName The name of the property being animated.
+     * @param converter Converts a PointF to the type associated with the setter. May be
+     *                  null if conversion is unnecessary.
+     * @param path The Path along which the values should be animated.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     */
+    public static PropertyValuesHolder ofObject(String propertyName,
+            TypeConverter<PointF, ?> converter, Path path) {
+        Keyframe[] keyframes = createKeyframes(path);
+        PropertyValuesHolder pvh = ofKeyframe(propertyName, keyframes);
+        pvh.setEvaluator(new PointFEvaluator(new PointF()));
+        pvh.setConverter(converter);
+        return pvh;
+    }
+
+    /**
      * Constructs and returns a PropertyValuesHolder with a given property and
      * set of Object values. This variant also takes a TypeEvaluator because the system
      * cannot automatically interpolate between objects of unknown type.
@@ -227,6 +451,55 @@
     }
 
     /**
+     * Constructs and returns a PropertyValuesHolder with a given property and
+     * set of Object values. This variant also takes a TypeEvaluator because the system
+     * cannot automatically interpolate between objects of unknown type. This variant also
+     * takes a <code>TypeConverter</code> to convert from animated values to the type
+     * of the property. If only one value is supplied, the <code>TypeConverter</code>
+     * must implement {@link TypeConverter#convertBack(Object)} to retrieve the current
+     * value.
+     *
+     * @param property The property being animated. Should not be null.
+     * @param converter Converts the animated object to the Property type.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see #setConverter(TypeConverter)
+     * @see TypeConverter
+     */
+    public static <T, V> PropertyValuesHolder ofObject(Property<?, V> property,
+            TypeConverter<T, V> converter, TypeEvaluator<T> evaluator, T... values) {
+        PropertyValuesHolder pvh = new PropertyValuesHolder(property);
+        pvh.setConverter(converter);
+        pvh.setObjectValues(values);
+        pvh.setEvaluator(evaluator);
+        return pvh;
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property and
+     * a Path along which the values should be animated. This variant supports a
+     * <code>TypeConverter</code> to convert from <code>PointF</code> to the target
+     * type.
+     *
+     * @param property The property being animated. Should not be null.
+     * @param converter Converts a PointF to the type associated with the setter. May be
+     *                  null if conversion is unnecessary.
+     * @param path The Path along which the values should be animated.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     */
+    public static <V> PropertyValuesHolder ofObject(Property<?, V> property,
+            TypeConverter<PointF, V> converter, Path path) {
+        Keyframe[] keyframes = createKeyframes(path);
+        PropertyValuesHolder pvh = ofKeyframe(property, keyframes);
+        pvh.setEvaluator(new PointFEvaluator(new PointF()));
+        pvh.setConverter(converter);
+        return pvh;
+    }
+
+    /**
      * Constructs and returns a PropertyValuesHolder object with the specified property name and set
      * of values. These values can be of any type, but the type should be consistent so that
      * an appropriate {@link android.animation.TypeEvaluator} can be found that matches
@@ -361,6 +634,14 @@
     }
 
     /**
+     * Sets the converter to convert from the values type to the setter's parameter type.
+     * @param converter The converter to use to convert values.
+     */
+    public void setConverter(TypeConverter converter) {
+        mConverter = converter;
+    }
+
+    /**
      * Determine the setter or getter function using the JavaBeans convention of setFoo or
      * getFoo for a property named 'foo'. This function figures out what the name of the
      * function should be and uses reflection to find the Method with that name on the
@@ -389,22 +670,24 @@
         } else {
             args = new Class[1];
             Class typeVariants[];
-            if (mValueType.equals(Float.class)) {
+            if (valueType.equals(Float.class)) {
                 typeVariants = FLOAT_VARIANTS;
-            } else if (mValueType.equals(Integer.class)) {
+            } else if (valueType.equals(Integer.class)) {
                 typeVariants = INTEGER_VARIANTS;
-            } else if (mValueType.equals(Double.class)) {
+            } else if (valueType.equals(Double.class)) {
                 typeVariants = DOUBLE_VARIANTS;
             } else {
                 typeVariants = new Class[1];
-                typeVariants[0] = mValueType;
+                typeVariants[0] = valueType;
             }
             for (Class typeVariant : typeVariants) {
                 args[0] = typeVariant;
                 try {
                     returnVal = targetClass.getMethod(methodName, args);
-                    // change the value type to suit
-                    mValueType = typeVariant;
+                    if (mConverter == null) {
+                        // change the value type to suit
+                        mValueType = typeVariant;
+                    }
                     return returnVal;
                 } catch (NoSuchMethodException e) {
                     // Swallow the error and keep trying other variants
@@ -415,7 +698,7 @@
 
         if (returnVal == null) {
             Log.w("PropertyValuesHolder", "Method " +
-                    getMethodName(prefix, mPropertyName) + "() with type " + mValueType +
+                    getMethodName(prefix, mPropertyName) + "() with type " + valueType +
                     " not found on target class " + targetClass);
         }
 
@@ -465,7 +748,8 @@
      * @param targetClass The Class on which the requested method should exist.
      */
     void setupSetter(Class targetClass) {
-        mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", mValueType);
+        Class<?> propertyType = mConverter == null ? mValueType : mConverter.getTargetType();
+        mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", propertyType);
     }
 
     /**
@@ -489,10 +773,13 @@
         if (mProperty != null) {
             // check to make sure that mProperty is on the class of target
             try {
-                Object testValue = mProperty.get(target);
+                Object testValue = null;
                 for (Keyframe kf : mKeyframeSet.mKeyframes) {
                     if (!kf.hasValue()) {
-                        kf.setValue(mProperty.get(target));
+                        if (testValue == null) {
+                            testValue = convertBack(mProperty.get(target));
+                        }
+                        kf.setValue(testValue);
                     }
                 }
                 return;
@@ -516,7 +803,8 @@
                     }
                 }
                 try {
-                    kf.setValue(mGetter.invoke(target));
+                    Object value = convertBack(mGetter.invoke(target));
+                    kf.setValue(value);
                 } catch (InvocationTargetException e) {
                     Log.e("PropertyValuesHolder", e.toString());
                 } catch (IllegalAccessException e) {
@@ -526,6 +814,18 @@
         }
     }
 
+    private Object convertBack(Object value) {
+        if (mConverter != null) {
+            value = mConverter.convertBack(value);
+            if (value == null) {
+                throw new IllegalArgumentException("Converter "
+                        + mConverter.getClass().getName()
+                        + " must implement convertBack and not return null.");
+            }
+        }
+        return value;
+    }
+
     /**
      * Utility function to set the value stored in a particular Keyframe. The value used is
      * whatever the value is for the property name specified in the keyframe on the target object.
@@ -535,7 +835,8 @@
      */
     private void setupValue(Object target, Keyframe kf) {
         if (mProperty != null) {
-            kf.setValue(mProperty.get(target));
+            Object value = convertBack(mProperty.get(target));
+            kf.setValue(value);
         }
         try {
             if (mGetter == null) {
@@ -546,7 +847,8 @@
                     return;
                 }
             }
-            kf.setValue(mGetter.invoke(target));
+            Object value = convertBack(mGetter.invoke(target));
+            kf.setValue(value);
         } catch (InvocationTargetException e) {
             Log.e("PropertyValuesHolder", e.toString());
         } catch (IllegalAccessException e) {
@@ -657,7 +959,8 @@
      * @param fraction The elapsed, interpolated fraction of the animation.
      */
     void calculateValue(float fraction) {
-        mAnimatedValue = mKeyframeSet.getValue(fraction);
+        Object value = mKeyframeSet.getValue(fraction);
+        mAnimatedValue = mConverter == null ? value : mConverter.convert(value);
     }
 
     /**
@@ -1015,8 +1318,334 @@
 
     }
 
+    static class MultiFloatValuesHolder extends PropertyValuesHolder {
+        private int mJniSetter;
+        private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap =
+                new HashMap<Class, HashMap<String, Integer>>();
+
+        public MultiFloatValuesHolder(String propertyName, TypeConverter converter,
+                TypeEvaluator evaluator, Object... values) {
+            super(propertyName);
+            setConverter(converter);
+            setObjectValues(values);
+            setEvaluator(evaluator);
+        }
+
+        public MultiFloatValuesHolder(String propertyName, TypeConverter converter,
+                TypeEvaluator evaluator, KeyframeSet keyframeSet) {
+            super(propertyName);
+            setConverter(converter);
+            mKeyframeSet = keyframeSet;
+            setEvaluator(evaluator);
+        }
+
+        /**
+         * Internal function to set the value on the target object, using the setter set up
+         * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+         * to handle turning the value calculated by ValueAnimator into a value set on the object
+         * according to the name of the property.
+         *
+         * @param target The target object on which the value is set
+         */
+        @Override
+        void setAnimatedValue(Object target) {
+            float[] values = (float[]) getAnimatedValue();
+            int numParameters = values.length;
+            if (mJniSetter != 0) {
+                switch (numParameters) {
+                    case 1:
+                        nCallFloatMethod(target, mJniSetter, values[0]);
+                        break;
+                    case 2:
+                        nCallTwoFloatMethod(target, mJniSetter, values[0], values[1]);
+                        break;
+                    case 4:
+                        nCallFourFloatMethod(target, mJniSetter, values[0], values[1],
+                                values[2], values[3]);
+                        break;
+                    default: {
+                        nCallMultipleFloatMethod(target, mJniSetter, values);
+                        break;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Internal function (called from ObjectAnimator) to set up the setter and getter
+         * prior to running the animation. No getter can be used for multiple parameters.
+         *
+         * @param target The object on which the setter exists.
+         */
+        @Override
+        void setupSetterAndGetter(Object target) {
+            setupSetter(target.getClass());
+        }
+
+        @Override
+        void setupSetter(Class targetClass) {
+            if (mJniSetter != 0) {
+                return;
+            }
+            try {
+                mPropertyMapLock.writeLock().lock();
+                HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass);
+                if (propertyMap != null) {
+                    Integer jniSetterInteger = propertyMap.get(mPropertyName);
+                    if (jniSetterInteger != null) {
+                        mJniSetter = jniSetterInteger;
+                    }
+                }
+                if (mJniSetter == 0) {
+                    String methodName = getMethodName("set", mPropertyName);
+                    calculateValue(0f);
+                    float[] values = (float[]) getAnimatedValue();
+                    int numParams = values.length;
+                    try {
+                        mJniSetter = nGetMultipleFloatMethod(targetClass, methodName, numParams);
+                    } catch (NoSuchMethodError e) {
+                        // try without the 'set' prefix
+                        mJniSetter = nGetMultipleFloatMethod(targetClass, mPropertyName, numParams);
+                    }
+                    if (mJniSetter != 0) {
+                        if (propertyMap == null) {
+                            propertyMap = new HashMap<String, Integer>();
+                            sJNISetterPropertyMap.put(targetClass, propertyMap);
+                        }
+                        propertyMap.put(mPropertyName, mJniSetter);
+                    }
+                }
+            } finally {
+                mPropertyMapLock.writeLock().unlock();
+            }
+        }
+    }
+
+    static class MultiIntValuesHolder extends PropertyValuesHolder {
+        private int mJniSetter;
+        private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap =
+                new HashMap<Class, HashMap<String, Integer>>();
+
+        public MultiIntValuesHolder(String propertyName, TypeConverter converter,
+                TypeEvaluator evaluator, Object... values) {
+            super(propertyName);
+            setConverter(converter);
+            setObjectValues(values);
+            setEvaluator(evaluator);
+        }
+
+        public MultiIntValuesHolder(String propertyName, TypeConverter converter,
+                TypeEvaluator evaluator, KeyframeSet keyframeSet) {
+            super(propertyName);
+            setConverter(converter);
+            mKeyframeSet = keyframeSet;
+            setEvaluator(evaluator);
+        }
+
+        /**
+         * Internal function to set the value on the target object, using the setter set up
+         * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+         * to handle turning the value calculated by ValueAnimator into a value set on the object
+         * according to the name of the property.
+         *
+         * @param target The target object on which the value is set
+         */
+        @Override
+        void setAnimatedValue(Object target) {
+            int[] values = (int[]) getAnimatedValue();
+            int numParameters = values.length;
+            if (mJniSetter != 0) {
+                switch (numParameters) {
+                    case 1:
+                        nCallIntMethod(target, mJniSetter, values[0]);
+                        break;
+                    case 2:
+                        nCallTwoIntMethod(target, mJniSetter, values[0], values[1]);
+                        break;
+                    case 4:
+                        nCallFourIntMethod(target, mJniSetter, values[0], values[1],
+                                values[2], values[3]);
+                        break;
+                    default: {
+                        nCallMultipleIntMethod(target, mJniSetter, values);
+                        break;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Internal function (called from ObjectAnimator) to set up the setter and getter
+         * prior to running the animation. No getter can be used for multiple parameters.
+         *
+         * @param target The object on which the setter exists.
+         */
+        @Override
+        void setupSetterAndGetter(Object target) {
+            setupSetter(target.getClass());
+        }
+
+        @Override
+        void setupSetter(Class targetClass) {
+            if (mJniSetter != 0) {
+                return;
+            }
+            try {
+                mPropertyMapLock.writeLock().lock();
+                HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass);
+                if (propertyMap != null) {
+                    Integer jniSetterInteger = propertyMap.get(mPropertyName);
+                    if (jniSetterInteger != null) {
+                        mJniSetter = jniSetterInteger;
+                    }
+                }
+                if (mJniSetter == 0) {
+                    String methodName = getMethodName("set", mPropertyName);
+                    calculateValue(0f);
+                    int[] values = (int[]) getAnimatedValue();
+                    int numParams = values.length;
+                    try {
+                        mJniSetter = nGetMultipleIntMethod(targetClass, methodName, numParams);
+                    } catch (NoSuchMethodError e) {
+                        // try without the 'set' prefix
+                        mJniSetter = nGetMultipleIntMethod(targetClass, mPropertyName, numParams);
+                    }
+                    if (mJniSetter != 0) {
+                        if (propertyMap == null) {
+                            propertyMap = new HashMap<String, Integer>();
+                            sJNISetterPropertyMap.put(targetClass, propertyMap);
+                        }
+                        propertyMap.put(mPropertyName, mJniSetter);
+                    }
+                }
+            } finally {
+                mPropertyMapLock.writeLock().unlock();
+            }
+        }
+    }
+
+    /* Path interpolation relies on approximating the Path as a series of line segments.
+       The line segments are recursively divided until there is less than 1/2 pixel error
+       between the lines and the curve. Each point of the line segment is converted
+       to a Keyframe and a linear interpolation between Keyframes creates a good approximation
+       of the curve.
+
+       The fraction for each Keyframe is the length along the Path to the point, divided by
+       the total Path length. Two points may have the same fraction in the case of a move
+       command causing a disjoint Path.
+
+       The value for each Keyframe is either the point as a PointF or one of the x or y
+       coordinates as an int or float. In the latter case, two Keyframes are generated for
+       each point that have the same fraction. */
+
+    /**
+     * Returns separate Keyframes arrays for the x and y coordinates along a Path. If
+     * isInt is true, the Keyframes will be IntKeyframes, otherwise they will be FloatKeyframes.
+     * The element at index 0 are the x coordinate Keyframes and element at index 1 are the
+     * y coordinate Keyframes. The returned values can be linearly interpolated and get less
+     * than 1/2 pixel error.
+     */
+    static Keyframe[][] createKeyframes(Path path, boolean isInt) {
+        if (path == null || path.isEmpty()) {
+            throw new IllegalArgumentException("The path must not be null or empty");
+        }
+        float[] pointComponents = path.approximate(0.5f);
+
+        int numPoints = pointComponents.length / 3;
+
+        Keyframe[][] keyframes = new Keyframe[2][];
+        keyframes[0] = new Keyframe[numPoints];
+        keyframes[1] = new Keyframe[numPoints];
+        int componentIndex = 0;
+        for (int i = 0; i < numPoints; i++) {
+            float fraction = pointComponents[componentIndex++];
+            float x = pointComponents[componentIndex++];
+            float y = pointComponents[componentIndex++];
+            if (isInt) {
+                keyframes[0][i] = Keyframe.ofInt(fraction, Math.round(x));
+                keyframes[1][i] = Keyframe.ofInt(fraction, Math.round(y));
+            } else {
+                keyframes[0][i] = Keyframe.ofFloat(fraction, x);
+                keyframes[1][i] = Keyframe.ofFloat(fraction, y);
+            }
+        }
+        return keyframes;
+    }
+
+    /**
+     * Returns PointF Keyframes for a Path. The resulting points can be linearly interpolated
+     * with less than 1/2 pixel in error.
+     */
+    private static Keyframe[] createKeyframes(Path path) {
+        if (path == null || path.isEmpty()) {
+            throw new IllegalArgumentException("The path must not be null or empty");
+        }
+        float[] pointComponents = path.approximate(0.5f);
+
+        int numPoints = pointComponents.length / 3;
+
+        Keyframe[] keyframes = new Keyframe[numPoints];
+        int componentIndex = 0;
+        for (int i = 0; i < numPoints; i++) {
+            float fraction = pointComponents[componentIndex++];
+            float x = pointComponents[componentIndex++];
+            float y = pointComponents[componentIndex++];
+            keyframes[i] = Keyframe.ofObject(fraction, new PointF(x, y));
+        }
+        return keyframes;
+    }
+
+    /**
+     * Convert from PointF to float[] for multi-float setters along a Path.
+     */
+    private static class PointFToFloatArray extends TypeConverter<PointF, float[]> {
+        private float[] mCoordinates = new float[2];
+
+        public PointFToFloatArray() {
+            super(PointF.class, float[].class);
+        }
+
+        @Override
+        public float[] convert(PointF value) {
+            mCoordinates[0] = value.x;
+            mCoordinates[1] = value.y;
+            return mCoordinates;
+        }
+    };
+
+    /**
+     * Convert from PointF to int[] for multi-int setters along a Path.
+     */
+    private static class PointFToIntArray extends TypeConverter<PointF, int[]> {
+        private int[] mCoordinates = new int[2];
+
+        public PointFToIntArray() {
+            super(PointF.class, int[].class);
+        }
+
+        @Override
+        public int[] convert(PointF value) {
+            mCoordinates[0] = Math.round(value.x);
+            mCoordinates[1] = Math.round(value.y);
+            return mCoordinates;
+        }
+    };
+
     native static private int nGetIntMethod(Class targetClass, String methodName);
     native static private int nGetFloatMethod(Class targetClass, String methodName);
+    native static private int nGetMultipleIntMethod(Class targetClass, String methodName,
+            int numParams);
+    native static private int nGetMultipleFloatMethod(Class targetClass, String methodName,
+            int numParams);
     native static private void nCallIntMethod(Object target, int methodID, int arg);
     native static private void nCallFloatMethod(Object target, int methodID, float arg);
-}
\ No newline at end of file
+    native static private void nCallTwoIntMethod(Object target, int methodID, int arg1, int arg2);
+    native static private void nCallFourIntMethod(Object target, int methodID, int arg1, int arg2,
+            int arg3, int arg4);
+    native static private void nCallMultipleIntMethod(Object target, int methodID, int[] args);
+    native static private void nCallTwoFloatMethod(Object target, int methodID, float arg1,
+            float arg2);
+    native static private void nCallFourFloatMethod(Object target, int methodID, float arg1,
+            float arg2, float arg3, float arg4);
+    native static private void nCallMultipleFloatMethod(Object target, int methodID, float[] args);
+}
diff --git a/core/java/android/animation/RectEvaluator.java b/core/java/android/animation/RectEvaluator.java
index 28d496b..23eb766 100644
--- a/core/java/android/animation/RectEvaluator.java
+++ b/core/java/android/animation/RectEvaluator.java
@@ -23,12 +23,45 @@
 public class RectEvaluator implements TypeEvaluator<Rect> {
 
     /**
+     * When null, a new Rect is returned on every evaluate call. When non-null,
+     * mRect will be modified and returned on every evaluate.
+     */
+    private Rect mRect;
+
+    /**
+     * Construct a RectEvaluator that returns a new Rect on every evaluate call.
+     * To avoid creating an object for each evaluate call,
+     * {@link RectEvaluator#RectEvaluator(android.graphics.Rect)} should be used
+     * whenever possible.
+     */
+    public RectEvaluator() {
+    }
+
+    /**
+     * Constructs a RectEvaluator that modifies and returns <code>reuseRect</code>
+     * in {@link #evaluate(float, android.graphics.Rect, android.graphics.Rect)} calls.
+     * The value returned from
+     * {@link #evaluate(float, android.graphics.Rect, android.graphics.Rect)} should
+     * not be cached because it will change over time as the object is reused on each
+     * call.
+     *
+     * @param reuseRect A Rect to be modified and returned by evaluate.
+     */
+    public RectEvaluator(Rect reuseRect) {
+        mRect = reuseRect;
+    }
+
+    /**
      * This function returns the result of linearly interpolating the start and
      * end Rect values, with <code>fraction</code> representing the proportion
      * between the start and end values. The calculation is a simple parametric
      * calculation on each of the separate components in the Rect objects
      * (left, top, right, and bottom).
      *
+     * <p>If {@link #RectEvaluator(android.graphics.Rect)} was used to construct
+     * this RectEvaluator, the object returned will be the <code>reuseRect</code>
+     * passed into the constructor.</p>
+     *
      * @param fraction   The fraction from the starting to the ending values
      * @param startValue The start Rect
      * @param endValue   The end Rect
@@ -37,9 +70,15 @@
      */
     @Override
     public Rect evaluate(float fraction, Rect startValue, Rect endValue) {
-        return new Rect(startValue.left + (int)((endValue.left - startValue.left) * fraction),
-                startValue.top + (int)((endValue.top - startValue.top) * fraction),
-                startValue.right + (int)((endValue.right - startValue.right) * fraction),
-                startValue.bottom + (int)((endValue.bottom - startValue.bottom) * fraction));
+        int left = startValue.left + (int) ((endValue.left - startValue.left) * fraction);
+        int top = startValue.top + (int) ((endValue.top - startValue.top) * fraction);
+        int right = startValue.right + (int) ((endValue.right - startValue.right) * fraction);
+        int bottom = startValue.bottom + (int) ((endValue.bottom - startValue.bottom) * fraction);
+        if (mRect == null) {
+            return new Rect(left, top, right, bottom);
+        } else {
+            mRect.set(left, top, right, bottom);
+            return mRect;
+        }
     }
 }
diff --git a/core/java/android/animation/TypeConverter.java b/core/java/android/animation/TypeConverter.java
new file mode 100644
index 0000000..03b3eb5
--- /dev/null
+++ b/core/java/android/animation/TypeConverter.java
@@ -0,0 +1,68 @@
+/*
+ * 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.animation;
+
+/**
+ * Abstract base class used convert type T to another type V. This
+ * is necessary when the value types of in animation are different
+ * from the property type.
+ * @see PropertyValuesHolder#setConverter(TypeConverter)
+ */
+public abstract class TypeConverter<T, V> {
+    private Class<T> mFromClass;
+    private Class<V> mToClass;
+
+    public TypeConverter(Class<T> fromClass, Class<V> toClass) {
+        mFromClass = fromClass;
+        mToClass = toClass;
+    }
+
+    /**
+     * Returns the target converted type. Used by the animation system to determine
+     * the proper setter function to call.
+     * @return The Class to convert the input to.
+     */
+    Class<V> getTargetType() {
+        return mToClass;
+    }
+
+    /**
+     * Returns the source conversion type.
+     */
+    Class<T> getSourceType() {
+        return mFromClass;
+    }
+
+    /**
+     * Converts a value from one type to another.
+     * @param value The Object to convert.
+     * @return A value of type V, converted from <code>value</code>.
+     */
+    public abstract V convert(T value);
+
+    /**
+     * Does a conversion from the target type back to the source type. The subclass
+     * must implement this when a TypeConverter is used in animations and current
+     * values will need to be read for an animation. By default, this will return null,
+     * indicating that back-conversion is not supported.
+     * @param value The Object to convert.
+     * @return A value of type T, converted from <code>value</code>.
+     */
+    public T convertBack(V value) {
+        return null;
+    }
+}
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 86da673..7880f39 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -280,6 +280,24 @@
     }
 
     /**
+     * Constructs and returns a ValueAnimator that animates between color values. A single
+     * value implies that that value is the one being animated to. However, this is not typically
+     * useful in a ValueAnimator object because there is no way for the object to determine the
+     * starting value for the animation (unlike ObjectAnimator, which can derive that value
+     * from the target object and property being animated). Therefore, there should typically
+     * be two or more values.
+     *
+     * @param values A set of values that the animation will animate between over time.
+     * @return A ValueAnimator object that is set up to animate between the given values.
+     */
+    public static ValueAnimator ofArgb(int... values) {
+        ValueAnimator anim = new ValueAnimator();
+        anim.setIntValues(values);
+        anim.setEvaluator(ArgbEvaluator.getInstance());
+        return anim;
+    }
+
+    /**
      * Constructs and returns a ValueAnimator that animates between float values. A single
      * value implies that that value is the one being animated to. However, this is not typically
      * useful in a ValueAnimator object because there is no way for the object to determine the
diff --git a/core/java/android/annotation/IntDef.java b/core/java/android/annotation/IntDef.java
new file mode 100644
index 0000000..3cae9c5
--- /dev/null
+++ b/core/java/android/annotation/IntDef.java
@@ -0,0 +1,60 @@
+/*
+ * 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated element of integer type, represents
+ * a logical type and that its value should be one of the explicitly
+ * named constants. If the {@link #flag()} attribute is set to true,
+ * multiple constants can be combined.
+ * <p>
+ * Example:
+ * <pre>{@code
+ *  &#64;Retention(CLASS)
+ *  &#64;IntDef(&#123;NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS&#125;)
+ *  public &#64;interface NavigationMode &#123;&#125;
+ *  public static final int NAVIGATION_MODE_STANDARD = 0;
+ *  public static final int NAVIGATION_MODE_LIST = 1;
+ *  public static final int NAVIGATION_MODE_TABS = 2;
+ *  ...
+ *  public abstract void setNavigationMode(&#64;NavigationMode int mode);
+ *  &#64;NavigationMode
+ *  public abstract int getNavigationMode();
+ * }</pre>
+ * For a flag, set the flag attribute:
+ * <pre>{@code
+ *  &#64;IntDef(
+ *      flag = true
+ *      value = &#123;NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS&#125;)
+ * }</pre>
+ *
+ * @hide
+ */
+@Retention(CLASS)
+@Target({ANNOTATION_TYPE})
+public @interface IntDef {
+    /** Defines the allowed constants for this element */
+    long[] value() default {};
+
+    /** Defines whether the constants can be used as a flag, or just as an enum (the default) */
+    boolean flag() default false;
+}
diff --git a/core/java/android/annotation/NonNull.java b/core/java/android/annotation/NonNull.java
new file mode 100644
index 0000000..8e604f0
--- /dev/null
+++ b/core/java/android/annotation/NonNull.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that a parameter, field or method return value can never be null.
+ * <p>
+ * This is a marker annotation and it has no specific attributes.
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface NonNull {
+}
diff --git a/core/java/android/annotation/Nullable.java b/core/java/android/annotation/Nullable.java
new file mode 100644
index 0000000..cdba2f6
--- /dev/null
+++ b/core/java/android/annotation/Nullable.java
@@ -0,0 +1,41 @@
+/*
+ * 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that a parameter, field or method return value can be null.
+ * <p>
+ * When decorating a method call parameter, this denotes that the parameter can
+ * legitimately be null and the method will gracefully deal with it. Typically
+ * used on optional parameters.
+ * <p>
+ * When decorating a method, this denotes the method might legitimately return
+ * null.
+ * <p>
+ * This is a marker annotation and it has no specific attributes.
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface Nullable {
+}
diff --git a/core/java/android/annotation/StringDef.java b/core/java/android/annotation/StringDef.java
new file mode 100644
index 0000000..5f7f380
--- /dev/null
+++ b/core/java/android/annotation/StringDef.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated String element, represents a logical
+ * type and that its value should be one of the explicitly named constants.
+ * <p>
+ * Example:
+ * <pre>{@code
+ *  &#64;Retention(SOURCE)
+ *  &#64;StringDef(&#123;
+ *     POWER_SERVICE,
+ *     WINDOW_SERVICE,
+ *     LAYOUT_INFLATER_SERVICE
+ *  &#125;)
+ *  public &#64;interface ServiceName &#123;&#125;
+ *  public static final String POWER_SERVICE = "power";
+ *  public static final String WINDOW_SERVICE = "window";
+ *  public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
+ *  ...
+ *  public abstract Object getSystemService(&#64;ServiceName String name);
+ * }</pre>
+ *
+ * @hide
+ */
+@Retention(CLASS)
+@Target({ANNOTATION_TYPE})
+public @interface StringDef {
+    /** Defines the allowed constants for this element */
+    String[] value() default {};
+}
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index c4ddf1f..fbe8987 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -16,6 +16,9 @@
 
 package android.app;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -28,6 +31,9 @@
 import android.view.Window;
 import android.widget.SpinnerAdapter;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A window feature at the top of the activity that may display the activity title, navigation
  * modes, and other interactive items.
@@ -57,6 +63,11 @@
  * </div>
  */
 public abstract class ActionBar {
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
+    public @interface NavigationMode {}
+
     /**
      * Standard navigation mode. Consists of either a logo or icon
      * and title text with an optional subtitle. Clicking any of these elements
@@ -78,6 +89,19 @@
      */
     public static final int NAVIGATION_MODE_TABS = 2;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true,
+            value = {
+                    DISPLAY_USE_LOGO,
+                    DISPLAY_SHOW_HOME,
+                    DISPLAY_HOME_AS_UP,
+                    DISPLAY_SHOW_TITLE,
+                    DISPLAY_SHOW_CUSTOM,
+                    DISPLAY_TITLE_MULTIPLE_LINES
+            })
+    public @interface DisplayOptions {}
+
     /**
      * Use logo instead of icon if available. This flag will cause appropriate
      * navigation modes to use a wider logo in place of the standard icon.
@@ -341,7 +365,7 @@
      * @param options A combination of the bits defined by the DISPLAY_ constants
      *                defined in ActionBar.
      */
-    public abstract void setDisplayOptions(int options);
+    public abstract void setDisplayOptions(@DisplayOptions int options);
     
     /**
      * Set selected display options. Only the options specified by mask will be changed.
@@ -356,7 +380,7 @@
      *                defined in ActionBar.
      * @param mask A bit mask declaring which display options should be changed.
      */
-    public abstract void setDisplayOptions(int options, int mask);
+    public abstract void setDisplayOptions(@DisplayOptions int options, @DisplayOptions int mask);
 
     /**
      * Set whether to display the activity logo rather than the activity icon.
@@ -431,7 +455,7 @@
      * @see #setStackedBackgroundDrawable(Drawable)
      * @see #setSplitBackgroundDrawable(Drawable)
      */
-    public abstract void setBackgroundDrawable(Drawable d);
+    public abstract void setBackgroundDrawable(@Nullable Drawable d);
 
     /**
      * Set the ActionBar's stacked background. This will appear
@@ -484,6 +508,7 @@
      *
      * @return The current navigation mode.
      */
+    @NavigationMode
     public abstract int getNavigationMode();
 
     /**
@@ -494,7 +519,7 @@
      * @see #NAVIGATION_MODE_LIST
      * @see #NAVIGATION_MODE_TABS
      */
-    public abstract void setNavigationMode(int mode);
+    public abstract void setNavigationMode(@NavigationMode int mode);
 
     /**
      * @return The current set of display options. 
@@ -1024,7 +1049,7 @@
         })
         public int gravity = Gravity.NO_GRAVITY;
 
-        public LayoutParams(Context c, AttributeSet attrs) {
+        public LayoutParams(@NonNull Context c, AttributeSet attrs) {
             super(c, attrs);
 
             TypedArray a = c.obtainStyledAttributes(attrs,
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index d6db8c2..698f06a 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,11 +16,17 @@
 
 package android.app;
 
+import android.annotation.NonNull;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionManager;
 import android.util.ArrayMap;
 import android.util.SuperNotCalledException;
 import com.android.internal.app.ActionBarImpl;
 import com.android.internal.policy.PolicyManager;
 
+import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.content.ComponentCallbacks2;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -84,6 +90,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.HashMap;
 
@@ -852,6 +860,7 @@
      * @see #getWindow
      * @see android.view.Window#getCurrentFocus
      */
+    @Nullable
     public View getCurrentFocus() {
         return mWindow != null ? mWindow.getCurrentFocus() : null;
     }
@@ -882,7 +891,7 @@
      * @see #onRestoreInstanceState
      * @see #onPostCreate
      */
-    protected void onCreate(Bundle savedInstanceState) {
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
         if (mLastNonConfigurationInstances != null) {
             mAllLoaderManagers = mLastNonConfigurationInstances.loaders;
@@ -1010,7 +1019,7 @@
      *     recently supplied in {@link #onSaveInstanceState}.  <b><i>Note: Otherwise it is null.</i></b>
      * @see #onCreate
      */
-    protected void onPostCreate(Bundle savedInstanceState) {
+    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
         if (!isChild()) {
             mTitleReady = true;
             onTitleChanged(getTitle(), getTitleColor());
@@ -1347,6 +1356,7 @@
      * @see #onSaveInstanceState
      * @see #onPause
      */
+    @Nullable
     public CharSequence onCreateDescription() {
         return null;
     }
@@ -1551,6 +1561,7 @@
      * {@link Fragment#setRetainInstance(boolean)} instead; this is also
      * available on older platforms through the Android compatibility package.
      */
+    @Nullable
     @Deprecated
     public Object getLastNonConfigurationInstance() {
         return mLastNonConfigurationInstances != null
@@ -1630,6 +1641,7 @@
      * @return Returns the object previously returned by
      * {@link #onRetainNonConfigurationChildInstances()}
      */
+    @Nullable
     HashMap<String, Object> getLastNonConfigurationChildInstances() {
         return mLastNonConfigurationInstances != null
                 ? mLastNonConfigurationInstances.children : null;
@@ -1642,6 +1654,7 @@
      * set of child activities, such as ActivityGroup.  The same guarantees and restrictions apply
      * as for {@link #onRetainNonConfigurationInstance()}.  The default implementation returns null.
      */
+    @Nullable
     HashMap<String,Object> onRetainNonConfigurationChildInstances() {
         return null;
     }
@@ -1889,6 +1902,7 @@
      *
      * @return The Activity's ActionBar, or null if it does not have one.
      */
+    @Nullable
     public ActionBar getActionBar() {
         initActionBar();
         return mActionBar;
@@ -1979,13 +1993,58 @@
     }
 
     /**
+     * Retrieve the {@link TransitionManager} responsible for default transitions in this window.
+     * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * <p>This method will return non-null after content has been initialized (e.g. by using
+     * {@link #setContentView}) if {@link Window#FEATURE_CONTENT_TRANSITIONS} has been granted.</p>
+     *
+     * @return This window's content TransitionManager or null if none is set.
+     */
+    public TransitionManager getContentTransitionManager() {
+        return getWindow().getTransitionManager();
+    }
+
+    /**
+     * Set the {@link TransitionManager} to use for default transitions in this window.
+     * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * @param tm The TransitionManager to use for scene changes.
+     */
+    public void setContentTransitionManager(TransitionManager tm) {
+        getWindow().setTransitionManager(tm);
+    }
+
+    /**
+     * Retrieve the {@link Scene} representing this window's current content.
+     * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * <p>This method will return null if the current content is not represented by a Scene.</p>
+     *
+     * @return Current Scene being shown or null
+     */
+    public Scene getContentScene() {
+        return getWindow().getContentScene();
+    }
+
+    /**
      * Sets whether this activity is finished when touched outside its window's
      * bounds.
      */
     public void setFinishOnTouchOutside(boolean finish) {
         mWindow.setCloseOnTouchOutside(finish);
     }
-    
+
+    /** @hide */
+    @IntDef({
+            DEFAULT_KEYS_DISABLE,
+            DEFAULT_KEYS_DIALER,
+            DEFAULT_KEYS_SHORTCUT,
+            DEFAULT_KEYS_SEARCH_LOCAL,
+            DEFAULT_KEYS_SEARCH_GLOBAL})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface DefaultKeyMode {}
+
     /**
      * Use with {@link #setDefaultKeyMode} to turn off default handling of
      * keys.
@@ -2055,7 +2114,7 @@
      * @see #DEFAULT_KEYS_SEARCH_GLOBAL
      * @see #onKeyDown
      */
-    public final void setDefaultKeyMode(int mode) {
+    public final void setDefaultKeyMode(@DefaultKeyMode int mode) {
         mDefaultKeyMode = mode;
         
         // Some modes use a SpannableStringBuilder to track & dispatch input events
@@ -2521,6 +2580,7 @@
      * simply returns null so that all panel sub-windows will have the default
      * menu behavior.
      */
+    @Nullable
     public View onCreatePanelView(int featureId) {
         return null;
     }
@@ -3018,6 +3078,7 @@
      * {@link FragmentManager} instead; this is also
      * available on older platforms through the Android compatibility package.
      */
+    @Nullable
     @Deprecated
     protected Dialog onCreateDialog(int id, Bundle args) {
         return onCreateDialog(id);
@@ -3105,6 +3166,7 @@
      * {@link FragmentManager} instead; this is also
      * available on older platforms through the Android compatibility package.
      */
+    @Nullable
     @Deprecated
     public final boolean showDialog(int id, Bundle args) {
         if (mManagedDialogs == null) {
@@ -3226,13 +3288,13 @@
      * <p>It is typically called from onSearchRequested(), either directly from 
      * Activity.onSearchRequested() or from an overridden version in any given 
      * Activity.  If your goal is simply to activate search, it is preferred to call
-     * onSearchRequested(), which may have been overriden elsewhere in your Activity.  If your goal
+     * onSearchRequested(), which may have been overridden elsewhere in your Activity.  If your goal
      * is to inject specific data such as context data, it is preferred to <i>override</i>
      * onSearchRequested(), so that any callers to it will benefit from the override.
      * 
      * @param initialQuery Any non-null non-empty string will be inserted as 
      * pre-entered text in the search query box.
-     * @param selectInitialQuery If true, the intial query will be preselected, which means that
+     * @param selectInitialQuery If true, the initial query will be preselected, which means that
      * any further typing will replace it.  This is useful for cases where an entire pre-formed
      * query is being inserted.  If false, the selection point will be placed at the end of the
      * inserted query.  This is useful when the inserted query is text that the user entered,
@@ -3250,8 +3312,8 @@
      * @see android.app.SearchManager
      * @see #onSearchRequested
      */
-    public void startSearch(String initialQuery, boolean selectInitialQuery, 
-            Bundle appSearchData, boolean globalSearch) {
+    public void startSearch(@Nullable String initialQuery, boolean selectInitialQuery,
+            @Nullable Bundle appSearchData, boolean globalSearch) {
         ensureSearchManager();
         mSearchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(),
                         appSearchData, globalSearch); 
@@ -3267,7 +3329,7 @@
      * searches.  This data will be returned with SEARCH intent(s).  Null if
      * no extra data is required.
      */
-    public void triggerSearch(String query, Bundle appSearchData) {
+    public void triggerSearch(String query, @Nullable Bundle appSearchData) {
         ensureSearchManager();
         mSearchManager.triggerSearch(query, getComponentName(), appSearchData);
     }
@@ -3334,6 +3396,7 @@
      * Convenience for calling
      * {@link android.view.Window#getLayoutInflater}.
      */
+    @NonNull
     public LayoutInflater getLayoutInflater() {
         return getWindow().getLayoutInflater();
     }
@@ -3341,6 +3404,7 @@
     /**
      * Returns a {@link MenuInflater} with this context.
      */
+    @NonNull
     public MenuInflater getMenuInflater() {
         // Make sure that action views can get an appropriate theme.
         if (mMenuInflater == null) {
@@ -3382,7 +3446,29 @@
      * @see #startActivity 
      */
     public void startActivityForResult(Intent intent, int requestCode) {
-        startActivityForResult(intent, requestCode, null);
+        final TransitionManager tm = getWindow().getTransitionManager();
+        final Scene currScene = getWindow().getContentScene();
+        final String[] targetSceneNames = currScene != null && tm != null ?
+                tm.getTargetSceneNames(currScene) : null;
+
+        if (targetSceneNames == null || targetSceneNames.length == 0) {
+            startActivityForResult(intent, requestCode, null);
+        } else {
+            // TODO Capture the scene transition args and send along
+            final ActivityOptions opts = ActivityOptions.makeSceneTransitionAnimation(
+                    targetSceneNames, null,
+                    new ActivityOptions.OnSceneTransitionStartedListener() {
+                        @Override public void onSceneTransitionStarted(String destSceneName) {
+                            final Transition t = tm.getNamedTransition(currScene, destSceneName);
+                            // TODO Fill this in to notify the outgoing activity that it should
+                            // treat this as a sync point for the transition - the target
+                            // transition has started.
+                            Log.d(TAG, "Scene transition to scene " + destSceneName +
+                                    " transition " + t);
+                        }
+                    }, mHandler);
+            startActivityForResult(intent, requestCode, opts.toBundle());
+        }
     }
 
     /**
@@ -3419,7 +3505,7 @@
      *
      * @see #startActivity 
      */
-    public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
+    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
         if (mParent == null) {
             Instrumentation.ActivityResult ar =
                 mInstrumentation.execStartActivity(
@@ -3498,7 +3584,7 @@
      * @param extraFlags Always set to 0.
      */
     public void startIntentSenderForResult(IntentSender intent, int requestCode,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
             throws IntentSender.SendIntentException {
         startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
                 flagsValues, extraFlags, null);
@@ -3530,7 +3616,7 @@
      * override any that conflict with those given by the IntentSender.
      */
     public void startIntentSenderForResult(IntentSender intent, int requestCode,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
             Bundle options) throws IntentSender.SendIntentException {
         if (mParent == null) {
             startIntentSenderForResultInner(intent, requestCode, fillInIntent,
@@ -3618,7 +3704,7 @@
      * @see #startActivityForResult 
      */
     @Override
-    public void startActivity(Intent intent, Bundle options) {
+    public void startActivity(Intent intent, @Nullable Bundle options) {
         if (options != null) {
             startActivityForResult(intent, -1, options);
         } else {
@@ -3667,7 +3753,7 @@
      * @see #startActivityForResult
      */
     @Override
-    public void startActivities(Intent[] intents, Bundle options) {
+    public void startActivities(Intent[] intents, @Nullable Bundle options) {
         mInstrumentation.execStartActivities(this, mMainThread.getApplicationThread(),
                 mToken, this, intents, options);
     }
@@ -3686,7 +3772,7 @@
      * @param extraFlags Always set to 0.
      */
     public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
             throws IntentSender.SendIntentException {
         startIntentSender(intent, fillInIntent, flagsMask, flagsValues,
                 extraFlags, null);
@@ -3713,7 +3799,7 @@
      * override any that conflict with those given by the IntentSender.
      */
     public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
             Bundle options) throws IntentSender.SendIntentException {
         if (options != null) {
             startIntentSenderForResult(intent, -1, fillInIntent, flagsMask,
@@ -3741,7 +3827,7 @@
      * @see #startActivity
      * @see #startActivityForResult
      */
-    public boolean startActivityIfNeeded(Intent intent, int requestCode) {
+    public boolean startActivityIfNeeded(@NonNull Intent intent, int requestCode) {
         return startActivityIfNeeded(intent, requestCode, null);
     }
 
@@ -3775,7 +3861,8 @@
      * @see #startActivity
      * @see #startActivityForResult
      */
-    public boolean startActivityIfNeeded(Intent intent, int requestCode, Bundle options) {
+    public boolean startActivityIfNeeded(@NonNull Intent intent, int requestCode,
+            @Nullable Bundle options) {
         if (mParent == null) {
             int result = ActivityManager.START_RETURN_INTENT_TO_CALLER;
             try {
@@ -3824,7 +3911,7 @@
      * wasn't.  In general, if true is returned you will then want to call
      * finish() on yourself.
      */
-    public boolean startNextMatchingActivity(Intent intent) {
+    public boolean startNextMatchingActivity(@NonNull Intent intent) {
         return startNextMatchingActivity(intent, null);
     }
 
@@ -3847,7 +3934,7 @@
      * wasn't.  In general, if true is returned you will then want to call
      * finish() on yourself.
      */
-    public boolean startNextMatchingActivity(Intent intent, Bundle options) {
+    public boolean startNextMatchingActivity(@NonNull Intent intent, @Nullable Bundle options) {
         if (mParent == null) {
             try {
                 intent.migrateExtraStreamToClipData();
@@ -3877,7 +3964,7 @@
      * @see #startActivity
      * @see #startActivityForResult
      */
-    public void startActivityFromChild(Activity child, Intent intent,
+    public void startActivityFromChild(@NonNull Activity child, Intent intent,
             int requestCode) {
         startActivityFromChild(child, intent, requestCode, null);
     }
@@ -3901,8 +3988,8 @@
      * @see #startActivity 
      * @see #startActivityForResult 
      */
-    public void startActivityFromChild(Activity child, Intent intent, 
-            int requestCode, Bundle options) {
+    public void startActivityFromChild(@NonNull Activity child, Intent intent,
+            int requestCode, @Nullable Bundle options) {
         Instrumentation.ActivityResult ar =
             mInstrumentation.execStartActivity(
                 this, mMainThread.getApplicationThread(), mToken, child,
@@ -3927,7 +4014,7 @@
      * @see Fragment#startActivity
      * @see Fragment#startActivityForResult
      */
-    public void startActivityFromFragment(Fragment fragment, Intent intent, 
+    public void startActivityFromFragment(@NonNull Fragment fragment, Intent intent,
             int requestCode) {
         startActivityFromFragment(fragment, intent, requestCode, null);
     }
@@ -3952,8 +4039,8 @@
      * @see Fragment#startActivity 
      * @see Fragment#startActivityForResult 
      */
-    public void startActivityFromFragment(Fragment fragment, Intent intent, 
-            int requestCode, Bundle options) {
+    public void startActivityFromFragment(@NonNull Fragment fragment, Intent intent,
+            int requestCode, @Nullable Bundle options) {
         Instrumentation.ActivityResult ar =
             mInstrumentation.execStartActivity(
                 this, mMainThread.getApplicationThread(), mToken, fragment,
@@ -3985,7 +4072,7 @@
      */
     public void startIntentSenderFromChild(Activity child, IntentSender intent,
             int requestCode, Intent fillInIntent, int flagsMask, int flagsValues,
-            int extraFlags, Bundle options)
+            int extraFlags, @Nullable Bundle options)
             throws IntentSender.SendIntentException {
         startIntentSenderForResultInner(intent, requestCode, fillInIntent,
                 flagsMask, flagsValues, child, options);
@@ -4084,6 +4171,7 @@
      * @return The package of the activity that will receive your
      *         reply, or null if none.
      */
+    @Nullable
     public String getCallingPackage() {
         try {
             return ActivityManagerNative.getDefault().getCallingPackage(mToken);
@@ -4106,6 +4194,7 @@
      * @return The ComponentName of the activity that will receive your
      *         reply, or null if none.
      */
+    @Nullable
     public ComponentName getCallingActivity() {
         try {
             return ActivityManagerNative.getDefault().getCallingActivity(mToken);
@@ -4298,7 +4387,7 @@
      * @param requestCode Request code that had been used to start the
      *                    activity.
      */
-    public void finishActivityFromChild(Activity child, int requestCode) {
+    public void finishActivityFromChild(@NonNull Activity child, int requestCode) {
         try {
             ActivityManagerNative.getDefault()
                 .finishSubActivity(mToken, child.mEmbeddedID, requestCode);
@@ -4359,8 +4448,8 @@
      * 
      * @see PendingIntent
      */
-    public PendingIntent createPendingResult(int requestCode, Intent data,
-            int flags) {
+    public PendingIntent createPendingResult(int requestCode, @NonNull Intent data,
+            @PendingIntent.Flags int flags) {
         String packageName = getPackageName();
         try {
             data.prepareToLeaveProcess();
@@ -4387,7 +4476,7 @@
      * @param requestedOrientation An orientation constant as used in
      * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
      */
-    public void setRequestedOrientation(int requestedOrientation) {
+    public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
         if (mParent == null) {
             try {
                 ActivityManagerNative.getDefault().setRequestedOrientation(
@@ -4409,6 +4498,7 @@
      * @return Returns an orientation constant as used in
      * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
      */
+    @ActivityInfo.ScreenOrientation
     public int getRequestedOrientation() {
         if (mParent == null) {
             try {
@@ -4480,6 +4570,7 @@
      * 
      * @return The local class name.
      */
+    @NonNull
     public String getLocalClassName() {
         final String pkg = getPackageName();
         final String cls = mComponent.getClassName();
@@ -4525,9 +4616,9 @@
         
         mSearchManager = new SearchManager(this, null);
     }
-    
+
     @Override
-    public Object getSystemService(String name) {
+    public Object getSystemService(@ServiceName @NonNull String name) {
         if (getBaseContext() == null) {
             throw new IllegalStateException(
                     "System services not available to Activities before onCreate()");
@@ -4567,6 +4658,17 @@
         setTitle(getText(titleId));
     }
 
+    /**
+     * Change the color of the title associated with this activity.
+     * <p>
+     * This method is deprecated starting in API Level 11 and replaced by action
+     * bar styles. For information on styling the Action Bar, read the <a
+     * href="{@docRoot} guide/topics/ui/actionbar.html">Action Bar</a> developer
+     * guide.
+     *
+     * @deprecated Use action bar styles instead.
+     */
+    @Deprecated
     public void setTitleColor(int textColor) {
         mTitleColor = textColor;
         onTitleChanged(mTitle, textColor);
@@ -4689,7 +4791,7 @@
 
     /**
      * Gets the suggested audio stream whose volume should be changed by the
-     * harwdare volume controls.
+     * hardware volume controls.
      * 
      * @return The suggested audio stream type whose volume should be changed by
      *         the hardware volume controls.
@@ -4725,6 +4827,7 @@
      * @see android.view.LayoutInflater#createView
      * @see android.view.Window#getLayoutInflater
      */
+    @Nullable
     public View onCreateView(String name, Context context, AttributeSet attrs) {
         return null;
     }
@@ -4983,6 +5086,7 @@
      *
      * @see ActionMode
      */
+    @Nullable
     public ActionMode startActionMode(ActionMode.Callback callback) {
         return mWindow.getDecorView().startActionMode(callback);
     }
@@ -4998,6 +5102,7 @@
      * @return The new action mode, or <code>null</code> if the activity does not want to
      *         provide special handling for this action mode. (It will be handled by the system.)
      */
+    @Nullable
     @Override
     public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
         initActionBar();
@@ -5141,6 +5246,7 @@
      * @return a new Intent targeting the defined parent of this activity or null if
      *         there is no valid parent.
      */
+    @Nullable
     public Intent getParentActivityIntent() {
         final String parentName = mActivityInfo.parentActivityName;
         if (TextUtils.isEmpty(parentName)) {
@@ -5183,6 +5289,16 @@
             CharSequence title, Activity parent, String id,
             NonConfigurationInstances lastNonConfigurationInstances,
             Configuration config) {
+        attach(context, aThread, instr, token, ident, application, intent, info, title, parent, id,
+                lastNonConfigurationInstances, config, null);
+    }
+
+    final void attach(Context context, ActivityThread aThread,
+            Instrumentation instr, IBinder token, int ident,
+            Application application, Intent intent, ActivityInfo info,
+            CharSequence title, Activity parent, String id,
+            NonConfigurationInstances lastNonConfigurationInstances,
+            Configuration config, Bundle options) {
         attachBaseContext(context);
 
         mFragments.attachActivity(this, mContainer, null);
@@ -5219,6 +5335,7 @@
             mWindow.setContainer(mParent.getWindow());
         }
         mWindowManager = mWindow.getWindowManager();
+        mWindow.setTransitionOptions(options);
         mCurrentConfig = config;
     }
 
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index c877cd3..7ca3459 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1289,15 +1289,106 @@
     }
 
     /**
+     * Information you can retrieve about the WindowManager StackBox hierarchy.
+     * @hide
+     */
+    public static class StackBoxInfo implements Parcelable {
+        public int stackBoxId;
+        public float weight;
+        public boolean vertical;
+        public Rect bounds;
+        public StackBoxInfo[] children;
+        public int stackId;
+        public StackInfo stack;
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(stackBoxId);
+            dest.writeFloat(weight);
+            dest.writeInt(vertical ? 1 : 0);
+            bounds.writeToParcel(dest, flags);
+            dest.writeInt(stackId);
+            if (children != null) {
+                children[0].writeToParcel(dest, flags);
+                children[1].writeToParcel(dest, flags);
+            } else {
+                stack.writeToParcel(dest, flags);
+            }
+        }
+
+        public void readFromParcel(Parcel source) {
+            stackBoxId = source.readInt();
+            weight = source.readFloat();
+            vertical = source.readInt() == 1;
+            bounds = Rect.CREATOR.createFromParcel(source);
+            stackId = source.readInt();
+            if (stackId == -1) {
+                children = new StackBoxInfo[2];
+                children[0] = StackBoxInfo.CREATOR.createFromParcel(source);
+                children[1] = StackBoxInfo.CREATOR.createFromParcel(source);
+            } else {
+                stack = StackInfo.CREATOR.createFromParcel(source);
+            }
+        }
+
+        public static final Creator<StackBoxInfo> CREATOR =
+                new Creator<ActivityManager.StackBoxInfo>() {
+
+            @Override
+            public StackBoxInfo createFromParcel(Parcel source) {
+                return new StackBoxInfo(source);
+            }
+
+            @Override
+            public StackBoxInfo[] newArray(int size) {
+                return new StackBoxInfo[size];
+            }
+        };
+
+        public StackBoxInfo() {
+        }
+
+        public StackBoxInfo(Parcel source) {
+            readFromParcel(source);
+        }
+
+        public String toString(String prefix) {
+            StringBuilder sb = new StringBuilder(256);
+            sb.append(prefix); sb.append("Box id=" + stackBoxId); sb.append(" weight=" + weight);
+            sb.append(" vertical=" + vertical); sb.append(" bounds=" + bounds.toShortString());
+            sb.append("\n");
+            if (children != null) {
+                sb.append(prefix); sb.append("First child=\n");
+                sb.append(children[0].toString(prefix + "  "));
+                sb.append(prefix); sb.append("Second child=\n");
+                sb.append(children[1].toString(prefix + "  "));
+            } else {
+                sb.append(prefix); sb.append("Stack=\n");
+                sb.append(stack.toString(prefix + "  "));
+            }
+            return sb.toString();
+        }
+
+        @Override
+        public String toString() {
+            return toString("");
+        }
+    }
+
+    /**
      * Information you can retrieve about an ActivityStack in the system.
      * @hide
      */
     public static class StackInfo implements Parcelable {
         public int stackId;
-        public Rect bounds = new Rect();
+        public Rect bounds;
         public int[] taskIds;
         public String[] taskNames;
-        public int displayId;
 
         @Override
         public int describeContents() {
@@ -1313,7 +1404,6 @@
             dest.writeInt(bounds.bottom);
             dest.writeIntArray(taskIds);
             dest.writeStringArray(taskNames);
-            dest.writeInt(displayId);
         }
 
         public void readFromParcel(Parcel source) {
@@ -1322,7 +1412,6 @@
                     source.readInt(), source.readInt(), source.readInt(), source.readInt());
             taskIds = source.createIntArray();
             taskNames = source.createStringArray();
-            displayId = source.readInt();
         }
 
         public static final Creator<StackInfo> CREATOR = new Creator<StackInfo>() {
@@ -1346,9 +1435,7 @@
         public String toString(String prefix) {
             StringBuilder sb = new StringBuilder(256);
             sb.append(prefix); sb.append("Stack id="); sb.append(stackId);
-                    sb.append(" bounds="); sb.append(bounds.toShortString());
-                    sb.append(" displayId="); sb.append(displayId);
-                    sb.append("\n");
+                    sb.append(" bounds="); sb.append(bounds.toShortString()); sb.append("\n");
             prefix = prefix + "  ";
             for (int i = 0; i < taskIds.length; ++i) {
                 sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]);
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index f0c4c93..74266cc 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -16,7 +16,7 @@
 
 package android.app;
 
-import android.app.ActivityManager.StackInfo;
+import android.app.ActivityManager.StackBoxInfo;
 import android.content.ComponentName;
 import android.content.IIntentReceiver;
 import android.content.IIntentSender;
@@ -31,7 +31,6 @@
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
-import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -615,7 +614,10 @@
         case CREATE_STACK_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int taskId = data.readInt();
-            int res = createStack(taskId);
+            int relativeStackId = data.readInt();
+            int position = data.readInt();
+            float weight = data.readFloat();
+            int res = createStack(taskId, relativeStackId, position, weight);
             reply.writeNoException();
             reply.writeInt(res);
             return true;
@@ -633,26 +635,25 @@
 
         case RESIZE_STACK_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
-            int stackId = data.readInt();
+            int stackBoxId = data.readInt();
             float weight = data.readFloat();
-            Rect r = Rect.CREATOR.createFromParcel(data);
-            resizeStack(stackId, r);
+            resizeStackBox(stackBoxId, weight);
             reply.writeNoException();
             return true;
         }
 
-        case GET_ALL_STACK_INFOS_TRANSACTION: {
+        case GET_STACK_BOXES_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
-            List<StackInfo> list = getAllStackInfos();
+            List<StackBoxInfo> list = getStackBoxes();
             reply.writeNoException();
             reply.writeTypedList(list);
             return true;
         }
 
-        case GET_STACK_INFO_TRANSACTION: {
+        case GET_STACK_BOX_INFO_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
-            int stackId = data.readInt();
-            StackInfo info = getStackInfo(stackId);
+            int stackBoxId = data.readInt();
+            StackBoxInfo info = getStackBoxInfo(stackBoxId);
             reply.writeNoException();
             if (info != null) {
                 reply.writeInt(1);
@@ -2714,12 +2715,16 @@
         reply.recycle();
     }
     @Override
-    public int createStack(int taskId) throws RemoteException
+    public int createStack(int taskId, int relativeStackBoxId, int position, float weight)
+            throws RemoteException
     {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(taskId);
+        data.writeInt(relativeStackBoxId);
+        data.writeInt(position);
+        data.writeFloat(weight);
         mRemote.transact(CREATE_STACK_TRANSACTION, data, reply, 0);
         reply.readException();
         int res = reply.readInt();
@@ -2742,44 +2747,44 @@
         reply.recycle();
     }
     @Override
-    public void resizeStack(int stackBoxId, Rect r) throws RemoteException
+    public void resizeStackBox(int stackBoxId, float weight) throws RemoteException
     {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(stackBoxId);
-        r.writeToParcel(data, 0);
+        data.writeFloat(weight);
         mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
         reply.readException();
         data.recycle();
         reply.recycle();
     }
     @Override
-    public List<StackInfo> getAllStackInfos() throws RemoteException
+    public List<StackBoxInfo> getStackBoxes() throws RemoteException
     {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_ALL_STACK_INFOS_TRANSACTION, data, reply, 0);
+        mRemote.transact(GET_STACK_BOXES_TRANSACTION, data, reply, 0);
         reply.readException();
-        ArrayList<StackInfo> list = reply.createTypedArrayList(StackInfo.CREATOR);
+        ArrayList<StackBoxInfo> list = reply.createTypedArrayList(StackBoxInfo.CREATOR);
         data.recycle();
         reply.recycle();
         return list;
     }
     @Override
-    public StackInfo getStackInfo(int stackId) throws RemoteException
+    public StackBoxInfo getStackBoxInfo(int stackBoxId) throws RemoteException
     {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        mRemote.transact(GET_STACK_INFO_TRANSACTION, data, reply, 0);
+        data.writeInt(stackBoxId);
+        mRemote.transact(GET_STACK_BOX_INFO_TRANSACTION, data, reply, 0);
         reply.readException();
         int res = reply.readInt();
-        StackInfo info = null;
+        StackBoxInfo info = null;
         if (res != 0) {
-            info = StackInfo.CREATOR.createFromParcel(reply);
+            info = StackBoxInfo.CREATOR.createFromParcel(reply);
         }
         data.recycle();
         reply.recycle();
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 87b1e24..582ce3c 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -22,6 +22,8 @@
 import android.os.Handler;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
 import android.view.View;
 
 /**
@@ -30,6 +32,8 @@
  * Context.startActivity(Intent, Bundle)} and related methods.
  */
 public class ActivityOptions {
+    private static final String TAG = "ActivityOptions";
+
     /**
      * The package name that created the options.
      * @hide
@@ -90,6 +94,35 @@
      */
     public static final String KEY_ANIM_START_LISTENER = "android:animStartListener";
 
+    /**
+     * A string array of names for the destination scene. This defines an API in the same
+     * way that intent action or extra names do and should follow a similar convention:
+     * "com.example.scene.FOO"
+     *
+     * @hide
+     */
+    public static final String KEY_DEST_SCENE_NAMES = "android:destSceneNames";
+
+    /**
+     * A string indicating the destination scene name that was chosen by the target.
+     * Used by {@link OnSceneTransitionStartedListener}.
+     * @hide
+     */
+    public static final String KEY_DEST_SCENE_NAME_CHOSEN = "android:destSceneNameChosen";
+
+    /**
+     * Callback for when scene transition is started.
+     * @hide
+     */
+    public static final String KEY_SCENE_TRANSITION_START_LISTENER =
+            "android:sceneTransitionStartListener";
+
+    /**
+     * Arguments for the scene transition about to begin.
+     * @hide
+     */
+    public static final String KEY_SCENE_TRANSITION_ARGS = "android:sceneTransitionArgs";
+
     /** @hide */
     public static final int ANIM_NONE = 0;
     /** @hide */
@@ -100,6 +133,8 @@
     public static final int ANIM_THUMBNAIL_SCALE_UP = 3;
     /** @hide */
     public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4;
+    /** @hide */
+    public static final int ANIM_SCENE_TRANSITION = 5;
 
     private String mPackageName;
     private int mAnimationType = ANIM_NONE;
@@ -110,7 +145,10 @@
     private int mStartY;
     private int mStartWidth;
     private int mStartHeight;
+    private String[] mDestSceneNames;
+    private Bundle mTransitionArgs;
     private IRemoteCallback mAnimationStartedListener;
+    private IRemoteCallback mSceneTransitionStartedListener;
 
     /**
      * Create an ActivityOptions specifying a custom animation to run when
@@ -156,11 +194,12 @@
         opts.mAnimationType = ANIM_CUSTOM;
         opts.mCustomEnterResId = enterResId;
         opts.mCustomExitResId = exitResId;
-        opts.setListener(handler, listener);
+        opts.setOnAnimationStartedListener(handler, listener);
         return opts;
     }
 
-    private void setListener(Handler handler, OnAnimationStartedListener listener) {
+    private void setOnAnimationStartedListener(Handler handler,
+            OnAnimationStartedListener listener) {
         if (listener != null) {
             final Handler h = handler;
             final OnAnimationStartedListener finalListener = listener;
@@ -176,6 +215,24 @@
         }
     }
 
+    private void setOnSceneTransitionStartedListener(Handler handler,
+            OnSceneTransitionStartedListener listener) {
+        if (listener != null) {
+            final Handler h = handler;
+            final OnSceneTransitionStartedListener l = listener;
+            mSceneTransitionStartedListener = new IRemoteCallback.Stub() {
+                @Override public void sendResult(final Bundle data) throws RemoteException {
+                    h.post(new Runnable() {
+                        public void run() {
+                            l.onSceneTransitionStarted(data != null ?
+                                    data.getString(KEY_DEST_SCENE_NAME_CHOSEN) : null);
+                        }
+                    });
+                }
+            };
+        }
+    }
+
     /**
      * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation}
      * to find out when the given animation has started running.
@@ -186,6 +243,15 @@
     }
 
     /**
+     * Callback for use with {@link ActivityOptions#makeSceneTransitionAnimation}
+     * to find out when a transition is about to begin.
+     * @hide
+     */
+    public interface OnSceneTransitionStartedListener {
+        void onSceneTransitionStarted(String destSceneName);
+    }
+
+    /**
      * Create an ActivityOptions specifying an animation where the new
      * activity is scaled from a small originating area of the screen to
      * its final full representation.
@@ -298,7 +364,23 @@
         source.getLocationOnScreen(pts);
         opts.mStartX = pts[0] + startX;
         opts.mStartY = pts[1] + startY;
-        opts.setListener(source.getHandler(), listener);
+        opts.setOnAnimationStartedListener(source.getHandler(), listener);
+        return opts;
+    }
+
+    /**
+     * Create an ActivityOptions specifying an animation where an activity window is asked
+     * to perform animations within the window content.
+     *
+     * @hide
+     */
+    public static ActivityOptions makeSceneTransitionAnimation(String[] destSceneNames,
+            Bundle args, OnSceneTransitionStartedListener listener, Handler handler) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mAnimationType = ANIM_SCENE_TRANSITION;
+        opts.mDestSceneNames = destSceneNames;
+        opts.mTransitionArgs = args;
+        opts.setOnSceneTransitionStartedListener(handler, listener);
         return opts;
     }
 
@@ -309,23 +391,36 @@
     public ActivityOptions(Bundle opts) {
         mPackageName = opts.getString(KEY_PACKAGE_NAME);
         mAnimationType = opts.getInt(KEY_ANIM_TYPE);
-        if (mAnimationType == ANIM_CUSTOM) {
-            mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
-            mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
-            mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
-                    opts.getIBinder(KEY_ANIM_START_LISTENER));
-        } else if (mAnimationType == ANIM_SCALE_UP) {
-            mStartX = opts.getInt(KEY_ANIM_START_X, 0);
-            mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
-            mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0);
-            mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0);
-        } else if (mAnimationType == ANIM_THUMBNAIL_SCALE_UP ||
-                mAnimationType == ANIM_THUMBNAIL_SCALE_DOWN) {
-            mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL);
-            mStartX = opts.getInt(KEY_ANIM_START_X, 0);
-            mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
-            mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
-                    opts.getIBinder(KEY_ANIM_START_LISTENER));
+        switch (mAnimationType) {
+            case ANIM_CUSTOM:
+                mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
+                mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
+                mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
+                        opts.getBinder(KEY_ANIM_START_LISTENER));
+                break;
+
+            case ANIM_SCALE_UP:
+                mStartX = opts.getInt(KEY_ANIM_START_X, 0);
+                mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
+                mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0);
+                mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0);
+                break;
+
+            case ANIM_THUMBNAIL_SCALE_UP:
+            case ANIM_THUMBNAIL_SCALE_DOWN:
+                mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL);
+                mStartX = opts.getInt(KEY_ANIM_START_X, 0);
+                mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
+                mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
+                        opts.getBinder(KEY_ANIM_START_LISTENER));
+                break;
+
+            case ANIM_SCENE_TRANSITION:
+                mDestSceneNames = opts.getStringArray(KEY_DEST_SCENE_NAMES);
+                mTransitionArgs = opts.getBundle(KEY_SCENE_TRANSITION_ARGS);
+                mSceneTransitionStartedListener = IRemoteCallback.Stub.asInterface(
+                        opts.getBinder(KEY_SCENE_TRANSITION_START_LISTENER));
+                break;
         }
     }
 
@@ -375,11 +470,37 @@
     }
 
     /** @hide */
+    public String[] getDestSceneNames() {
+        return mDestSceneNames;
+    }
+
+    /** @hide */
+    public Bundle getSceneTransitionArgs() {
+        return mTransitionArgs;
+    }
+
+    /** @hide */
     public IRemoteCallback getOnAnimationStartListener() {
         return mAnimationStartedListener;
     }
 
     /** @hide */
+    public void dispatchSceneTransitionStarted(String destScene) {
+        if (mSceneTransitionStartedListener != null) {
+            Bundle data = null;
+            if (!TextUtils.isEmpty(destScene)) {
+                data = new Bundle();
+                data.putString(KEY_DEST_SCENE_NAME_CHOSEN, destScene);
+            }
+            try {
+                mSceneTransitionStartedListener.sendResult(data);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Caught exception dispatching scene transition start", e);
+            }
+        }
+    }
+
+    /** @hide */
     public void abort() {
         if (mAnimationStartedListener != null) {
             try {
@@ -387,6 +508,12 @@
             } catch (RemoteException e) {
             }
         }
+        if (mSceneTransitionStartedListener != null) {
+            try {
+                mSceneTransitionStartedListener.sendResult(null);
+            } catch (RemoteException e) {
+            }
+        }
     }
 
     /** @hide */
@@ -411,13 +538,16 @@
                 mCustomEnterResId = otherOptions.mCustomEnterResId;
                 mCustomExitResId = otherOptions.mCustomExitResId;
                 mThumbnail = null;
-                if (otherOptions.mAnimationStartedListener != null) {
+                if (mAnimationStartedListener != null) {
                     try {
-                        otherOptions.mAnimationStartedListener.sendResult(null);
+                        mAnimationStartedListener.sendResult(null);
                     } catch (RemoteException e) {
                     }
                 }
                 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
+                mSceneTransitionStartedListener = null;
+                mTransitionArgs = null;
+                mDestSceneNames = null;
                 break;
             case ANIM_SCALE_UP:
                 mAnimationType = otherOptions.mAnimationType;
@@ -425,13 +555,16 @@
                 mStartY = otherOptions.mStartY;
                 mStartWidth = otherOptions.mStartWidth;
                 mStartHeight = otherOptions.mStartHeight;
-                if (otherOptions.mAnimationStartedListener != null) {
+                if (mAnimationStartedListener != null) {
                     try {
-                        otherOptions.mAnimationStartedListener.sendResult(null);
+                        mAnimationStartedListener.sendResult(null);
                     } catch (RemoteException e) {
                     }
                 }
                 mAnimationStartedListener = null;
+                mSceneTransitionStartedListener = null;
+                mTransitionArgs = null;
+                mDestSceneNames = null;
                 break;
             case ANIM_THUMBNAIL_SCALE_UP:
             case ANIM_THUMBNAIL_SCALE_DOWN:
@@ -439,13 +572,30 @@
                 mThumbnail = otherOptions.mThumbnail;
                 mStartX = otherOptions.mStartX;
                 mStartY = otherOptions.mStartY;
-                if (otherOptions.mAnimationStartedListener != null) {
+                if (mAnimationStartedListener != null) {
                     try {
-                        otherOptions.mAnimationStartedListener.sendResult(null);
+                        mAnimationStartedListener.sendResult(null);
                     } catch (RemoteException e) {
                     }
                 }
                 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
+                mSceneTransitionStartedListener = null;
+                mTransitionArgs = null;
+                mDestSceneNames = null;
+                break;
+            case ANIM_SCENE_TRANSITION:
+                mAnimationType = otherOptions.mAnimationType;
+                if (mSceneTransitionStartedListener != null) {
+                    try {
+                        mSceneTransitionStartedListener.sendResult(null);
+                    } catch (RemoteException e) {
+                    }
+                }
+                mSceneTransitionStartedListener = otherOptions.mSceneTransitionStartedListener;
+                mDestSceneNames = otherOptions.mDestSceneNames;
+                mTransitionArgs = otherOptions.mTransitionArgs;
+                mThumbnail = null;
+                mAnimationStartedListener = null;
                 break;
         }
     }
@@ -468,7 +618,7 @@
                 b.putInt(KEY_ANIM_TYPE, mAnimationType);
                 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
                 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
-                b.putIBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
+                b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
                         != null ? mAnimationStartedListener.asBinder() : null);
                 break;
             case ANIM_SCALE_UP:
@@ -484,10 +634,31 @@
                 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
                 b.putInt(KEY_ANIM_START_X, mStartX);
                 b.putInt(KEY_ANIM_START_Y, mStartY);
-                b.putIBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
+                b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
                         != null ? mAnimationStartedListener.asBinder() : null);
                 break;
+            case ANIM_SCENE_TRANSITION:
+                b.putInt(KEY_ANIM_TYPE, mAnimationType);
+                b.putStringArray(KEY_DEST_SCENE_NAMES, mDestSceneNames);
+                b.putBundle(KEY_SCENE_TRANSITION_ARGS, mTransitionArgs);
+                b.putBinder(KEY_SCENE_TRANSITION_START_LISTENER, mSceneTransitionStartedListener
+                        != null ? mSceneTransitionStartedListener.asBinder() : null);
+                break;
         }
         return b;
     }
+
+    /**
+     * Return the filtered options only meant to be seen by the target activity itself
+     * @hide
+     */
+    public ActivityOptions forTargetActivity() {
+        if (mAnimationType == ANIM_SCENE_TRANSITION) {
+            final ActivityOptions result = new ActivityOptions();
+            result.update(this);
+            return result;
+        }
+
+        return null;
+    }
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 5e3dc02..e667bad 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -56,6 +56,7 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.IRemoteCallback;
 import android.os.Looper;
 import android.os.Message;
 import android.os.MessageQueue;
@@ -68,12 +69,15 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.transition.Scene;
+import android.transition.TransitionManager;
 import android.util.AndroidRuntimeException;
 import android.util.ArrayMap;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.LogPrinter;
+import android.util.Pair;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.util.SuperNotCalledException;
@@ -284,6 +288,7 @@
         boolean isForward;
         int pendingConfigChanges;
         boolean onlyLocalRequest;
+        Bundle activityOptions;
 
         View mPendingRemoveWindow;
         WindowManager mPendingRemoveWindowManager;
@@ -576,9 +581,10 @@
         }
 
         public final void scheduleResumeActivity(IBinder token, int processState,
-                boolean isForward) {
+                boolean isForward, Bundle resumeArgs) {
             updateProcessState(processState, false);
-            sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
+            sendMessage(H.RESUME_ACTIVITY, new Pair<IBinder, Bundle>(token, resumeArgs),
+                    isForward ? 1 : 0);
         }
 
         public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
@@ -594,7 +600,8 @@
                 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
                 int procState, Bundle state, List<ResultInfo> pendingResults,
                 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
-                String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
+                String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler,
+                Bundle resumeArgs) {
 
             updateProcessState(procState, false);
 
@@ -616,6 +623,7 @@
             r.profileFile = profileName;
             r.profileFd = profileFd;
             r.autoStopProfiler = autoStopProfiler;
+            r.activityOptions = resumeArgs;
 
             updatePendingConfiguration(curConfig);
 
@@ -1189,7 +1197,7 @@
             switch (msg.what) {
                 case LAUNCH_ACTIVITY: {
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
-                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
+                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
 
                     r.packageInfo = getPackageInfoNoCheck(
                             r.activityInfo.applicationInfo, r.compatInfo);
@@ -1235,7 +1243,8 @@
                     break;
                 case RESUME_ACTIVITY:
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
-                    handleResumeActivity((IBinder)msg.obj, true,
+                    final Pair<IBinder, Bundle> resumeArgs = (Pair<IBinder, Bundle>) msg.obj;
+                    handleResumeActivity(resumeArgs.first, resumeArgs.second, true,
                             msg.arg1 != 0, true);
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
@@ -2032,7 +2041,7 @@
                     + ", comp=" + name
                     + ", token=" + token);
         }
-        return performLaunchActivity(r, null);
+        return performLaunchActivity(r, null, null);
     }
 
     public final Activity getActivity(IBinder token) {
@@ -2085,7 +2094,8 @@
         sendMessage(H.CLEAN_UP_CONTEXT, cci);
     }
 
-    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
+    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent,
+            Bundle options) {
         // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
 
         ActivityInfo aInfo = r.activityInfo;
@@ -2143,7 +2153,7 @@
                         + r.activityInfo.name + " with config " + config);
                 activity.attach(appContext, this, getInstrumentation(), r.token,
                         r.ident, app, r.intent, r.activityInfo, title, r.parent,
-                        r.embeddedID, r.lastNonConfigurationInstances, config);
+                        r.embeddedID, r.lastNonConfigurationInstances, config, options);
 
                 if (customIntent != null) {
                     activity.mIntent = customIntent;
@@ -2242,12 +2252,13 @@
 
         if (localLOGV) Slog.v(
             TAG, "Handling launch of " + r);
-        Activity a = performLaunchActivity(r, customIntent);
+
+        Activity a = performLaunchActivity(r, customIntent, r.activityOptions);
 
         if (a != null) {
             r.createdConfig = new Configuration(mConfiguration);
             Bundle oldState = r.state;
-            handleResumeActivity(r.token, false, r.isForward,
+            handleResumeActivity(r.token, r.activityOptions, false, r.isForward,
                     !r.activity.mFinished && !r.startsNotResumed);
 
             if (!r.activity.mFinished && r.startsNotResumed) {
@@ -2808,12 +2819,13 @@
         r.mPendingRemoveWindowManager = null;
     }
 
-    final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
-            boolean reallyResume) {
+    final void handleResumeActivity(IBinder token, Bundle resumeArgs,
+            boolean clearHide, boolean isForward, boolean reallyResume) {
         // If we are getting ready to gc after going to the background, well
         // we are back active so skip it.
         unscheduleGcIdler();
 
+        // TODO Push resumeArgs into the activity for consideration
         ActivityClientRecord r = performResumeActivity(token, clearHide);
 
         if (r != null) {
@@ -3734,6 +3746,7 @@
             }
         }
         r.startsNotResumed = tmp.startsNotResumed;
+        r.activityOptions = null;
 
         handleLaunchActivity(r, currentIntent);
     }
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index 10d5e25..2fd3cc8 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -27,7 +27,6 @@
 import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
 import android.view.KeyEvent;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.AdapterView;
@@ -853,6 +852,21 @@
         }
         
         /**
+         * Set a custom view resource to be the contents of the Dialog. The
+         * resource will be inflated, adding all top-level views to the screen.
+         *
+         * @param layoutResId Resource ID to be inflated.
+         * @return This Builder object to allow for chaining of calls to set
+         *         methods
+         */
+        public Builder setView(int layoutResId) {
+            P.mView = null;
+            P.mViewLayoutResId = layoutResId;
+            P.mViewSpacingSpecified = false;
+            return this;
+        }
+
+        /**
          * Set a custom view to be the contents of the Dialog. If the supplied view is an instance
          * of a {@link ListView} the light background will be used.
          *
@@ -862,6 +876,7 @@
          */
         public Builder setView(View view) {
             P.mView = view;
+            P.mViewLayoutResId = 0;
             P.mViewSpacingSpecified = false;
             return this;
         }
@@ -891,6 +906,7 @@
         public Builder setView(View view, int viewSpacingLeft, int viewSpacingTop,
                 int viewSpacingRight, int viewSpacingBottom) {
             P.mView = view;
+            P.mViewLayoutResId = 0;
             P.mViewSpacingSpecified = true;
             P.mViewSpacingLeft = viewSpacingLeft;
             P.mViewSpacingTop = viewSpacingTop;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 183927b..e71d47d 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -36,7 +36,7 @@
  * API for interacting with "application operation" tracking.
  *
  * <p>This API is not generally intended for third party application developers; most
- * features are only available to system applicatins.  Obtain an instance of it through
+ * features are only available to system applications.  Obtain an instance of it through
  * {@link Context#getSystemService(String) Context.getSystemService} with
  * {@link Context#APP_OPS_SERVICE Context.APP_OPS_SERVICE}.</p>
  */
@@ -369,8 +369,8 @@
             android.Manifest.permission.WRITE_CALL_LOG,
             android.Manifest.permission.READ_CALENDAR,
             android.Manifest.permission.WRITE_CALENDAR,
-            null, // no permission required for notifications
             android.Manifest.permission.ACCESS_WIFI_STATE,
+            null, // no permission required for notifications
             null, // neighboring cells shares the coarse location perm
             android.Manifest.permission.CALL_PHONE,
             android.Manifest.permission.READ_SMS,
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index c117486..8b132e0 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -24,7 +24,6 @@
 import android.content.pm.ResolveInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.util.Printer;
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index b505d4f..b910ba5 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -57,8 +57,6 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 
 /*package*/
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 347d43f..c8f1280 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -113,7 +113,8 @@
             IBinder b = data.readStrongBinder();
             int procState = data.readInt();
             boolean isForward = data.readInt() != 0;
-            scheduleResumeActivity(b, procState, isForward);
+            Bundle resumeArgs = data.readBundle();
+            scheduleResumeActivity(b, procState, isForward, resumeArgs);
             return true;
         }
         
@@ -145,8 +146,10 @@
             ParcelFileDescriptor profileFd = data.readInt() != 0
                     ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
             boolean autoStopProfiler = data.readInt() != 0;
+            Bundle resumeArgs = data.readBundle();
             scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, procState, state,
-                    ri, pi, notResumed, isForward, profileName, profileFd, autoStopProfiler);
+                    ri, pi, notResumed, isForward, profileName, profileFd, autoStopProfiler,
+                    resumeArgs);
             return true;
         }
         
@@ -696,13 +699,15 @@
         data.recycle();
     }
 
-    public final void scheduleResumeActivity(IBinder token, int procState, boolean isForward)
+    public final void scheduleResumeActivity(IBinder token, int procState, boolean isForward,
+            Bundle resumeArgs)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
         data.writeInt(procState);
         data.writeInt(isForward ? 1 : 0);
+        data.writeBundle(resumeArgs);
         mRemote.transact(SCHEDULE_RESUME_ACTIVITY_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
@@ -722,9 +727,10 @@
     public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
             ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
             int procState, Bundle state, List<ResultInfo> pendingResults,
-    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
-    		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
-    		throws RemoteException {
+            List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+            String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler,
+            Bundle resumeArgs)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         intent.writeToParcel(data, 0);
@@ -747,6 +753,7 @@
             data.writeInt(0);
         }
         data.writeInt(autoStopProfiler ? 1 : 0);
+        data.writeBundle(resumeArgs);
         mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index cda2c5f..a041a46 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -17,7 +17,6 @@
 package android.app;
 
 import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
 import com.android.internal.app.ActionBarImpl;
 import com.android.internal.policy.PolicyManager;
 
@@ -457,13 +456,20 @@
     }
 
     /**
-     * Finds a view that was identified by the id attribute from the XML that
-     * was processed in {@link #onStart}.
+     * Finds a child view with the given identifier.
+     * <p>
+     * Prior to API 20, this function could only be used after the first call
+     * to {@link #show()}. In later versions, this function may be used at any
+     * time; however, the first call to this function "locks in" certain dialog
+     * characteristics.
      *
      * @param id the identifier of the view to find
-     * @return The view if found or null otherwise.
+     * @return The view with the given id or null.
      */
     public View findViewById(int id) {
+        if (!mCreated) {
+            dispatchOnCreate(null);
+        }
         return mWindow.findViewById(id);
     }
 
@@ -480,7 +486,7 @@
     /**
      * Set the screen content to an explicit view.  This view is placed
      * directly into the screen's view hierarchy.  It can itself be a complex
-     * view hierarhcy.
+     * view hierarchy.
      * 
      * @param view The desired content to display.
      */
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index b741cc5..2ed8b0f 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -1011,15 +1011,15 @@
     }
 
     /**
-     * Returns {@link Uri} for the given downloaded file id, if the file is
-     * downloaded successfully. otherwise, null is returned.
+     * Returns the {@link Uri} of the given downloaded file id, if the file is
+     * downloaded successfully. Otherwise, null is returned.
      *<p>
      * If the specified downloaded file is in external storage (for example, /sdcard dir),
      * then it is assumed to be safe for anyone to read and the returned {@link Uri} corresponds
      * to the filepath on sdcard.
      *
      * @param id the id of the downloaded file.
-     * @return the {@link Uri} for the given downloaded file id, if download was successful. null
+     * @return the {@link Uri} of the given downloaded file id, if download was successful. null
      * otherwise.
      */
     public Uri getUriForDownloadedFile(long id) {
@@ -1064,15 +1064,11 @@
     }
 
     /**
-     * Returns {@link Uri} for the given downloaded file id, if the file is
-     * downloaded successfully. otherwise, null is returned.
-     *<p>
-     * If the specified downloaded file is in external storage (for example, /sdcard dir),
-     * then it is assumed to be safe for anyone to read and the returned {@link Uri} corresponds
-     * to the filepath on sdcard.
+     * Returns the media type of the given downloaded file id, if the file was
+     * downloaded successfully. Otherwise, null is returned.
      *
      * @param id the id of the downloaded file.
-     * @return the {@link Uri} for the given downloaded file id, if download was successful. null
+     * @return the media type of the given downloaded file id, if download was successful. null
      * otherwise.
      */
     public String getMimeTypeForDownloadedFile(long id) {
diff --git a/core/java/android/app/ExpandableListActivity.java b/core/java/android/app/ExpandableListActivity.java
index 9651078..e08f25a 100644
--- a/core/java/android/app/ExpandableListActivity.java
+++ b/core/java/android/app/ExpandableListActivity.java
@@ -27,7 +27,6 @@
 import android.widget.ExpandableListView;
 import android.widget.SimpleCursorTreeAdapter;
 import android.widget.SimpleExpandableListAdapter;
-import android.widget.AdapterView.AdapterContextMenuInfo;
 
 import java.util.Map;
 
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index d626e5f..c09da87 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.animation.Animator;
+import android.annotation.Nullable;
 import android.content.ComponentCallbacks2;
 import android.content.Context;
 import android.content.Intent;
@@ -575,7 +576,7 @@
      * the given fragment class.  This is a runtime exception; it is not
      * normally expected to happen.
      */
-    public static Fragment instantiate(Context context, String fname, Bundle args) {
+    public static Fragment instantiate(Context context, String fname, @Nullable Bundle args) {
         try {
             Class<?> clazz = sClassMap.get(fname);
             if (clazz == null) {
@@ -1213,7 +1214,8 @@
      * 
      * @return Return the View for the fragment's UI, or null.
      */
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+    @Nullable
+    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
             Bundle savedInstanceState) {
         return null;
     }
@@ -1228,7 +1230,7 @@
      * @param savedInstanceState If non-null, this fragment is being re-constructed
      * from a previous saved state as given here.
      */
-    public void onViewCreated(View view, Bundle savedInstanceState) {
+    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
     }
     
     /**
@@ -1237,6 +1239,7 @@
      * 
      * @return The fragment's root view, or null if it has no layout.
      */
+    @Nullable
     public View getView() {
         return mView;
     }
diff --git a/core/java/android/app/FragmentBreadCrumbs.java b/core/java/android/app/FragmentBreadCrumbs.java
index b810b89..e4de7af 100644
--- a/core/java/android/app/FragmentBreadCrumbs.java
+++ b/core/java/android/app/FragmentBreadCrumbs.java
@@ -81,14 +81,19 @@
     }
 
     public FragmentBreadCrumbs(Context context, AttributeSet attrs) {
-        this(context, attrs, android.R.style.Widget_FragmentBreadCrumbs);
+        this(context, attrs, com.android.internal.R.attr.fragmentBreadCrumbsStyle);
     }
 
-    public FragmentBreadCrumbs(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public FragmentBreadCrumbs(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.FragmentBreadCrumbs, defStyle, 0);
+    public FragmentBreadCrumbs(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.FragmentBreadCrumbs, defStyleAttr, defStyleRes);
 
         mGravity = a.getInt(com.android.internal.R.styleable.FragmentBreadCrumbs_gravity,
                 DEFAULT_GRAVITY);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 4371907..bf2a629 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -574,12 +574,12 @@
             return null;
         }
         if (index >= mActive.size()) {
-            throwException(new IllegalStateException("Fragement no longer exists for key "
+            throwException(new IllegalStateException("Fragment no longer exists for key "
                     + key + ": index " + index));
         }
         Fragment f = mActive.get(index);
         if (f == null) {
-            throwException(new IllegalStateException("Fragement no longer exists for key "
+            throwException(new IllegalStateException("Fragment no longer exists for key "
                     + key + ": index " + index));
         }
         return f;
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 631d9b1..77c2ea0 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -18,7 +18,7 @@
 
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManager.RunningServiceInfo;
-import android.app.ActivityManager.StackInfo;
+import android.app.ActivityManager.StackBoxInfo;
 import android.content.ComponentName;
 import android.content.ContentProviderNative;
 import android.content.IContentProvider;
@@ -36,7 +36,6 @@
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
-import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Debug;
@@ -118,11 +117,12 @@
     public void moveTaskToBack(int task) throws RemoteException;
     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) throws RemoteException;
     public void moveTaskBackwards(int task) throws RemoteException;
-    public int createStack(int taskId) throws RemoteException;
+    public int createStack(int taskId, int relativeStackBoxId, int position, float weight)
+            throws RemoteException;
     public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException;
-    public void resizeStack(int stackId, Rect bounds) throws RemoteException;
-    public List<StackInfo> getAllStackInfos() throws RemoteException;
-    public StackInfo getStackInfo(int stackId) throws RemoteException;
+    public void resizeStackBox(int stackBoxId, float weight) throws RemoteException;
+    public List<StackBoxInfo> getStackBoxes() throws RemoteException;
+    public StackBoxInfo getStackBoxInfo(int stackBoxId) throws RemoteException;
     public void setFocusedStack(int stackId) throws RemoteException;
     public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
     /* oneway */
@@ -681,9 +681,9 @@
     int CREATE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+167;
     int MOVE_TASK_TO_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+168;
     int RESIZE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+169;
-    int GET_ALL_STACK_INFOS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170;
+    int GET_STACK_BOXES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170;
     int SET_FOCUSED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+171;
-    int GET_STACK_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172;
+    int GET_STACK_BOX_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172;
     int CONVERT_FROM_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+173;
     int CONVERT_TO_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+174;
     int NOTIFY_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+175;
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index d0cc1bb..1ea9d87 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -50,15 +50,16 @@
             int configChanges) throws RemoteException;
     void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
     void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
-    void scheduleResumeActivity(IBinder token, int procState, boolean isForward)
+    void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs)
             throws RemoteException;
     void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
     void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
             ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
             int procState, Bundle state, List<ResultInfo> pendingResults,
-    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
-    		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
-    		throws RemoteException;
+            List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+            String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler,
+            Bundle resumeArgs)
+            throws RemoteException;
     void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
             List<Intent> pendingNewIntents, int configChanges,
             boolean notResumed, Configuration config) throws RemoteException;
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index a307a73..028fa68 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1213,8 +1213,8 @@
     }
 
     /**
-     * Perform calling of an activity's {@link Activity#onPause} method.  The
-     * default implementation simply calls through to that method.
+     * Perform calling of an activity's {@link Activity#onSaveInstanceState}
+     * method.  The default implementation simply calls through to that method.
      * 
      * @param activity The activity being saved.
      * @param outState The bundle to pass to the call.
diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java
index a7982f4..fa2813e 100644
--- a/core/java/android/app/MediaRouteButton.java
+++ b/core/java/android/app/MediaRouteButton.java
@@ -73,13 +73,18 @@
     }
 
     public MediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public MediaRouteButton(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         mRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
         mCallback = new MediaRouterCallback();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.MediaRouteButton, defStyleAttr, 0);
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.MediaRouteButton, defStyleAttr, defStyleRes);
         setRemoteIndicatorDrawable(a.getDrawable(
                 com.android.internal.R.styleable.MediaRouteButton_externalRouteEnabledDrawable));
         mMinWidth = a.getDimensionPixelSize(
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c63e586..62a84219 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.R;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -37,6 +38,8 @@
 import android.widget.ProgressBar;
 import android.widget.RemoteViews;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.text.NumberFormat;
 import java.util.ArrayList;
 
@@ -350,6 +353,11 @@
 
     public int flags;
 
+    /** @hide */
+    @IntDef({PRIORITY_DEFAULT,PRIORITY_LOW,PRIORITY_MIN,PRIORITY_HIGH,PRIORITY_MAX})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Priority {}
+
     /**
      * Default notification {@link #priority}. If your application does not prioritize its own
      * notifications, use this value for all notifications.
@@ -391,6 +399,7 @@
      * system will make a determination about how to interpret this priority when presenting
      * the notification.
      */
+    @Priority
     public int priority;
 
     /**
@@ -1550,7 +1559,7 @@
          *
          * @see Notification#priority
          */
-        public Builder setPriority(int pri) {
+        public Builder setPriority(@Priority int pri) {
             mPriority = pri;
             return this;
         }
@@ -1778,7 +1787,7 @@
             RemoteViews button = new RemoteViews(mContext.getPackageName(),
                     tombstone ? R.layout.notification_action_tombstone
                               : R.layout.notification_action);
-            button.setTextViewCompoundDrawables(R.id.action0, action.icon, 0, 0, 0);
+            button.setTextViewCompoundDrawablesRelative(R.id.action0, action.icon, 0, 0, 0);
             button.setTextViewText(R.id.action0, action.title);
             if (!tombstone) {
                 button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index bdd0adb..29885e7 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -16,6 +16,9 @@
 
 package android.app;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IIntentReceiver;
@@ -30,6 +33,9 @@
 import android.os.UserHandle;
 import android.util.AndroidException;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A description of an Intent and target action to perform with it.  Instances
  * of this class are created with {@link #getActivity}, {@link #getActivities},
@@ -86,6 +92,26 @@
 public final class PendingIntent implements Parcelable {
     private final IIntentSender mTarget;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                    FLAG_ONE_SHOT,
+                    FLAG_NO_CREATE,
+                    FLAG_CANCEL_CURRENT,
+                    FLAG_UPDATE_CURRENT,
+
+                    Intent.FILL_IN_ACTION,
+                    Intent.FILL_IN_DATA,
+                    Intent.FILL_IN_CATEGORIES,
+                    Intent.FILL_IN_COMPONENT,
+                    Intent.FILL_IN_PACKAGE,
+                    Intent.FILL_IN_SOURCE_BOUNDS,
+                    Intent.FILL_IN_SELECTOR,
+                    Intent.FILL_IN_CLIP_DATA
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Flags {}
+
     /**
      * Flag for use with {@link #getActivity}, {@link #getBroadcast}, and
      * {@link #getService}: this
@@ -96,8 +122,8 @@
     public static final int FLAG_ONE_SHOT = 1<<30;
     /**
      * Flag for use with {@link #getActivity}, {@link #getBroadcast}, and
-     * {@link #getService}: if the described PendingIntent does not already
-     * exist, then simply return null instead of creating it.
+     * {@link #getService}: if the described PendingIntent already exists,
+     * then simply return null instead of creating it.
      */
     public static final int FLAG_NO_CREATE = 1<<29;
     /**
@@ -220,7 +246,7 @@
      * supplied.
      */
     public static PendingIntent getActivity(Context context, int requestCode,
-            Intent intent, int flags) {
+            Intent intent, @Flags int flags) {
         return getActivity(context, requestCode, intent, flags, null);
     }
 
@@ -253,7 +279,7 @@
      * supplied.
      */
     public static PendingIntent getActivity(Context context, int requestCode,
-            Intent intent, int flags, Bundle options) {
+            @NonNull Intent intent, @Flags int flags, @Nullable Bundle options) {
         String packageName = context.getPackageName();
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
@@ -278,7 +304,7 @@
      * activity is started, not when the pending intent is created.
      */
     public static PendingIntent getActivityAsUser(Context context, int requestCode,
-            Intent intent, int flags, Bundle options, UserHandle user) {
+            @NonNull Intent intent, int flags, Bundle options, UserHandle user) {
         String packageName = context.getPackageName();
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
@@ -343,7 +369,7 @@
      * supplied.
      */
     public static PendingIntent getActivities(Context context, int requestCode,
-            Intent[] intents, int flags) {
+            @NonNull Intent[] intents, @Flags int flags) {
         return getActivities(context, requestCode, intents, flags, null);
     }
 
@@ -393,7 +419,7 @@
      * supplied.
      */
     public static PendingIntent getActivities(Context context, int requestCode,
-            Intent[] intents, int flags, Bundle options) {
+            @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options) {
         String packageName = context.getPackageName();
         String[] resolvedTypes = new String[intents.length];
         for (int i=0; i<intents.length; i++) {
@@ -419,7 +445,7 @@
      * activity is started, not when the pending intent is created.
      */
     public static PendingIntent getActivitiesAsUser(Context context, int requestCode,
-            Intent[] intents, int flags, Bundle options, UserHandle user) {
+            @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) {
         String packageName = context.getPackageName();
         String[] resolvedTypes = new String[intents.length];
         for (int i=0; i<intents.length; i++) {
@@ -463,7 +489,7 @@
      * supplied.
      */
     public static PendingIntent getBroadcast(Context context, int requestCode,
-            Intent intent, int flags) {
+            Intent intent, @Flags int flags) {
         return getBroadcastAsUser(context, requestCode, intent, flags,
                 new UserHandle(UserHandle.myUserId()));
     }
@@ -517,7 +543,7 @@
      * supplied.
      */
     public static PendingIntent getService(Context context, int requestCode,
-            Intent intent, int flags) {
+            @NonNull Intent intent, @Flags int flags) {
         String packageName = context.getPackageName();
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
@@ -747,6 +773,7 @@
      * @return The package name of the PendingIntent, or null if there is
      * none associated with it.
      */
+    @Nullable
     public String getCreatorPackage() {
         try {
             return ActivityManagerNative.getDefault()
@@ -805,6 +832,7 @@
      * @return The user handle of the PendingIntent, or null if there is
      * none associated with it.
      */
+    @Nullable
     public UserHandle getCreatorUserHandle() {
         try {
             int uid = ActivityManagerNative.getDefault()
@@ -920,8 +948,8 @@
      * @param sender The PendingIntent to write, or null.
      * @param out Where to write the PendingIntent.
      */
-    public static void writePendingIntentOrNullToParcel(PendingIntent sender,
-            Parcel out) {
+    public static void writePendingIntentOrNullToParcel(@Nullable PendingIntent sender,
+            @NonNull Parcel out) {
         out.writeStrongBinder(sender != null ? sender.mTarget.asBinder()
                 : null);
     }
@@ -936,7 +964,8 @@
      * @return Returns the Messenger read from the Parcel, or null if null had
      * been written.
      */
-    public static PendingIntent readPendingIntentOrNullFromParcel(Parcel in) {
+    @Nullable
+    public static PendingIntent readPendingIntentOrNullFromParcel(@NonNull Parcel in) {
         IBinder b = in.readStrongBinder();
         return b != null ? new PendingIntent(b) : null;
     }
diff --git a/core/java/android/app/ResultInfo.java b/core/java/android/app/ResultInfo.java
index 48a0fc2..5e0867c 100644
--- a/core/java/android/app/ResultInfo.java
+++ b/core/java/android/app/ResultInfo.java
@@ -17,12 +17,8 @@
 package android.app;
 
 import android.content.Intent;
-import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Bundle;
-
-import java.util.Map;
 
 /**
  * {@hide}
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index f9c245e..33c3409 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.database.Cursor;
 import android.graphics.Rect;
@@ -34,7 +33,6 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Slog;
 import android.view.KeyEvent;
 
 import java.util.List;
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 86fd7b9..dd882ce 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -42,7 +42,6 @@
 import java.util.Set;
 import java.util.WeakHashMap;
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
 
 import libcore.io.ErrnoException;
 import libcore.io.IoUtils;
diff --git a/core/java/android/app/TaskStackBuilder.java b/core/java/android/app/TaskStackBuilder.java
index 3e0ac7e..0077db1 100644
--- a/core/java/android/app/TaskStackBuilder.java
+++ b/core/java/android/app/TaskStackBuilder.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.annotation.NonNull;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -244,7 +245,7 @@
      *
      * @return The obtained PendingIntent
      */
-    public PendingIntent getPendingIntent(int requestCode, int flags) {
+    public PendingIntent getPendingIntent(int requestCode, @PendingIntent.Flags int flags) {
         return getPendingIntent(requestCode, flags, null);
     }
 
@@ -263,7 +264,8 @@
      *
      * @return The obtained PendingIntent
      */
-    public PendingIntent getPendingIntent(int requestCode, int flags, Bundle options) {
+    public PendingIntent getPendingIntent(int requestCode, @PendingIntent.Flags int flags,
+            Bundle options) {
         if (mIntents.isEmpty()) {
             throw new IllegalStateException(
                     "No intents added to TaskStackBuilder; cannot getPendingIntent");
@@ -294,6 +296,7 @@
      *
      * @return An array containing the intents added to this builder.
      */
+    @NonNull
     public Intent[] getIntents() {
         Intent[] intents = new Intent[mIntents.size()];
         if (intents.length == 0) return intents;
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 952227f..a85c61f 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -16,17 +16,19 @@
 
 package android.app;
 
-import com.android.internal.R;
-
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.os.Bundle;
+import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.TimePicker;
 import android.widget.TimePicker.OnTimeChangedListener;
 
+import com.android.internal.R;
+
+
 /**
  * A dialog that prompts the user for the time of day using a {@link TimePicker}.
  *
@@ -38,7 +40,7 @@
 
     /**
      * The callback interface used to indicate the user is done filling in
-     * the time (they clicked on the 'Set' button).
+     * the time (they clicked on the 'Done' button).
      */
     public interface OnTimeSetListener {
 
@@ -55,7 +57,7 @@
     private static final String IS_24_HOUR = "is24hour";
 
     private final TimePicker mTimePicker;
-    private final OnTimeSetListener mCallback;
+    private final OnTimeSetListener mTimeSetCallback;
 
     int mInitialHourOfDay;
     int mInitialMinute;
@@ -74,6 +76,16 @@
         this(context, 0, callBack, hourOfDay, minute, is24HourView);
     }
 
+    static int resolveDialogTheme(Context context, int resid) {
+        if (resid == 0) {
+            TypedValue outValue = new TypedValue();
+            context.getTheme().resolveAttribute(R.attr.timePickerDialogTheme, outValue, true);
+            return outValue.resourceId;
+        } else {
+            return resid;
+        }
+    }
+
     /**
      * @param context Parent.
      * @param theme the theme to apply to this dialog
@@ -86,17 +98,13 @@
             int theme,
             OnTimeSetListener callBack,
             int hourOfDay, int minute, boolean is24HourView) {
-        super(context, theme);
-        mCallback = callBack;
+        super(context, resolveDialogTheme(context, theme));
+        mTimeSetCallback = callBack;
         mInitialHourOfDay = hourOfDay;
         mInitialMinute = minute;
         mIs24HourView = is24HourView;
 
-        setIcon(0);
-        setTitle(R.string.time_picker_dialog_title);
-
         Context themeContext = getContext();
-        setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_done), this);
 
         LayoutInflater inflater =
                 (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -104,7 +112,18 @@
         setView(view);
         mTimePicker = (TimePicker) view.findViewById(R.id.timePicker);
 
-        // initialize state
+        // Initialize state
+        mTimePicker.setLegacyMode(false /* will show new UI */);
+        mTimePicker.setShowDoneButton(true);
+        mTimePicker.setDismissCallback(new TimePicker.TimePickerDismissCallback() {
+            @Override
+            public void dismiss(TimePicker view, boolean isCancel, int hourOfDay, int minute) {
+                if (!isCancel) {
+                    mTimeSetCallback.onTimeSet(view, hourOfDay, minute);
+                }
+                TimePickerDialog.this.dismiss();
+            }
+        });
         mTimePicker.setIs24HourView(mIs24HourView);
         mTimePicker.setCurrentHour(mInitialHourOfDay);
         mTimePicker.setCurrentMinute(mInitialMinute);
@@ -125,9 +144,9 @@
     }
 
     private void tryNotifyTimeSet() {
-        if (mCallback != null) {
+        if (mTimeSetCallback != null) {
             mTimePicker.clearFocus();
-            mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
+            mTimeSetCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
                     mTimePicker.getCurrentMinute());
         }
     }
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index ced72f8..4435032 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -41,7 +41,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -221,24 +220,9 @@
         
         private static final int MSG_CLEAR_WALLPAPER = 1;
         
-        private final Handler mHandler;
-        
         Globals(Looper looper) {
             IBinder b = ServiceManager.getService(Context.WALLPAPER_SERVICE);
             mService = IWallpaperManager.Stub.asInterface(b);
-            mHandler = new Handler(looper) {
-                @Override
-                public void handleMessage(Message msg) {
-                    switch (msg.what) {
-                        case MSG_CLEAR_WALLPAPER:
-                            synchronized (this) {
-                                mWallpaper = null;
-                                mDefaultWallpaper = null;
-                            }
-                            break;
-                    }
-                }
-            };
         }
         
         public void onWallpaperChanged() {
@@ -247,7 +231,10 @@
              * to null so if the user requests the wallpaper again then we'll
              * fetch it.
              */
-            mHandler.sendEmptyMessage(MSG_CLEAR_WALLPAPER);
+            synchronized (this) {
+                mWallpaper = null;
+                mDefaultWallpaper = null;
+            }
         }
 
         public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault) {
@@ -280,7 +267,6 @@
             synchronized (this) {
                 mWallpaper = null;
                 mDefaultWallpaper = null;
-                mHandler.removeMessages(MSG_CLEAR_WALLPAPER);
             }
         }
 
diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java
index cb0737e..cfd0a65 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -16,9 +16,6 @@
 
 package android.app.backup;
 
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
diff --git a/core/java/android/app/backup/SharedPreferencesBackupHelper.java b/core/java/android/app/backup/SharedPreferencesBackupHelper.java
index 213bd31..939616b 100644
--- a/core/java/android/app/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/app/backup/SharedPreferencesBackupHelper.java
@@ -18,7 +18,6 @@
 
 import android.app.QueuedWork;
 import android.content.Context;
-import android.content.SharedPreferences;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index f104d71..84d3835 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -19,7 +19,6 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 
-import android.app.ActivityThread;
 import android.content.Context;
 import android.os.Binder;
 import android.os.Handler;
@@ -31,7 +30,6 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.util.TypedValue;
 import android.widget.RemoteViews;
 import android.widget.RemoteViews.OnClickHandler;
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index d1c7bec..8a89cbc 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -16,7 +16,6 @@
 
 package android.appwidget;
 
-import android.app.ActivityManagerNative;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index e2bc80a..7ee2313 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -19,9 +19,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
-import android.os.Binder;
 import android.os.IBinder;
-import android.os.Message;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -34,10 +32,8 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Random;
 import java.util.Set;
 import java.util.UUID;
 
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index d789a94..1bd698d 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -19,12 +19,10 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
-import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.io.IOException;
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index a2bb78c..b6e1bb3 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -18,18 +18,9 @@
 
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProfile.ServiceListener;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.IBluetoothStateChangeCallback;
-
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
index f0ecbb4..a86677c 100644
--- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java
+++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
@@ -16,7 +16,6 @@
 package android.bluetooth;
 
 import java.util.ArrayList;
-import java.util.IllegalFormatConversionException;
 import java.util.List;
 import java.util.UUID;
 
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index 58ee54f..09072f9 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -19,18 +19,9 @@
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProfile.ServiceListener;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.IBluetoothStateChangeCallback;
-
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java
index f9f1d97..fc3ffe8 100644
--- a/core/java/android/bluetooth/BluetoothGattServerCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattServerCallback.java
@@ -18,8 +18,6 @@
 
 import android.bluetooth.BluetoothDevice;
 
-import android.util.Log;
-
 /**
  * This abstract class is used to implement {@link BluetoothGattServer} callbacks.
  */
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index 2e950fa..daf3bad 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -23,7 +23,6 @@
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index 844f432..c4ba5b1 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -24,7 +24,6 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index 92a2f1e..5a1b7aa 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -24,7 +24,6 @@
 import android.content.ServiceConnection;
 import android.os.RemoteException;
 import android.os.IBinder;
-import android.os.ServiceManager;
 import android.util.Log;
 
 /**
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index b7a37f4..e72832c 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -24,7 +24,6 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index 7f45652..8522ee0 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -22,7 +22,6 @@
 import android.content.ServiceConnection;
 import android.os.RemoteException;
 import android.os.IBinder;
-import android.os.ServiceManager;
 import android.util.Log;
 
 /**
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index 96be8a2..bc56e55 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -17,7 +17,6 @@
 package android.bluetooth;
 
 import android.os.Handler;
-import android.os.Message;
 import android.os.ParcelUuid;
 
 import java.io.Closeable;
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index d10eaea..ddefc70 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -16,21 +16,16 @@
 
 package android.bluetooth;
 
-import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.io.Closeable;
 import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.List;
 import java.util.Locale;
 import java.util.UUID;
 import android.net.LocalSocket;
diff --git a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
index a9b7176..6dd551e 100644
--- a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
+++ b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
@@ -17,9 +17,6 @@
 package android.bluetooth;
 
 import android.net.BaseNetworkStateTracker;
-import android.os.IBinder;
-import android.os.ServiceManager;
-import android.os.INetworkManagementService;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.DhcpResults;
@@ -35,11 +32,6 @@
 import android.os.Messenger;
 import android.text.TextUtils;
 import android.util.Log;
-import java.net.InterfaceAddress;
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-import java.net.Inet4Address;
-import android.os.SystemProperties;
 
 import com.android.internal.util.AsyncChannel;
 
@@ -143,11 +135,6 @@
     }
 
     @Override
-    public void captivePortalCheckComplete() {
-        // not implemented
-    }
-
-    @Override
     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
         // not implemented
     }
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java
index eb7426e..7241e0d 100644
--- a/core/java/android/content/AsyncTaskLoader.java
+++ b/core/java/android/content/AsyncTaskLoader.java
@@ -20,7 +20,7 @@
 import android.os.Handler;
 import android.os.OperationCanceledException;
 import android.os.SystemClock;
-import android.util.Slog;
+import android.util.Log;
 import android.util.TimeUtils;
 
 import java.io.FileDescriptor;
@@ -64,10 +64,10 @@
         /* Runs on a worker thread */
         @Override
         protected D doInBackground(Void... params) {
-            if (DEBUG) Slog.v(TAG, this + " >>> doInBackground");
+            if (DEBUG) Log.v(TAG, this + " >>> doInBackground");
             try {
                 D data = AsyncTaskLoader.this.onLoadInBackground();
-                if (DEBUG) Slog.v(TAG, this + "  <<< doInBackground");
+                if (DEBUG) Log.v(TAG, this + "  <<< doInBackground");
                 return data;
             } catch (OperationCanceledException ex) {
                 if (!isCancelled()) {
@@ -79,7 +79,7 @@
                     // So we treat this case as an unhandled exception.
                     throw ex;
                 }
-                if (DEBUG) Slog.v(TAG, this + "  <<< doInBackground (was canceled)", ex);
+                if (DEBUG) Log.v(TAG, this + "  <<< doInBackground (was canceled)", ex);
                 return null;
             }
         }
@@ -87,7 +87,7 @@
         /* Runs on the UI thread */
         @Override
         protected void onPostExecute(D data) {
-            if (DEBUG) Slog.v(TAG, this + " onPostExecute");
+            if (DEBUG) Log.v(TAG, this + " onPostExecute");
             try {
                 AsyncTaskLoader.this.dispatchOnLoadComplete(this, data);
             } finally {
@@ -98,7 +98,7 @@
         /* Runs on the UI thread */
         @Override
         protected void onCancelled(D data) {
-            if (DEBUG) Slog.v(TAG, this + " onCancelled");
+            if (DEBUG) Log.v(TAG, this + " onCancelled");
             try {
                 AsyncTaskLoader.this.dispatchOnCancelled(this, data);
             } finally {
@@ -162,18 +162,18 @@
         super.onForceLoad();
         cancelLoad();
         mTask = new LoadTask();
-        if (DEBUG) Slog.v(TAG, "Preparing load: mTask=" + mTask);
+        if (DEBUG) Log.v(TAG, "Preparing load: mTask=" + mTask);
         executePendingTask();
     }
 
     @Override
     protected boolean onCancelLoad() {
-        if (DEBUG) Slog.v(TAG, "onCancelLoad: mTask=" + mTask);
+        if (DEBUG) Log.v(TAG, "onCancelLoad: mTask=" + mTask);
         if (mTask != null) {
             if (mCancellingTask != null) {
                 // There was a pending task already waiting for a previous
                 // one being canceled; just drop it.
-                if (DEBUG) Slog.v(TAG,
+                if (DEBUG) Log.v(TAG,
                         "cancelLoad: still waiting for cancelled task; dropping next");
                 if (mTask.waiting) {
                     mTask.waiting = false;
@@ -184,14 +184,14 @@
             } else if (mTask.waiting) {
                 // There is a task, but it is waiting for the time it should
                 // execute.  We can just toss it.
-                if (DEBUG) Slog.v(TAG, "cancelLoad: task is waiting, dropping it");
+                if (DEBUG) Log.v(TAG, "cancelLoad: task is waiting, dropping it");
                 mTask.waiting = false;
                 mHandler.removeCallbacks(mTask);
                 mTask = null;
                 return false;
             } else {
                 boolean cancelled = mTask.cancel(false);
-                if (DEBUG) Slog.v(TAG, "cancelLoad: cancelled=" + cancelled);
+                if (DEBUG) Log.v(TAG, "cancelLoad: cancelled=" + cancelled);
                 if (cancelled) {
                     mCancellingTask = mTask;
                     cancelLoadInBackground();
@@ -223,7 +223,7 @@
                 long now = SystemClock.uptimeMillis();
                 if (now < (mLastLoadCompleteTime+mUpdateThrottle)) {
                     // Not yet time to do another load.
-                    if (DEBUG) Slog.v(TAG, "Waiting until "
+                    if (DEBUG) Log.v(TAG, "Waiting until "
                             + (mLastLoadCompleteTime+mUpdateThrottle)
                             + " to execute: " + mTask);
                     mTask.waiting = true;
@@ -231,7 +231,7 @@
                     return;
                 }
             }
-            if (DEBUG) Slog.v(TAG, "Executing: " + mTask);
+            if (DEBUG) Log.v(TAG, "Executing: " + mTask);
             mTask.executeOnExecutor(mExecutor, (Void[]) null);
         }
     }
@@ -239,11 +239,11 @@
     void dispatchOnCancelled(LoadTask task, D data) {
         onCanceled(data);
         if (mCancellingTask == task) {
-            if (DEBUG) Slog.v(TAG, "Cancelled task is now canceled!");
+            if (DEBUG) Log.v(TAG, "Cancelled task is now canceled!");
             rollbackContentChanged();
             mLastLoadCompleteTime = SystemClock.uptimeMillis();
             mCancellingTask = null;
-            if (DEBUG) Slog.v(TAG, "Delivering cancellation");
+            if (DEBUG) Log.v(TAG, "Delivering cancellation");
             deliverCancellation();
             executePendingTask();
         }
@@ -251,7 +251,7 @@
 
     void dispatchOnLoadComplete(LoadTask task, D data) {
         if (mTask != task) {
-            if (DEBUG) Slog.v(TAG, "Load complete of old task, trying to cancel");
+            if (DEBUG) Log.v(TAG, "Load complete of old task, trying to cancel");
             dispatchOnCancelled(task, data);
         } else {
             if (isAbandoned()) {
@@ -261,7 +261,7 @@
                 commitContentChanged();
                 mLastLoadCompleteTime = SystemClock.uptimeMillis();
                 mTask = null;
-                if (DEBUG) Slog.v(TAG, "Delivering result");
+                if (DEBUG) Log.v(TAG, "Delivering result");
                 deliverResult(data);
             }
         }
diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java
index 73e6fd0..5653cad 100644
--- a/core/java/android/content/ClipboardManager.java
+++ b/core/java/android/content/ClipboardManager.java
@@ -22,8 +22,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.ServiceManager;
-import android.os.StrictMode;
-import android.util.Log;
 
 import java.util.ArrayList;
 
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 4e6cc92..018e4c5 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -141,7 +141,7 @@
     public static final String SYNC_EXTRAS_PRIORITY = "sync_priority";
 
     /** {@hide} Flag to allow sync to occur on metered network. */
-    public static final String SYNC_EXTRAS_DISALLOW_METERED = "disallow_metered";
+    public static final String SYNC_EXTRAS_DISALLOW_METERED = "allow_metered";
 
     /**
      * Set by the SyncManager to request that the SyncAdapter initialize itself for
@@ -368,9 +368,7 @@
     }
 
     /**
-     * <p>
      * Query the given URI, returning a {@link Cursor} over the result set.
-     * </p>
      * <p>
      * For best performance, the caller should follow these guidelines:
      * <ul>
@@ -405,9 +403,8 @@
     }
 
     /**
-     * <p>
-     * Query the given URI, returning a {@link Cursor} over the result set.
-     * </p>
+     * Query the given URI, returning a {@link Cursor} over the result set
+     * with optional support for cancellation.
      * <p>
      * For best performance, the caller should follow these guidelines:
      * <ul>
@@ -1751,7 +1748,7 @@
             new SyncRequest.Builder()
                 .setSyncAdapter(account, authority)
                 .setExtras(extras)
-                .syncOnce()
+                .syncOnce()     // Immediate sync.
                 .build();
         requestSync(request);
     }
@@ -1759,9 +1756,6 @@
     /**
      * Register a sync with the SyncManager. These requests are built using the
      * {@link SyncRequest.Builder}.
-     *
-     * @param request The immutable SyncRequest object containing the sync parameters. Use
-     * {@link SyncRequest.Builder} to construct these.
      */
     public static void requestSync(SyncRequest request) {
         try {
@@ -1829,12 +1823,25 @@
      */
     public static void cancelSync(Account account, String authority) {
         try {
-            getContentService().cancelSync(account, authority);
+            getContentService().cancelSync(account, authority, null);
         } catch (RemoteException e) {
         }
     }
 
     /**
+     * Cancel any active or pending syncs that are running on this service.
+     *
+     * @param cname the service for which to cancel all active/pending operations.
+     */
+    public static void cancelSync(ComponentName cname) {
+        try {
+            getContentService().cancelSync(null, null, cname);
+        } catch (RemoteException e) {
+            
+        }
+    }
+
+    /**
      * Get information about the SyncAdapters that are known to the system.
      * @return an array of SyncAdapters that have registered with the system
      */
@@ -1897,12 +1904,13 @@
      * {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE},
      * {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true.
      * If any are supplied then an {@link IllegalArgumentException} will be thrown.
-     * <p>As of API level 19 this function introduces a default flexibility of ~4% (up to a maximum
-     * of one hour in the day) into the requested period. Use
-     * {@link SyncRequest.Builder#syncPeriodic(long, long)} to set this flexibility manually.
      *
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
+     * <p>The bundle for a periodic sync can be queried by applications with the correct
+     * permissions using
+     * {@link ContentResolver#getPeriodicSyncs(Account account, String provider)}, so no
+     * sensitive data should be transferred here.
      *
      * @param account the account to specify in the sync
      * @param authority the provider to specify in the sync request
@@ -1932,6 +1940,26 @@
     }
 
     /**
+     * {@hide}
+     * Helper function to throw an <code>IllegalArgumentException</code> if any illegal
+     * extras were set for a periodic sync.
+     *
+     * @param extras bundle to validate.
+     */
+    public static boolean invalidPeriodicExtras(Bundle extras) {
+        if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)
+                || extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)
+                || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false)
+                || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
+                || extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)
+                || extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false)
+                || extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Remove a periodic sync. Has no affect if account, authority and extras don't match
      * an existing periodic sync.
      * <p>This method requires the caller to hold the permission
@@ -1951,6 +1979,31 @@
     }
 
     /**
+     * Remove the specified sync. This will cancel any pending or active syncs. If the request is
+     * for a periodic sync, this call will remove any future occurrences.
+     * <p>If a periodic sync is specified, the caller must hold the permission
+     * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. If this SyncRequest targets a
+     * SyncService adapter,the calling application must be signed with the same certificate as the
+     * adapter.
+     *</p>It is possible to cancel a sync using a SyncRequest object that is not the same object
+     * with which you requested the sync. Do so by building a SyncRequest with the same
+     * service/adapter, frequency, <b>and</b> extras bundle.
+     *
+     * @param request SyncRequest object containing information about sync to cancel.
+     */
+    public static void cancelSync(SyncRequest request) {
+        if (request == null) {
+            throw new IllegalArgumentException("request cannot be null");
+        }
+        try {
+            getContentService().cancelRequest(request);
+        } catch (RemoteException e) {
+            // exception ignored; if this is thrown then it means the runtime is in the midst of
+            // being restarted
+        }
+    }
+
+    /**
      * Get the list of information about the periodic syncs for the given account and authority.
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#READ_SYNC_SETTINGS}.
@@ -1961,7 +2014,23 @@
      */
     public static List<PeriodicSync> getPeriodicSyncs(Account account, String authority) {
         try {
-            return getContentService().getPeriodicSyncs(account, authority);
+            return getContentService().getPeriodicSyncs(account, authority, null);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    /**
+     * Return periodic syncs associated with the provided component.
+     * <p>The calling application must be signed with the same certificate as the target component,
+     * otherwise this call will fail.
+     */
+    public static List<PeriodicSync> getPeriodicSyncs(ComponentName cname) {
+        if (cname == null) {
+            throw new IllegalArgumentException("Component must not be null");
+        }
+        try {
+            return getContentService().getPeriodicSyncs(null, null, cname);
         } catch (RemoteException e) {
             throw new RuntimeException("the ContentService should always be reachable", e);
         }
@@ -1997,6 +2066,38 @@
     }
 
     /**
+     * Set whether the provided {@link SyncService} is available to process work.
+     * <p>This method requires the caller to hold the permission
+     * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
+     * <p>The calling application must be signed with the same certificate as the target component,
+     * otherwise this call will fail.
+     */
+    public static void setServiceActive(ComponentName cname, boolean active) {
+        try {
+            getContentService().setServiceActive(cname, active);
+        } catch (RemoteException e) {
+            // exception ignored; if this is thrown then it means the runtime is in the midst of
+            // being restarted
+        }
+    }
+
+    /**
+     * Query the state of this sync service.
+     * <p>Set with {@link #setServiceActive(ComponentName cname, boolean active)}.
+     * <p>The calling application must be signed with the same certificate as the target component,
+     * otherwise this call will fail.
+     * @param cname ComponentName referring to a {@link SyncService}
+     * @return true if jobs will be run on this service, false otherwise.
+     */
+    public static boolean isServiceActive(ComponentName cname) {
+        try {
+            return getContentService().isServiceActive(cname);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    /**
      * Gets the master auto-sync setting that applies to all the providers and accounts.
      * If this is false then the per-provider auto-sync setting is ignored.
      * <p>This method requires the caller to hold the permission
@@ -2030,8 +2131,8 @@
     }
 
     /**
-     * Returns true if there is currently a sync operation for the given
-     * account or authority in the pending list, or actively being processed.
+     * Returns true if there is currently a sync operation for the given account or authority
+     * actively being processed.
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#READ_SYNC_STATS}.
      * @param account the account whose setting we are querying
@@ -2039,8 +2140,26 @@
      * @return true if a sync is active for the given account or authority.
      */
     public static boolean isSyncActive(Account account, String authority) {
+        if (account == null) {
+            throw new IllegalArgumentException("account must not be null");
+        }
+        if (authority == null) {
+            throw new IllegalArgumentException("authority must not be null");
+        }
+
         try {
-            return getContentService().isSyncActive(account, authority);
+            return getContentService().isSyncActive(account, authority, null);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    public static boolean isSyncActive(ComponentName cname) {
+        if (cname == null) {
+            throw new IllegalArgumentException("component name must not be null");
+        }
+        try {
+            return getContentService().isSyncActive(null, null, cname);
         } catch (RemoteException e) {
             throw new RuntimeException("the ContentService should always be reachable", e);
         }
@@ -2098,7 +2217,7 @@
      */
     public static SyncStatusInfo getSyncStatus(Account account, String authority) {
         try {
-            return getContentService().getSyncStatus(account, authority);
+            return getContentService().getSyncStatus(account, authority, null);
         } catch (RemoteException e) {
             throw new RuntimeException("the ContentService should always be reachable", e);
         }
@@ -2114,7 +2233,15 @@
      */
     public static boolean isSyncPending(Account account, String authority) {
         try {
-            return getContentService().isSyncPending(account, authority);
+            return getContentService().isSyncPending(account, authority, null);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    public static boolean isSyncPending(ComponentName cname) {
+        try {
+            return getContentService().isSyncPending(null, null, cname);
         } catch (RemoteException e) {
             throw new RuntimeException("the ContentService should always be reachable", e);
         }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 2e4e209..32b95c2 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -16,6 +16,10 @@
 
 package android.content;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.StringDef;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
@@ -47,6 +51,8 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * Interface to global information about an application environment.  This is
@@ -132,6 +138,20 @@
      */
     public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 0x0008;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                BIND_AUTO_CREATE,
+                BIND_AUTO_CREATE,
+                BIND_DEBUG_UNBIND,
+                BIND_NOT_FOREGROUND,
+                BIND_ABOVE_CLIENT,
+                BIND_ALLOW_OOM_MANAGEMENT,
+                BIND_WAIVE_PRIORITY
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface BindServiceFlags {}
+
     /**
      * Flag for {@link #bindService}: automatically create the service as long
      * as the binding exists.  Note that while this will create the service,
@@ -495,7 +515,7 @@
      * and {@link #MODE_WORLD_WRITEABLE} to control permissions.  The bit
      * {@link #MODE_MULTI_PROCESS} can also be used if multiple processes
      * are mutating the same SharedPreferences file.  {@link #MODE_MULTI_PROCESS}
-     * is always on in apps targetting Gingerbread (Android 2.3) and below, and
+     * is always on in apps targeting Gingerbread (Android 2.3) and below, and
      * off by default in later versions.
      *
      * @return The single {@link SharedPreferences} instance that can be used
@@ -674,7 +694,8 @@
      * @see #getFilesDir
      * @see android.os.Environment#getExternalStoragePublicDirectory
      */
-    public abstract File getExternalFilesDir(String type);
+    @Nullable
+    public abstract File getExternalFilesDir(@Nullable String type);
 
     /**
      * Returns absolute paths to application-specific directories on all
@@ -840,6 +861,7 @@
      *
      * @see #getCacheDir
      */
+    @Nullable
     public abstract File getExternalCacheDir();
 
     /**
@@ -960,7 +982,8 @@
      * @see #deleteDatabase
      */
     public abstract SQLiteDatabase openOrCreateDatabase(String name,
-            int mode, CursorFactory factory, DatabaseErrorHandler errorHandler);
+            int mode, CursorFactory factory,
+            @Nullable DatabaseErrorHandler errorHandler);
 
     /**
      * Delete an existing private SQLiteDatabase associated with this Context's
@@ -1106,7 +1129,7 @@
      * @see #startActivity(Intent)
      * @see PackageManager#resolveActivity
      */
-    public abstract void startActivity(Intent intent, Bundle options);
+    public abstract void startActivity(Intent intent, @Nullable Bundle options);
 
     /**
      * Version of {@link #startActivity(Intent, Bundle)} that allows you to specify the
@@ -1122,7 +1145,7 @@
      * @throws ActivityNotFoundException &nbsp;
      * @hide
      */
-    public void startActivityAsUser(Intent intent, Bundle options, UserHandle userId) {
+    public void startActivityAsUser(Intent intent, @Nullable Bundle options, UserHandle userId) {
         throw new RuntimeException("Not implemented. Must override in a subclass.");
     }
 
@@ -1241,7 +1264,7 @@
      * @see #startIntentSender(IntentSender, Intent, int, int, int)
      */
     public abstract void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
             Bundle options) throws IntentSender.SendIntentException;
 
     /**
@@ -1291,11 +1314,11 @@
      * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
      */
     public abstract void sendBroadcast(Intent intent,
-            String receiverPermission);
+            @Nullable String receiverPermission);
 
     /**
      * Like {@link #sendBroadcast(Intent, String)}, but also allows specification
-     * of an assocated app op as per {@link android.app.AppOpsManager}.
+     * of an associated app op as per {@link android.app.AppOpsManager}.
      * @hide
      */
     public abstract void sendBroadcast(Intent intent,
@@ -1322,7 +1345,7 @@
      * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
      */
     public abstract void sendOrderedBroadcast(Intent intent,
-            String receiverPermission);
+            @Nullable String receiverPermission);
 
     /**
      * Version of {@link #sendBroadcast(Intent)} that allows you to
@@ -1366,15 +1389,15 @@
      * @see #registerReceiver
      * @see android.app.Activity#RESULT_OK
      */
-    public abstract void sendOrderedBroadcast(Intent intent,
-            String receiverPermission, BroadcastReceiver resultReceiver,
-            Handler scheduler, int initialCode, String initialData,
-            Bundle initialExtras);
+    public abstract void sendOrderedBroadcast(@NonNull Intent intent,
+            @Nullable String receiverPermission, BroadcastReceiver resultReceiver,
+            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+            @Nullable Bundle initialExtras);
 
     /**
      * Like {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler,
      * int, String, android.os.Bundle)}, but also allows specification
-     * of an assocated app op as per {@link android.app.AppOpsManager}.
+     * of an associated app op as per {@link android.app.AppOpsManager}.
      * @hide
      */
     public abstract void sendOrderedBroadcast(Intent intent,
@@ -1409,7 +1432,7 @@
      * @see #sendBroadcast(Intent, String)
      */
     public abstract void sendBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission);
+            @Nullable String receiverPermission);
 
     /**
      * Version of
@@ -1442,8 +1465,9 @@
      * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
      */
     public abstract void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
-            int initialCode, String initialData, Bundle initialExtras);
+            @Nullable String receiverPermission, BroadcastReceiver resultReceiver,
+            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+            @Nullable  Bundle initialExtras);
 
     /**
      * Perform a {@link #sendBroadcast(Intent)} that is "sticky," meaning the
@@ -1508,8 +1532,8 @@
      */
     public abstract void sendStickyOrderedBroadcast(Intent intent,
             BroadcastReceiver resultReceiver,
-            Handler scheduler, int initialCode, String initialData,
-            Bundle initialExtras);
+            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+            @Nullable Bundle initialExtras);
 
     /**
      * Remove the data previously sent with {@link #sendStickyBroadcast},
@@ -1569,8 +1593,8 @@
      */
     public abstract void sendStickyOrderedBroadcastAsUser(Intent intent,
             UserHandle user, BroadcastReceiver resultReceiver,
-            Handler scheduler, int initialCode, String initialData,
-            Bundle initialExtras);
+            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+            @Nullable Bundle initialExtras);
 
     /**
      * Version of {@link #removeStickyBroadcast(Intent)} that allows you to specify the
@@ -1637,7 +1661,8 @@
      * @see #sendBroadcast
      * @see #unregisterReceiver
      */
-    public abstract Intent registerReceiver(BroadcastReceiver receiver,
+    @Nullable
+    public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,
                                             IntentFilter filter);
 
     /**
@@ -1671,8 +1696,10 @@
      * @see #sendBroadcast
      * @see #unregisterReceiver
      */
+    @Nullable
     public abstract Intent registerReceiver(BroadcastReceiver receiver,
-            IntentFilter filter, String broadcastPermission, Handler scheduler);
+            IntentFilter filter, @Nullable String broadcastPermission,
+            @Nullable Handler scheduler);
 
     /**
      * @hide
@@ -1698,9 +1725,10 @@
      * @see #sendBroadcast
      * @see #unregisterReceiver
      */
+    @Nullable
     public abstract Intent registerReceiverAsUser(BroadcastReceiver receiver,
-            UserHandle user, IntentFilter filter, String broadcastPermission,
-            Handler scheduler);
+            UserHandle user, IntentFilter filter, @Nullable String broadcastPermission,
+            @Nullable Handler scheduler);
 
     /**
      * Unregister a previously registered BroadcastReceiver.  <em>All</em>
@@ -1759,6 +1787,7 @@
      * @see #stopService
      * @see #bindService
      */
+    @Nullable
     public abstract ComponentName startService(Intent service);
 
     /**
@@ -1846,8 +1875,8 @@
      * @see #BIND_DEBUG_UNBIND
      * @see #BIND_NOT_FOREGROUND
      */
-    public abstract boolean bindService(Intent service, ServiceConnection conn,
-            int flags);
+    public abstract boolean bindService(Intent service, @NonNull ServiceConnection conn,
+            @BindServiceFlags int flags);
 
     /**
      * Same as {@link #bindService(Intent, ServiceConnection, int)}, but with an explicit userHandle
@@ -1868,7 +1897,7 @@
      *
      * @see #bindService
      */
-    public abstract void unbindService(ServiceConnection conn);
+    public abstract void unbindService(@NonNull ServiceConnection conn);
 
     /**
      * Start executing an {@link android.app.Instrumentation} class.  The given
@@ -1893,8 +1922,64 @@
      * @return {@code true} if the instrumentation was successfully started,
      * else {@code false} if it could not be found.
      */
-    public abstract boolean startInstrumentation(ComponentName className,
-            String profileFile, Bundle arguments);
+    public abstract boolean startInstrumentation(@NonNull ComponentName className,
+            @Nullable String profileFile, @Nullable Bundle arguments);
+
+    /** @hide */
+    @StringDef({
+            POWER_SERVICE,
+            WINDOW_SERVICE,
+            LAYOUT_INFLATER_SERVICE,
+            ACCOUNT_SERVICE,
+            ACTIVITY_SERVICE,
+            ALARM_SERVICE,
+            NOTIFICATION_SERVICE,
+            ACCESSIBILITY_SERVICE,
+            CAPTIONING_SERVICE,
+            KEYGUARD_SERVICE,
+            LOCATION_SERVICE,
+            //@hide: COUNTRY_DETECTOR,
+            SEARCH_SERVICE,
+            SENSOR_SERVICE,
+            STORAGE_SERVICE,
+            WALLPAPER_SERVICE,
+            VIBRATOR_SERVICE,
+            //@hide: STATUS_BAR_SERVICE,
+            CONNECTIVITY_SERVICE,
+            //@hide: UPDATE_LOCK_SERVICE,
+            //@hide: NETWORKMANAGEMENT_SERVICE,
+            //@hide: NETWORK_STATS_SERVICE,
+            //@hide: NETWORK_POLICY_SERVICE,
+            WIFI_SERVICE,
+            WIFI_P2P_SERVICE,
+            NSD_SERVICE,
+            AUDIO_SERVICE,
+            MEDIA_ROUTER_SERVICE,
+            TELEPHONY_SERVICE,
+            CLIPBOARD_SERVICE,
+            INPUT_METHOD_SERVICE,
+            TEXT_SERVICES_MANAGER_SERVICE,
+            //@hide: APPWIDGET_SERVICE,
+            //@hide: BACKUP_SERVICE,
+            DROPBOX_SERVICE,
+            DEVICE_POLICY_SERVICE,
+            UI_MODE_SERVICE,
+            DOWNLOAD_SERVICE,
+            NFC_SERVICE,
+            BLUETOOTH_SERVICE,
+            //@hide: SIP_SERVICE,
+            USB_SERVICE,
+            //@hide: SERIAL_SERVICE,
+            INPUT_SERVICE,
+            DISPLAY_SERVICE,
+            //@hide: SCHEDULING_POLICY_SERVICE,
+            USER_SERVICE,
+            //@hide: APP_OPS_SERVICE
+            CAMERA_SERVICE,
+            PRINT_SERVICE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ServiceName {}
 
     /**
      * Return the handle to a system-level service by name. The class of the
@@ -1995,7 +2080,7 @@
      * @see #DOWNLOAD_SERVICE
      * @see android.app.DownloadManager
      */
-    public abstract Object getSystemService(String name);
+    public abstract Object getSystemService(@ServiceName @NonNull String name);
 
     /**
      * Use with {@link #getSystemService} to retrieve a
@@ -2431,7 +2516,6 @@
      *
      * @see #getSystemService
      * @see android.hardware.camera2.CameraManager
-     * @hide
      */
     public static final String CAMERA_SERVICE = "camera";
 
@@ -2470,7 +2554,8 @@
      * @see PackageManager#checkPermission(String, String)
      * @see #checkCallingPermission
      */
-    public abstract int checkPermission(String permission, int pid, int uid);
+    @PackageManager.PermissionResult
+    public abstract int checkPermission(@NonNull String permission, int pid, int uid);
 
     /**
      * Determine whether the calling process of an IPC you are handling has been
@@ -2493,7 +2578,8 @@
      * @see #checkPermission
      * @see #checkCallingOrSelfPermission
      */
-    public abstract int checkCallingPermission(String permission);
+    @PackageManager.PermissionResult
+    public abstract int checkCallingPermission(@NonNull String permission);
 
     /**
      * Determine whether the calling process of an IPC <em>or you</em> have been
@@ -2511,7 +2597,8 @@
      * @see #checkPermission
      * @see #checkCallingPermission
      */
-    public abstract int checkCallingOrSelfPermission(String permission);
+    @PackageManager.PermissionResult
+    public abstract int checkCallingOrSelfPermission(@NonNull String permission);
 
     /**
      * If the given permission is not allowed for a particular process
@@ -2526,7 +2613,7 @@
      * @see #checkPermission(String, int, int)
      */
     public abstract void enforcePermission(
-            String permission, int pid, int uid, String message);
+            @NonNull String permission, int pid, int uid, @Nullable String message);
 
     /**
      * If the calling process of an IPC you are handling has not been
@@ -2547,7 +2634,7 @@
      * @see #checkCallingPermission(String)
      */
     public abstract void enforceCallingPermission(
-            String permission, String message);
+            @NonNull String permission, @Nullable String message);
 
     /**
      * If neither you nor the calling process of an IPC you are
@@ -2563,7 +2650,7 @@
      * @see #checkCallingOrSelfPermission(String)
      */
     public abstract void enforceCallingOrSelfPermission(
-            String permission, String message);
+            @NonNull String permission, @Nullable String message);
 
     /**
      * Grant permission to access a specific Uri to another package, regardless
@@ -2599,7 +2686,7 @@
      * @see #revokeUriPermission
      */
     public abstract void grantUriPermission(String toPackage, Uri uri,
-            int modeFlags);
+            @Intent.GrantUriMode int modeFlags);
 
     /**
      * Remove all permissions to access a particular content provider Uri
@@ -2618,7 +2705,7 @@
      *
      * @see #grantUriPermission
      */
-    public abstract void revokeUriPermission(Uri uri, int modeFlags);
+    public abstract void revokeUriPermission(Uri uri, @Intent.GrantUriMode int modeFlags);
 
     /**
      * Determine whether a particular process and user ID has been granted
@@ -2641,7 +2728,8 @@
      *
      * @see #checkCallingUriPermission
      */
-    public abstract int checkUriPermission(Uri uri, int pid, int uid, int modeFlags);
+    public abstract int checkUriPermission(Uri uri, int pid, int uid,
+            @Intent.GrantUriMode int modeFlags);
 
     /**
      * Determine whether the calling process and user ID has been
@@ -2664,7 +2752,7 @@
      *
      * @see #checkUriPermission(Uri, int, int, int)
      */
-    public abstract int checkCallingUriPermission(Uri uri, int modeFlags);
+    public abstract int checkCallingUriPermission(Uri uri, @Intent.GrantUriMode int modeFlags);
 
     /**
      * Determine whether the calling process of an IPC <em>or you</em> has been granted
@@ -2683,7 +2771,8 @@
      *
      * @see #checkCallingUriPermission
      */
-    public abstract int checkCallingOrSelfUriPermission(Uri uri, int modeFlags);
+    public abstract int checkCallingOrSelfUriPermission(Uri uri,
+            @Intent.GrantUriMode int modeFlags);
 
     /**
      * Check both a Uri and normal permission.  This allows you to perform
@@ -2695,7 +2784,7 @@
      * @param readPermission The permission that provides overall read access,
      * or null to not do this check.
      * @param writePermission The permission that provides overall write
-     * acess, or null to not do this check.
+     * access, or null to not do this check.
      * @param pid The process ID being checked against.  Must be &gt; 0.
      * @param uid The user ID being checked against.  A uid of 0 is the root
      * user, which will pass every permission check.
@@ -2707,8 +2796,9 @@
      * is allowed to access that uri or holds one of the given permissions, or
      * {@link PackageManager#PERMISSION_DENIED} if it is not.
      */
-    public abstract int checkUriPermission(Uri uri, String readPermission,
-            String writePermission, int pid, int uid, int modeFlags);
+    public abstract int checkUriPermission(@Nullable Uri uri, @Nullable String readPermission,
+            @Nullable String writePermission, int pid, int uid,
+            @Intent.GrantUriMode int modeFlags);
 
     /**
      * If a particular process and user ID has not been granted
@@ -2730,7 +2820,7 @@
      * @see #checkUriPermission(Uri, int, int, int)
      */
     public abstract void enforceUriPermission(
-            Uri uri, int pid, int uid, int modeFlags, String message);
+            Uri uri, int pid, int uid, @Intent.GrantUriMode int modeFlags, String message);
 
     /**
      * If the calling process and user ID has not been granted
@@ -2752,7 +2842,7 @@
      * @see #checkCallingUriPermission(Uri, int)
      */
     public abstract void enforceCallingUriPermission(
-            Uri uri, int modeFlags, String message);
+            Uri uri, @Intent.GrantUriMode int modeFlags, String message);
 
     /**
      * If the calling process of an IPC <em>or you</em> has not been
@@ -2771,7 +2861,7 @@
      * @see #checkCallingOrSelfUriPermission(Uri, int)
      */
     public abstract void enforceCallingOrSelfUriPermission(
-            Uri uri, int modeFlags, String message);
+            Uri uri, @Intent.GrantUriMode int modeFlags, String message);
 
     /**
      * Enforce both a Uri and normal permission.  This allows you to perform
@@ -2783,7 +2873,7 @@
      * @param readPermission The permission that provides overall read access,
      * or null to not do this check.
      * @param writePermission The permission that provides overall write
-     * acess, or null to not do this check.
+     * access, or null to not do this check.
      * @param pid The process ID being checked against.  Must be &gt; 0.
      * @param uid The user ID being checked against.  A uid of 0 is the root
      * user, which will pass every permission check.
@@ -2795,8 +2885,15 @@
      * @see #checkUriPermission(Uri, String, String, int, int, int)
      */
     public abstract void enforceUriPermission(
-            Uri uri, String readPermission, String writePermission,
-            int pid, int uid, int modeFlags, String message);
+            @Nullable Uri uri, @Nullable String readPermission,
+            @Nullable String writePermission, int pid, int uid, @Intent.GrantUriMode int modeFlags,
+            @Nullable String message);
+
+    /** @hide */
+    @IntDef(flag = true,
+            value = {CONTEXT_INCLUDE_CODE, CONTEXT_IGNORE_SECURITY, CONTEXT_RESTRICTED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CreatePackageOptions {}
 
     /**
      * Flag for use with {@link #createPackageContext}: include the application
@@ -2854,7 +2951,7 @@
      * the given package name.
      */
     public abstract Context createPackageContext(String packageName,
-            int flags) throws PackageManager.NameNotFoundException;
+            @CreatePackageOptions int flags) throws PackageManager.NameNotFoundException;
 
     /**
      * Similar to {@link #createPackageContext(String, int)}, but with a
@@ -2890,7 +2987,8 @@
      *
      * @return A {@link Context} with the given configuration override.
      */
-    public abstract Context createConfigurationContext(Configuration overrideConfiguration);
+    public abstract Context createConfigurationContext(
+            @NonNull Configuration overrideConfiguration);
 
     /**
      * Return a new Context object for the current Context but whose resources
@@ -2910,7 +3008,7 @@
      *
      * @return A {@link Context} for the display.
      */
-    public abstract Context createDisplayContext(Display display);
+    public abstract Context createDisplayContext(@NonNull Display display);
 
     /**
      * Gets the display adjustments holder for this context.  This information
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index a708dad..93f6cdf 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -16,9 +16,6 @@
 
 package android.content;
 
-import android.app.Activity;
-import android.app.ActivityManagerNative;
-import android.app.LoadedApk;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
@@ -33,7 +30,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.view.DisplayAdjustments;
 import android.view.Display;
diff --git a/core/java/android/content/CursorLoader.java b/core/java/android/content/CursorLoader.java
index 5d7d677..c78871c 100644
--- a/core/java/android/content/CursorLoader.java
+++ b/core/java/android/content/CursorLoader.java
@@ -16,7 +16,6 @@
 
 package android.content;
 
-import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.CancellationSignal;
diff --git a/core/java/android/content/Entity.java b/core/java/android/content/Entity.java
index 7842de0..607cb3f 100644
--- a/core/java/android/content/Entity.java
+++ b/core/java/android/content/Entity.java
@@ -16,10 +16,7 @@
 
 package android.content;
 
-import android.os.Parcelable;
-import android.os.Parcel;
 import android.net.Uri;
-import android.util.Log;
 
 import java.util.ArrayList;
 
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index 9ad5a19..73a76e8 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -17,6 +17,7 @@
 package android.content;
 
 import android.accounts.Account;
+import android.content.ComponentName;
 import android.content.SyncInfo;
 import android.content.ISyncStatusObserver;
 import android.content.SyncAdapterType;
@@ -55,8 +56,14 @@
             int userHandle);
 
     void requestSync(in Account account, String authority, in Bundle extras);
+    /**
+     * Start a sync given a request.
+     */
     void sync(in SyncRequest request);
-    void cancelSync(in Account account, String authority);
+    void cancelSync(in Account account, String authority, in ComponentName cname);
+
+    /** Cancel a sync, providing information about the sync to be cancelled. */
+     void cancelRequest(in SyncRequest request);
 
     /**
      * Check if the provider should be synced when a network tickle is received
@@ -74,12 +81,14 @@
     void setSyncAutomatically(in Account account, String providerName, boolean sync);
 
     /**
-     * Get the frequency of the periodic poll, if any.
-     * @param providerName the provider whose setting we are querying
-     * @return the frequency of the periodic sync in seconds. If 0 then no periodic syncs
-     * will take place.
+     * Get a list of periodic operations for a specified authority, or service.
+     * @param account account for authority, must be null if cname is non-null.
+     * @param providerName name of provider, must be null if cname is non-null.
+     * @param cname component to identify sync service, must be null if account/providerName are
+     * non-null.
      */
-    List<PeriodicSync> getPeriodicSyncs(in Account account, String providerName);
+    List<PeriodicSync> getPeriodicSyncs(in Account account, String providerName,
+        in ComponentName cname);
 
     /**
      * Set whether or not the provider is to be synced on a periodic basis.
@@ -112,16 +121,23 @@
      */
     void setIsSyncable(in Account account, String providerName, int syncable);
 
+    /**
+     * Corresponds roughly to setIsSyncable(String account, String provider) for syncs that bind
+     * to a SyncService.
+     */
+    void setServiceActive(in ComponentName cname, boolean active);
+
+    /**
+     * Corresponds roughly to getIsSyncable(String account, String provider) for syncs that bind
+     * to a SyncService.
+     * @return 0 if this SyncService is not enabled, 1 if enabled, <0 if unknown.
+     */
+    boolean isServiceActive(in ComponentName cname);
+
     void setMasterSyncAutomatically(boolean flag);
 
     boolean getMasterSyncAutomatically();
 
-    /**
-     * Returns true if there is currently a sync operation for the given
-     * account or authority in the pending list, or actively being processed.
-     */
-    boolean isSyncActive(in Account account, String authority);
-
     List<SyncInfo> getCurrentSyncs();
 
     /**
@@ -131,17 +147,33 @@
     SyncAdapterType[] getSyncAdapterTypes();
 
     /**
+     * Returns true if there is currently a operation for the given account/authority or service
+     * actively being processed.
+     * @param account account for authority, must be null if cname is non-null.
+     * @param providerName name of provider, must be null if cname is non-null.
+     * @param cname component to identify sync service, must be null if account/providerName are
+     * non-null.
+     */
+    boolean isSyncActive(in Account account, String authority, in ComponentName cname);
+
+    /**
      * Returns the status that matches the authority. If there are multiples accounts for
      * the authority, the one with the latest "lastSuccessTime" status is returned.
-     * @param authority the authority whose row should be selected
-     * @return the SyncStatusInfo for the authority, or null if none exists
+     * @param account account for authority, must be null if cname is non-null.
+     * @param providerName name of provider, must be null if cname is non-null.
+     * @param cname component to identify sync service, must be null if account/providerName are
+     * non-null.
      */
-    SyncStatusInfo getSyncStatus(in Account account, String authority);
+    SyncStatusInfo getSyncStatus(in Account account, String authority, in ComponentName cname);
 
     /**
      * Return true if the pending status is true of any matching authorities.
+     * @param account account for authority, must be null if cname is non-null.
+     * @param providerName name of provider, must be null if cname is non-null.
+     * @param cname component to identify sync service, must be null if account/providerName are
+     * non-null.
      */
-    boolean isSyncPending(in Account account, String authority);
+    boolean isSyncPending(in Account account, String authority, in ComponentName cname);
 
     void addStatusChangeListener(int mask, ISyncStatusObserver callback);
 
diff --git a/core/java/android/content/IAnonymousSyncAdapter.aidl b/core/java/android/content/ISyncServiceAdapter.aidl
similarity index 97%
rename from core/java/android/content/IAnonymousSyncAdapter.aidl
rename to core/java/android/content/ISyncServiceAdapter.aidl
index a80cea3..d419307 100644
--- a/core/java/android/content/IAnonymousSyncAdapter.aidl
+++ b/core/java/android/content/ISyncServiceAdapter.aidl
@@ -24,7 +24,7 @@
  * Provider specified). See {@link android.content.AbstractThreadedSyncAdapter}.
  * {@hide}
  */
-oneway interface IAnonymousSyncAdapter {
+oneway interface ISyncServiceAdapter {
 
     /**
      * Initiate a sync. SyncAdapter-specific parameters may be specified in
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index a289649..ba7db76 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -21,6 +21,7 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.annotation.IntDef;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.pm.ActivityInfo;
@@ -45,6 +46,8 @@
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
@@ -3335,6 +3338,12 @@
     // ---------------------------------------------------------------------
     // Intent flags (see mFlags variable).
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface GrantUriMode {}
+
     /**
      * If set, the recipient of this Intent will be granted permission to
      * perform read operations on the URI in the Intent's data and any URIs
@@ -4415,7 +4424,7 @@
      * Return the {@link ClipData} associated with this Intent.  If there is
      * none, returns null.  See {@link #setClipData} for more information.
      *
-     * @see #setClipData;
+     * @see #setClipData
      */
     public ClipData getClipData() {
         return mClipData;
@@ -6374,6 +6383,21 @@
         }
     }
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                    FILL_IN_ACTION,
+                    FILL_IN_DATA,
+                    FILL_IN_CATEGORIES,
+                    FILL_IN_COMPONENT,
+                    FILL_IN_PACKAGE,
+                    FILL_IN_SOURCE_BOUNDS,
+                    FILL_IN_SELECTOR,
+                    FILL_IN_CLIP_DATA
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FillInFlags {}
+
     /**
      * Use with {@link #fillIn} to allow the current action value to be
      * overwritten, even if it is already set.
@@ -6467,10 +6491,12 @@
      *
      * @return Returns a bit mask of {@link #FILL_IN_ACTION},
      * {@link #FILL_IN_DATA}, {@link #FILL_IN_CATEGORIES}, {@link #FILL_IN_PACKAGE},
-     * {@link #FILL_IN_COMPONENT}, {@link #FILL_IN_SOURCE_BOUNDS}, and
-     * {@link #FILL_IN_SELECTOR} indicating which fields were changed.
+     * {@link #FILL_IN_COMPONENT}, {@link #FILL_IN_SOURCE_BOUNDS},
+     * {@link #FILL_IN_SELECTOR} and {@link #FILL_IN_CLIP_DATA indicating which fields were
+     * changed.
      */
-    public int fillIn(Intent other, int flags) {
+    @FillInFlags
+    public int fillIn(Intent other, @FillInFlags int flags) {
         int changes = 0;
         if (other.mAction != null
                 && (mAction == null || (flags&FILL_IN_ACTION) != 0)) {
@@ -7153,8 +7179,8 @@
      *
      * @param type MIME data type to normalize
      * @return normalized MIME data type, or null if the input was null
-     * @see {@link #setType}
-     * @see {@link #setTypeAndNormalize}
+     * @see #setType
+     * @see #setTypeAndNormalize
      */
     public static String normalizeMimeType(String type) {
         if (type == null) {
diff --git a/core/java/android/content/Loader.java b/core/java/android/content/Loader.java
index 911e49c..f3828b0 100644
--- a/core/java/android/content/Loader.java
+++ b/core/java/android/content/Loader.java
@@ -413,7 +413,7 @@
      * {@link #onReset()} happens.  You can retrieve the current abandoned
      * state with {@link #isAbandoned}.
      */
-    protected void onAbandon() {        
+    protected void onAbandon() {
     }
     
     /**
diff --git a/core/java/android/content/PeriodicSync.java b/core/java/android/content/PeriodicSync.java
index b586eec..836c6f8 100644
--- a/core/java/android/content/PeriodicSync.java
+++ b/core/java/android/content/PeriodicSync.java
@@ -29,13 +29,17 @@
     public final Account account;
     /** The authority of the sync. Can be null. */
     public final String authority;
+    /** The service for syncing, if this is an anonymous sync. Can be null.*/
+    public final ComponentName service;
     /** Any extras that parameters that are to be passed to the sync adapter. */
     public final Bundle extras;
     /** How frequently the sync should be scheduled, in seconds. Kept around for API purposes. */
     public final long period;
+    /** Whether this periodic sync runs on a {@link SyncService}. */
+    public final boolean isService;
     /**
-     * {@hide}
      * How much flexibility can be taken in scheduling the sync, in seconds.
+     * {@hide}
      */
     public final long flexTime;
 
@@ -48,44 +52,74 @@
     public PeriodicSync(Account account, String authority, Bundle extras, long periodInSeconds) {
         this.account = account;
         this.authority = authority;
+        this.service = null;
+        this.isService = false;
         if (extras == null) {
             this.extras = new Bundle();
         } else {
             this.extras = new Bundle(extras);
         }
         this.period = periodInSeconds;
-        // Initialise to a sane value.
+        // Old API uses default flex time. No-one should be using this ctor anyway.
         this.flexTime = 0L;
     }
 
     /**
-     * {@hide}
      * Create a copy of a periodic sync.
+     * {@hide}
      */
     public PeriodicSync(PeriodicSync other) {
         this.account = other.account;
         this.authority = other.authority;
+        this.service = other.service;
+        this.isService = other.isService;
         this.extras = new Bundle(other.extras);
         this.period = other.period;
         this.flexTime = other.flexTime;
     }
 
     /**
-     * {@hide}
      * A PeriodicSync for a sync with a specified provider.
+     * {@hide}
      */
     public PeriodicSync(Account account, String authority, Bundle extras,
             long period, long flexTime) {
         this.account = account;
         this.authority = authority;
+        this.service = null;
+        this.isService = false;
+        this.extras = new Bundle(extras);
+        this.period = period;
+        this.flexTime = flexTime;
+    }
+
+    /**
+     * A PeriodicSync for a sync with a specified SyncService.
+     * {@hide}
+     */
+    public PeriodicSync(ComponentName service, Bundle extras,
+            long period,
+            long flexTime) {
+        this.account = null;
+        this.authority = null;
+        this.service = service;
+        this.isService = true;
         this.extras = new Bundle(extras);
         this.period = period;
         this.flexTime = flexTime;
     }
 
     private PeriodicSync(Parcel in) {
-        this.account = in.readParcelable(null);
-        this.authority = in.readString();
+        this.isService = (in.readInt() != 0);
+        if (this.isService) {
+            this.service = in.readParcelable(null);
+            this.account = null;
+            this.authority = null;
+        } else {
+            this.account = in.readParcelable(null);
+            this.authority = in.readString();
+            this.service = null;
+        }
         this.extras = in.readBundle();
         this.period = in.readLong();
         this.flexTime = in.readLong();
@@ -98,8 +132,13 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeParcelable(account, flags);
-        dest.writeString(authority);
+        dest.writeInt(isService ? 1 : 0);
+        if (account == null && authority == null) {
+            dest.writeParcelable(service, flags);
+        } else {
+            dest.writeParcelable(account, flags);
+            dest.writeString(authority);
+        }
         dest.writeBundle(extras);
         dest.writeLong(period);
         dest.writeLong(flexTime);
@@ -126,14 +165,24 @@
             return false;
         }
         final PeriodicSync other = (PeriodicSync) o;
-        return account.equals(other.account)
-            && authority.equals(other.authority)
+        if (this.isService != other.isService) {
+            return false;
+        }
+        boolean equal = false;
+        if (this.isService) {
+            equal = service.equals(other.service);
+        } else {
+            equal = account.equals(other.account)
+                    && authority.equals(other.authority);
+        }
+        return equal
             && period == other.period
             && syncExtrasEquals(extras, other.extras);
     }
 
     /**
-     * Periodic sync extra comparison function.
+     * Periodic sync extra comparison function. Duplicated from
+     * {@link com.android.server.content.SyncManager#syncExtrasEquals(Bundle b1, Bundle b2)}
      * {@hide}
      */
     public static boolean syncExtrasEquals(Bundle b1, Bundle b2) {
@@ -158,6 +207,7 @@
     public String toString() {
         return "account: " + account +
                ", authority: " + authority +
+               ", service: " + service +
                ". period: " + period + "s " +
                ", flex: " + flexTime;
     }
diff --git a/core/java/android/content/RestrictionEntry.java b/core/java/android/content/RestrictionEntry.java
index 283a097..3ff53bf 100644
--- a/core/java/android/content/RestrictionEntry.java
+++ b/core/java/android/content/RestrictionEntry.java
@@ -19,8 +19,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import java.lang.annotation.Inherited;
-
 /**
  * Applications can expose restrictions for a restricted user on a
  * multiuser device. The administrator can configure these restrictions that will then be
diff --git a/core/java/android/content/SyncInfo.java b/core/java/android/content/SyncInfo.java
index cffc653..146dd99 100644
--- a/core/java/android/content/SyncInfo.java
+++ b/core/java/android/content/SyncInfo.java
@@ -19,7 +19,6 @@
 import android.accounts.Account;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Parcelable.Creator;
 
 /**
  * Information about the sync operation that is currently underway.
@@ -29,16 +28,24 @@
     public final int authorityId;
 
     /**
-     * The {@link Account} that is currently being synced.
+     * The {@link Account} that is currently being synced. Will be null if this sync is running via
+     * a {@link SyncService}.
      */
     public final Account account;
 
     /**
-     * The authority of the provider that is currently being synced.
+     * The authority of the provider that is currently being synced. Will be null if this sync
+     * is running via a {@link SyncService}.
      */
     public final String authority;
 
     /**
+     * The {@link SyncService} that is targeted by this operation. Null if this sync is running via
+     * a {@link AbstractThreadedSyncAdapter}. 
+     */
+    public final ComponentName service;
+
+    /**
      * The start time of the current sync operation in milliseconds since boot.
      * This is represented in elapsed real time.
      * See {@link android.os.SystemClock#elapsedRealtime()}.
@@ -46,12 +53,13 @@
     public final long startTime;
 
     /** @hide */
-    public SyncInfo(int authorityId, Account account, String authority,
+    public SyncInfo(int authorityId, Account account, String authority, ComponentName service,
             long startTime) {
         this.authorityId = authorityId;
         this.account = account;
         this.authority = authority;
         this.startTime = startTime;
+        this.service = service;
     }
 
     /** @hide */
@@ -60,6 +68,7 @@
         this.account = new Account(other.account.name, other.account.type);
         this.authority = other.authority;
         this.startTime = other.startTime;
+        this.service = other.service;
     }
 
     /** @hide */
@@ -70,17 +79,20 @@
     /** @hide */
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(authorityId);
-        account.writeToParcel(parcel, 0);
+        parcel.writeParcelable(account, flags);
         parcel.writeString(authority);
         parcel.writeLong(startTime);
+        parcel.writeParcelable(service, flags);
+        
     }
 
     /** @hide */
     SyncInfo(Parcel parcel) {
         authorityId = parcel.readInt();
-        account = new Account(parcel);
+        account = parcel.readParcelable(Account.class.getClassLoader());
         authority = parcel.readString();
         startTime = parcel.readLong();
+        service = parcel.readParcelable(ComponentName.class.getClassLoader());
     }
 
     /** @hide */
diff --git a/core/java/android/content/SyncRequest.java b/core/java/android/content/SyncRequest.java
index 6ca283d..a9a62a7 100644
--- a/core/java/android/content/SyncRequest.java
+++ b/core/java/android/content/SyncRequest.java
@@ -23,15 +23,15 @@
 
 public class SyncRequest implements Parcelable {
     private static final String TAG = "SyncRequest";
-    /** Account to pass to the sync adapter. May be null. */
+    /** Account to pass to the sync adapter. Can be null. */
     private final Account mAccountToSync;
     /** Authority string that corresponds to a ContentProvider. */
     private final String mAuthority;
-    /** Sync service identifier. May be null.*/
+    /** {@link SyncService} identifier. */
     private final ComponentName mComponentInfo;
     /** Bundle containing user info as well as sync settings. */
     private final Bundle mExtras;
-    /** Disallow this sync request on metered networks. */
+    /** Don't allow this sync request on metered networks. */
     private final boolean mDisallowMetered;
     /**
      * Anticipated upload size in bytes.
@@ -69,18 +69,14 @@
         return mIsPeriodic;
     }
 
-    /**
-     * {@hide}
-     * @return whether this is an expedited sync.
-     */
     public boolean isExpedited() {
         return mIsExpedited;
     }
 
     /**
      * {@hide}
-     * @return true if this sync uses an account/authority pair, or false if this sync is bound to
-     * a Sync Service.
+     * @return true if this sync uses an account/authority pair, or false if
+     *         this is an anonymous sync bound to an @link AnonymousSyncService.
      */
     public boolean hasAuthority() {
         return mIsAuthority;
@@ -88,34 +84,51 @@
 
     /**
      * {@hide}
+     *
      * @return account object for this sync.
-     * @throws IllegalArgumentException if this function is called for a request that does not
-     * specify an account/provider authority.
+     * @throws IllegalArgumentException if this function is called for a request that targets a
+     * sync service.
      */
     public Account getAccount() {
         if (!hasAuthority()) {
-            throw new IllegalArgumentException("Cannot getAccount() for a sync that does not"
-                    + "specify an authority.");
+            throw new IllegalArgumentException("Cannot getAccount() for a sync that targets a sync"
+                    + "service.");
         }
         return mAccountToSync;
     }
 
     /**
      * {@hide}
+     *
      * @return provider for this sync.
-     * @throws IllegalArgumentException if this function is called for a request that does not
-     * specify an account/provider authority.
+     * @throws IllegalArgumentException if this function is called for a request that targets a
+     * sync service.
      */
     public String getProvider() {
         if (!hasAuthority()) {
-            throw new IllegalArgumentException("Cannot getProvider() for a sync that does not"
-                    + "specify a provider.");
+            throw new IllegalArgumentException("Cannot getProvider() for a sync that targets a"
+                    + "sync service.");
         }
         return mAuthority;
     }
 
     /**
      * {@hide}
+     * Throws a runtime IllegalArgumentException if this function is called for a
+     * SyncRequest that is bound to an account/provider.
+     *
+     * @return ComponentName for the service that this sync will bind to.
+     */
+    public ComponentName getService() {
+        if (hasAuthority()) {
+            throw new IllegalArgumentException(
+                    "Cannot getAnonymousService() for a sync that has specified a provider.");
+        }
+        return mComponentInfo;
+    }
+
+    /**
+     * {@hide}
      * Retrieve bundle for this SyncRequest. Will not be null.
      */
     public Bundle getBundle() {
@@ -129,7 +142,6 @@
     public long getSyncFlexTime() {
         return mSyncFlexTimeSecs;
     }
-
     /**
      * {@hide}
      * @return the last point in time at which this sync must scheduled.
@@ -216,7 +228,7 @@
     }
 
     /**
-     * Builder class for a {@link SyncRequest}. As you build your SyncRequest this class will also
+     * Builder class for a @link SyncRequest. As you build your SyncRequest this class will also
      * perform validation.
      */
     public static class Builder {
@@ -232,9 +244,12 @@
         private static final int SYNC_TARGET_SERVICE = 1;
         /** Specify that this is a sync with a provider. */
         private static final int SYNC_TARGET_ADAPTER = 2;
-        /** Earliest point of displacement into the future at which this sync can occur. */
+        /**
+         * Earliest point of displacement into the future at which this sync can
+         * occur.
+         */
         private long mSyncFlexTimeSecs;
-        /** Latest point of displacement into the future at which this sync must occur. */
+        /** Displacement into the future at which this sync must occur. */
         private long mSyncRunTimeSecs;
         /**
          * Sync configuration information - custom user data explicitly provided by the developer.
@@ -283,8 +298,9 @@
         private boolean mExpedited;
 
         /**
-         * The sync component that contains the sync logic if this is a provider-less sync,
-         * otherwise null.
+         * The {@link SyncService} component that
+         * contains the sync logic if this is a provider-less sync, otherwise
+         * null.
          */
         private ComponentName mComponentName;
         /**
@@ -320,11 +336,15 @@
 
         /**
          * Build a periodic sync. Either this or syncOnce() <b>must</b> be called for this builder.
-         * Syncs are identified by target {@link android.provider}/{@link android.accounts.Account}
-         * and by the contents of the extras bundle.
-         * You cannot reuse the same builder for one-time syncs (by calling this function) after
-         * having specified a periodic sync. If you do, an <code>IllegalArgumentException</code>
+         * Syncs are identified by target {@link SyncService}/{@link android.provider} and by the
+         * contents of the extras bundle.
+         * You cannot reuse the same builder for one-time syncs after having specified a periodic
+         * sync (by calling this function). If you do, an <code>IllegalArgumentException</code>
          * will be thrown.
+         * <p>The bundle for a periodic sync can be queried by applications with the correct
+         * permissions using
+         * {@link ContentResolver#getPeriodicSyncs(Account account, String provider)}, so no
+         * sensitive data should be transferred here.
          *
          * Example usage.
          *
@@ -375,7 +395,6 @@
         }
 
         /**
-         * {@hide}
          * Developer can provide insight into their payload size; optional. -1 specifies unknown,
          * so that you are not restricted to defining both fields.
          *
@@ -389,20 +408,28 @@
         }
 
         /**
-         * @see android.net.ConnectivityManager#isActiveNetworkMetered()
-         * @param disallow true to enforce that this transfer not occur on metered networks.
-         *                 Default false.
+         * Will throw an <code>IllegalArgumentException</code> if called and
+         * {@link #setIgnoreSettings(boolean ignoreSettings)} has already been called.
+         * @param disallow true to allow this transfer on metered networks. Default false.
+         * 
          */
         public Builder setDisallowMetered(boolean disallow) {
+            if (mIgnoreSettings && disallow) {
+                throw new IllegalArgumentException("setDisallowMetered(true) after having"
+                        + "specified that settings are ignored.");
+            }
             mDisallowMetered = disallow;
             return this;
         }
 
         /**
-         * Specify an authority and account for this transfer.
+         * Specify an authority and account for this transfer. Cannot be used with
+         * {@link #setSyncAdapter(ComponentName cname)}.
          *
-         * @param authority String identifying which content provider to sync.
-         * @param account Account to sync. Can be null unless this is a periodic sync.
+         * @param authority
+         * @param account Account to sync. Can be null unless this is a periodic
+         *            sync, for which verification by the ContentResolver will
+         *            fail. If a sync is performed without an account, the
          */
         public Builder setSyncAdapter(Account account, String authority) {
             if (mSyncTarget != SYNC_TARGET_UNKNOWN) {
@@ -419,10 +446,26 @@
         }
 
         /**
-         * Optional developer-provided extras handed back in
-         * {@link AbstractThreadedSyncAdapter#onPerformSync(Account, Bundle, String,
-         * ContentProviderClient, SyncResult)} occurs. This bundle is copied into the SyncRequest
-         * returned by {@link #build()}.
+         * Specify the {@link SyncService} component for this sync. This is not validated until
+         * sync time so providing an incorrect component name here will not fail. Cannot be used
+         * with {@link #setSyncAdapter(Account account, String authority)}.
+         *
+         * @param cname ComponentName to identify your Anonymous service
+         */
+        public Builder setSyncAdapter(ComponentName cname) {
+            if (mSyncTarget != SYNC_TARGET_UNKNOWN) {
+                throw new IllegalArgumentException("Sync target has already been defined.");
+            }
+            mSyncTarget = SYNC_TARGET_SERVICE;
+            mComponentName = cname;
+            mAccount = null;
+            mAuthority = null;
+            return this;
+        }
+
+        /**
+         * Developer-provided extras handed back when sync actually occurs. This bundle is copied
+         * into the SyncRequest returned by {@link #build()}.
          *
          * Example:
          * <pre>
@@ -436,7 +479,7 @@
          *     Bundle extras = new Bundle();
          *     extras.setString("data", syncData);
          *     builder.setExtras(extras);
-         *     ContentResolver.sync(builder.build()); // Each sync() request is for a unique sync.
+         *     ContentResolver.sync(builder.build()); // Each sync() request creates a unique sync.
          *   }
          * </pre>
          * Only values of the following types may be used in the extras bundle:
@@ -477,13 +520,19 @@
         /**
          * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_SETTINGS}.
          *
-         * A sync can specify that system sync settings be ignored (user has turned sync off). Not
-         * valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
+         * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
          * {@link #build()}.
+         * <p>Throws <code>IllegalArgumentException</code> if called and
+         * {@link #setDisallowMetered(boolean)} has been set.
+         * 
          *
          * @param ignoreSettings true to ignore the sync automatically settings. Default false.
          */
         public Builder setIgnoreSettings(boolean ignoreSettings) {
+            if (mDisallowMetered && ignoreSettings) {
+                throw new IllegalArgumentException("setIgnoreSettings(true) after having specified"
+                        + " sync settings with this builder.");
+            }
             mIgnoreSettings = ignoreSettings;
             return this;
         }
@@ -491,13 +540,13 @@
         /**
          * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF}.
          *
-         * Force the sync scheduling process to ignore any back-off that was the result of a failed
-         * sync, as well as to invalidate any {@link SyncResult#delayUntil} value that may have
-         * been set by the adapter. Successive failures will not honor this flag. Not valid for
-         * periodic sync and will throw an <code>IllegalArgumentException</code> in
-         * {@link #build()}.
+         * Ignoring back-off will force the sync scheduling process to ignore any back-off that was
+         * the result of a failed sync, as well as to invalidate any {@link SyncResult#delayUntil}
+         * value that may have been set by the adapter. Successive failures will not honor this
+         * flag. Not valid for periodic sync and will throw an <code>IllegalArgumentException</code>
+         * in {@link #build()}.
          *
-         * @param ignoreBackoff ignore back-off settings. Default false.
+         * @param ignoreBackoff ignore back off settings. Default false.
          */
         public Builder setIgnoreBackoff(boolean ignoreBackoff) {
             mIgnoreBackoff = ignoreBackoff;
@@ -507,9 +556,8 @@
         /**
          * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_MANUAL}.
          *
-         * A manual sync is functionally equivalent to calling {@link #setIgnoreBackoff(boolean)}
-         * and {@link #setIgnoreSettings(boolean)}. Not valid for periodic sync and will throw an
-         * <code>IllegalArgumentException</code> in {@link #build()}.
+         * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
+         * {@link #build()}.
          *
          * @param isManual User-initiated sync or not. Default false.
          */
@@ -519,7 +567,7 @@
         }
 
         /**
-         * An expedited sync runs immediately and will preempt another non-expedited running sync.
+         * An expedited sync runs immediately and can preempt other non-expedited running syncs.
          *
          * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
          * {@link #build()}.
@@ -532,7 +580,6 @@
         }
 
         /**
-         * {@hide}
          * @param priority the priority of this request among all requests from the calling app.
          * Range of [-2,2] similar to how this is done with notifications.
          */
@@ -552,11 +599,11 @@
          *         builder.
          */
         public SyncRequest build() {
+            // Validate the extras bundle
+            ContentResolver.validateSyncExtrasBundle(mCustomExtras);
             if (mCustomExtras == null) {
                 mCustomExtras = new Bundle();
             }
-            // Validate the extras bundle
-            ContentResolver.validateSyncExtrasBundle(mCustomExtras);
             // Combine builder extra flags into the config bundle.
             mSyncConfigExtras = new Bundle();
             if (mIgnoreBackoff) {
@@ -575,51 +622,33 @@
                 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
             }
             if (mIsManual) {
-                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
             }
             mSyncConfigExtras.putLong(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD, mTxBytes);
             mSyncConfigExtras.putLong(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD, mRxBytes);
             mSyncConfigExtras.putInt(ContentResolver.SYNC_EXTRAS_PRIORITY, mPriority);
             if (mSyncType == SYNC_TYPE_PERIODIC) {
                 // If this is a periodic sync ensure than invalid extras were not set.
-                validatePeriodicExtras(mCustomExtras);
-                validatePeriodicExtras(mSyncConfigExtras);
-                // Verify that account and provider are not null.
-                if (mAccount == null) {
-                    throw new IllegalArgumentException("Account must not be null for periodic"
-                            + " sync.");
-                }
-                if (mAuthority == null) {
-                    throw new IllegalArgumentException("Authority must not be null for periodic"
-                            + " sync.");
+                if (ContentResolver.invalidPeriodicExtras(mCustomExtras) || 
+                        ContentResolver.invalidPeriodicExtras(mSyncConfigExtras)) {
+                    throw new IllegalArgumentException("Illegal extras were set");
                 }
             } else if (mSyncType == SYNC_TYPE_UNKNOWN) {
                 throw new IllegalArgumentException("Must call either syncOnce() or syncPeriodic()");
             }
+            if (mSyncTarget == SYNC_TARGET_SERVICE) {
+                if (mSyncConfigExtras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)) {
+                    throw new IllegalArgumentException("Cannot specify an initialisation sync"
+                            + " that targets a service.");
+                }
+            }
             // Ensure that a target for the sync has been set.
             if (mSyncTarget == SYNC_TARGET_UNKNOWN) {
-                throw new IllegalArgumentException("Must specify an adapter with "
-                        + "setSyncAdapter(Account, String");
+                throw new IllegalArgumentException("Must specify an adapter with one of"
+                    + "setSyncAdapter(ComponentName) or setSyncAdapter(Account, String");
             }
             return new SyncRequest(this);
         }
-
-        /**
-         * Helper function to throw an <code>IllegalArgumentException</code> if any illegal
-         * extras were set for a periodic sync.
-         *
-         * @param extras bundle to validate.
-         */
-        private void validatePeriodicExtras(Bundle extras) {
-            if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)
-                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)
-                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false)
-                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
-                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)
-                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false)
-                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
-                throw new IllegalArgumentException("Illegal extras were set");
-            }
-        }
-    }
+    }   
 }
diff --git a/core/java/android/content/SyncService.java b/core/java/android/content/SyncService.java
new file mode 100644
index 0000000..4df998c
--- /dev/null
+++ b/core/java/android/content/SyncService.java
@@ -0,0 +1,211 @@
+/*
+ * 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.content;
+
+import android.app.Service;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.Trace;
+import android.util.SparseArray;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+/**
+ * Simplified @link android.content.AbstractThreadedSyncAdapter. Folds that
+ * behaviour into a service to which the system can bind when requesting an
+ * anonymous (providerless/accountless) sync.
+ * <p>
+ * In order to perform an anonymous sync operation you must extend this service, implementing the
+ * abstract methods. This service must be declared in the application's manifest as usual. You
+ * can use this service for other work, however you <b> must not </b> override the onBind() method
+ * unless you know what you're doing, which limits the usefulness of this service for other work.
+ * <p>A {@link SyncService} can either be active or inactive. Different to an
+ * {@link AbstractThreadedSyncAdapter}, there is no
+ * {@link ContentResolver#setSyncAutomatically(android.accounts.Account account, String provider, boolean sync)},
+ * as well as no concept of initialisation (you can handle your own if needed).
+ *
+ * <pre>
+ * &lt;service android:name=".MySyncService"/&gt;
+ * </pre>
+ * Like @link android.content.AbstractThreadedSyncAdapter this service supports
+ * multiple syncs at the same time. Each incoming startSync() with a unique tag
+ * will spawn a thread to do the work of that sync. If startSync() is called
+ * with a tag that already exists, a SyncResult.ALREADY_IN_PROGRESS is returned.
+ * Remember that your service will spawn multiple threads if you schedule multiple syncs
+ * at once, so if you mutate local objects you must ensure synchronization.
+ */
+public abstract class SyncService extends Service {
+    private static final String TAG = "SyncService";
+
+    private final SyncAdapterImpl mSyncAdapter = new SyncAdapterImpl();
+
+    /** Keep track of on-going syncs, keyed by bundle. */
+    @GuardedBy("mSyncThreadLock")
+    private final SparseArray<SyncThread>
+            mSyncThreads = new SparseArray<SyncThread>();
+    /** Lock object for accessing the SyncThreads HashMap. */
+    private final Object mSyncThreadLock = new Object();
+    /**
+     * Default key for if this sync service does not support parallel operations. Currently not
+     * sure if null keys will make it into the ArrayMap for KLP, so keeping our default for now.
+     */
+    private static final int KEY_DEFAULT = 0;
+    /** Identifier for this sync service. */
+    private ComponentName mServiceComponent;
+
+    /** {@hide} */
+    public IBinder onBind(Intent intent) {
+        mServiceComponent = new ComponentName(this, getClass());
+        return mSyncAdapter.asBinder();
+    }
+
+    /** {@hide} */
+    private class SyncAdapterImpl extends ISyncServiceAdapter.Stub {
+        @Override
+        public void startSync(ISyncContext syncContext, Bundle extras) {
+            // Wrap the provided Sync Context because it may go away by the time
+            // we call it.
+            final SyncContext syncContextClient = new SyncContext(syncContext);
+            boolean alreadyInProgress = false;
+            final int extrasAsKey = extrasToKey(extras);
+            synchronized (mSyncThreadLock) {
+                if (mSyncThreads.get(extrasAsKey) == null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, "starting sync for : " + mServiceComponent);
+                    }
+                    // Start sync.
+                    SyncThread syncThread = new SyncThread(syncContextClient, extras);
+                    mSyncThreads.put(extrasAsKey, syncThread);
+                    syncThread.start();
+                } else {
+                    // Don't want to call back to SyncManager while still
+                    // holding lock.
+                    alreadyInProgress = true;
+                }
+            }
+            if (alreadyInProgress) {
+                syncContextClient.onFinished(SyncResult.ALREADY_IN_PROGRESS);
+            }
+        }
+
+        /**
+         * Used by the SM to cancel a specific sync using the
+         * com.android.server.content.SyncManager.ActiveSyncContext as a handle.
+         */
+        @Override
+        public void cancelSync(ISyncContext syncContext) {
+            SyncThread runningSync = null;
+            synchronized (mSyncThreadLock) {
+                for (int i = 0; i < mSyncThreads.size(); i++) {
+                    SyncThread thread = mSyncThreads.valueAt(i);
+                    if (thread.mSyncContext.getSyncContextBinder() == syncContext.asBinder()) {
+                        runningSync = thread;
+                        break;
+                    }
+                }
+            }
+            if (runningSync != null) {
+                runningSync.interrupt();
+            }
+        }
+    }
+
+    /**
+     * 
+     * @param extras Bundle for which to compute hash
+     * @return an integer hash that is equal to that of another bundle if they both contain the
+     * same key -> value mappings, however, not necessarily in order.
+     * Based on the toString() representation of the value mapped.
+     */
+    private int extrasToKey(Bundle extras) {
+        int hash = KEY_DEFAULT; // Empty bundle, or no parallel operations enabled.
+        if (parallelSyncsEnabled()) {
+            for (String key : extras.keySet()) {
+                String mapping = key + " " + extras.get(key).toString();
+                hash += mapping.hashCode();
+            }
+        }
+        return hash;
+    }
+
+    /**
+     * {@hide}
+     * Similar to {@link android.content.AbstractThreadedSyncAdapter.SyncThread}. However while
+     * the ATSA considers an already in-progress sync to be if the account provided is currently
+     * syncing, this anonymous sync has no notion of account and considers a sync unique if the
+     * provided bundle is different.
+     */
+    private class SyncThread extends Thread {
+        private final SyncContext mSyncContext;
+        private final Bundle mExtras;
+        private final int mThreadsKey;
+
+        public SyncThread(SyncContext syncContext, Bundle extras) {
+            mSyncContext = syncContext;
+            mExtras = extras;
+            mThreadsKey = extrasToKey(extras);
+        }
+
+        @Override
+        public void run() {
+            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+
+            Trace.traceBegin(Trace.TRACE_TAG_SYNC_MANAGER, getApplication().getPackageName());
+
+            SyncResult syncResult = new SyncResult();
+            try {
+                if (isCancelled()) return;
+                // Run the sync.
+                SyncService.this.onPerformSync(mExtras, syncResult);
+            } finally {
+                Trace.traceEnd(Trace.TRACE_TAG_SYNC_MANAGER);
+                if (!isCancelled()) {
+                    mSyncContext.onFinished(syncResult);
+                }
+                // Synchronize so that the assignment will be seen by other
+                // threads that also synchronize accesses to mSyncThreads.
+                synchronized (mSyncThreadLock) {
+                    mSyncThreads.remove(mThreadsKey);
+                }
+            }
+        }
+
+        private boolean isCancelled() {
+            return Thread.currentThread().isInterrupted();
+        }
+    }
+
+    /**
+     * Initiate an anonymous sync using this service. SyncAdapter-specific
+     * parameters may be specified in extras, which is guaranteed to not be
+     * null.
+     */
+    public abstract void onPerformSync(Bundle extras, SyncResult syncResult);
+
+    /**
+     * Override this function to indicated whether you want to support parallel syncs.
+     * <p>If you override and return true multiple threads will be spawned within your Service to
+     * handle each concurrent sync request.
+     *
+     * @return false to indicate that this service does not support parallel operations by default.
+     */
+    protected boolean parallelSyncsEnabled() {
+        return false;
+    }
+}
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index b8ac3bf..40275d8 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -16,11 +16,15 @@
 
 package android.content.pm;
 
+import android.annotation.IntDef;
 import android.content.res.Configuration;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Printer;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Information you can retrieve about a particular application
  * activity or receiver. This corresponds to information collected
@@ -212,6 +216,28 @@
      */
     public int flags;
 
+    /** @hide */
+    @IntDef({
+            SCREEN_ORIENTATION_UNSPECIFIED,
+            SCREEN_ORIENTATION_LANDSCAPE,
+            SCREEN_ORIENTATION_PORTRAIT,
+            SCREEN_ORIENTATION_USER,
+            SCREEN_ORIENTATION_BEHIND,
+            SCREEN_ORIENTATION_SENSOR,
+            SCREEN_ORIENTATION_NOSENSOR,
+            SCREEN_ORIENTATION_SENSOR_LANDSCAPE,
+            SCREEN_ORIENTATION_SENSOR_PORTRAIT,
+            SCREEN_ORIENTATION_REVERSE_LANDSCAPE,
+            SCREEN_ORIENTATION_REVERSE_PORTRAIT,
+            SCREEN_ORIENTATION_FULL_SENSOR,
+            SCREEN_ORIENTATION_USER_LANDSCAPE,
+            SCREEN_ORIENTATION_USER_PORTRAIT,
+            SCREEN_ORIENTATION_FULL_USER,
+            SCREEN_ORIENTATION_LOCKED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScreenOrientation {}
+
     /**
      * Constant corresponding to <code>unspecified</code> in
      * the {@link android.R.attr#screenOrientation} attribute.
@@ -323,6 +349,7 @@
      * {@link #SCREEN_ORIENTATION_FULL_USER},
      * {@link #SCREEN_ORIENTATION_LOCKED},
      */
+    @ScreenOrientation
     public int screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
     
     /**
diff --git a/core/java/android/content/pm/FeatureInfo.java b/core/java/android/content/pm/FeatureInfo.java
index 89394f9..d919fc3 100644
--- a/core/java/android/content/pm/FeatureInfo.java
+++ b/core/java/android/content/pm/FeatureInfo.java
@@ -18,7 +18,6 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Parcelable.Creator;
 
 /**
  * A single feature that can be requested by an application. This corresponds
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c97c2b8..0192a30 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -16,6 +16,7 @@
 
 package android.content.pm;
 
+import android.annotation.IntDef;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ComponentName;
@@ -33,6 +34,8 @@
 import android.util.DisplayMetrics;
 
 import java.io.File;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -190,6 +193,11 @@
      */
     public static final int MATCH_DEFAULT_ONLY   = 0x00010000;
 
+    /** @hide */
+    @IntDef({PERMISSION_GRANTED, PERMISSION_DENIED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PermissionResult {}
+
     /**
      * Permission check result: this is returned by {@link #checkPermission}
      * if the permission has been granted to the given package.
diff --git a/core/java/android/content/pm/XmlSerializerAndParser.java b/core/java/android/content/pm/XmlSerializerAndParser.java
index 935fc02..20cb61c 100644
--- a/core/java/android/content/pm/XmlSerializerAndParser.java
+++ b/core/java/android/content/pm/XmlSerializerAndParser.java
@@ -19,7 +19,6 @@
 import org.xmlpull.v1.XmlSerializer;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import android.os.Parcel;
 
 import java.io.IOException;
 
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index fc9e486..e53486d 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -17,7 +17,6 @@
 package android.content.res;
 
 import android.os.ParcelFileDescriptor;
-import android.os.Trace;
 import android.util.Log;
 import android.util.TypedValue;
 
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index bd23db4..431226a 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -16,6 +16,7 @@
 
 package android.content.res;
 
+import android.graphics.Color;
 import com.android.internal.util.ArrayUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -259,7 +260,17 @@
     public boolean isStateful() {
         return mStateSpecs.length > 1;
     }
-    
+
+    public boolean isOpaque() {
+        final int n = mColors.length;
+        for (int i = 0; i < n; i++) {
+            if (Color.alpha(mColors[i]) != 0xFF) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     /**
      * Return the color associated with the given set of {@link android.view.View} states.
      *
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index cd5b5d2f..eb41ee9 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -36,7 +36,6 @@
 import android.util.Slog;
 import android.util.TypedValue;
 import android.util.LongSparseArray;
-import android.view.DisplayAdjustments;
 
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 83d48aa..4b96800 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -16,7 +16,6 @@
 
 package android.content.res;
 
-import android.content.pm.ActivityInfo;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
diff --git a/core/java/android/database/CursorToBulkCursorAdaptor.java b/core/java/android/database/CursorToBulkCursorAdaptor.java
index 82a61d4..7dcfae2 100644
--- a/core/java/android/database/CursorToBulkCursorAdaptor.java
+++ b/core/java/android/database/CursorToBulkCursorAdaptor.java
@@ -20,7 +20,6 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.util.Log;
 
 
 /**
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
index 431eca2..2dd4800 100644
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.database.DatabaseErrorHandler;
-import android.database.DefaultDatabaseErrorHandler;
 import android.database.sqlite.SQLiteDatabase.CursorFactory;
 import android.util.Log;
 
diff --git a/core/java/android/ddm/DdmHandleNativeHeap.java b/core/java/android/ddm/DdmHandleNativeHeap.java
index 6bd65aa..775c570 100644
--- a/core/java/android/ddm/DdmHandleNativeHeap.java
+++ b/core/java/android/ddm/DdmHandleNativeHeap.java
@@ -20,7 +20,6 @@
 import org.apache.harmony.dalvik.ddmc.ChunkHandler;
 import org.apache.harmony.dalvik.ddmc.DdmServer;
 import android.util.Log;
-import java.nio.ByteBuffer;
 
 /**
  * Handle thread-related traffic.
diff --git a/core/java/android/ddm/DdmHandleProfiling.java b/core/java/android/ddm/DdmHandleProfiling.java
index ec08393..cce4dd2 100644
--- a/core/java/android/ddm/DdmHandleProfiling.java
+++ b/core/java/android/ddm/DdmHandleProfiling.java
@@ -21,7 +21,6 @@
 import org.apache.harmony.dalvik.ddmc.DdmServer;
 import android.os.Debug;
 import android.util.Log;
-import java.io.IOException;
 import java.nio.ByteBuffer;
 
 /**
@@ -37,6 +36,7 @@
     public static final int CHUNK_SPSS = type("SPSS");
     public static final int CHUNK_SPSE = type("SPSE");
 
+    private static final boolean DEBUG = false;
     private static DdmHandleProfiling mInstance = new DdmHandleProfiling();
 
 
@@ -72,7 +72,7 @@
      * Handle a chunk of data.
      */
     public Chunk handleChunk(Chunk request) {
-        if (false)
+        if (DEBUG)
             Log.v("ddm-heap", "Handling " + name(request.type) + " chunk");
         int type = request.type;
 
@@ -83,13 +83,13 @@
         } else if (type == CHUNK_MPSS) {
             return handleMPSS(request);
         } else if (type == CHUNK_MPSE) {
-            return handleMPSE(request);
+            return handleMPSEOrSPSE(request, "Method");
         } else if (type == CHUNK_MPRQ) {
             return handleMPRQ(request);
         } else if (type == CHUNK_SPSS) {
             return handleSPSS(request);
         } else if (type == CHUNK_SPSE) {
-            return handleSPSE(request);
+            return handleMPSEOrSPSE(request, "Sample");
         } else {
             throw new RuntimeException("Unknown packet "
                 + ChunkHandler.name(type));
@@ -106,7 +106,7 @@
         int flags = in.getInt();
         int len = in.getInt();
         String fileName = getString(in, len);
-        if (false)
+        if (DEBUG)
             Log.v("ddm-heap", "Method profiling start: filename='" + fileName
                 + "', size=" + bufferSize + ", flags=" + flags);
 
@@ -146,7 +146,7 @@
 
         int bufferSize = in.getInt();
         int flags = in.getInt();
-        if (false) {
+        if (DEBUG) {
             Log.v("ddm-heap", "Method prof stream start: size=" + bufferSize
                 + ", flags=" + flags);
         }
@@ -160,20 +160,18 @@
     }
 
     /*
-     * Handle a "Method Profiling w/Streaming End" request.
+     * Handle a "Method Profiling w/Streaming End" request or a
+     * "Sample Profiling w/Streaming End" request.
      */
-    private Chunk handleMPSE(Chunk request) {
-        byte result;
-
-        if (false) {
-            Log.v("ddm-heap", "Method prof stream end");
+    private Chunk handleMPSEOrSPSE(Chunk request, String type) {
+        if (DEBUG) {
+            Log.v("ddm-heap", type + " prof stream end");
         }
 
         try {
             Debug.stopMethodTracing();
-            result = 0;
         } catch (RuntimeException re) {
-            Log.w("ddm-heap", "Method prof stream end failed: "
+            Log.w("ddm-heap", type + " prof stream end failed: "
                 + re.getMessage());
             return createFailChunk(1, re.getMessage());
         }
@@ -202,7 +200,7 @@
         int bufferSize = in.getInt();
         int flags = in.getInt();
         int interval = in.getInt();
-        if (false) {
+        if (DEBUG) {
             Log.v("ddm-heap", "Sample prof stream start: size=" + bufferSize
                 + ", flags=" + flags + ", interval=" + interval);
         }
@@ -214,25 +212,5 @@
             return createFailChunk(1, re.getMessage());
         }
     }
-
-    /*
-     * Handle a "Sample Profiling w/Streaming End" request.
-     */
-    private Chunk handleSPSE(Chunk request) {
-        if (false) {
-            Log.v("ddm-heap", "Sample prof stream end");
-        }
-
-        try {
-            Debug.stopMethodTracing();
-        } catch (RuntimeException re) {
-            Log.w("ddm-heap", "Sample prof stream end failed: "
-                + re.getMessage());
-            return createFailChunk(1, re.getMessage());
-        }
-
-        /* VM sent the (perhaps very large) response directly */
-        return null;
-    }
 }
 
diff --git a/core/java/android/gesture/GestureOverlayView.java b/core/java/android/gesture/GestureOverlayView.java
index 2d47f28..6e3a00f 100644
--- a/core/java/android/gesture/GestureOverlayView.java
+++ b/core/java/android/gesture/GestureOverlayView.java
@@ -134,11 +134,16 @@
         this(context, attrs, com.android.internal.R.attr.gestureOverlayViewStyle);
     }
 
-    public GestureOverlayView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public GestureOverlayView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                R.styleable.GestureOverlayView, defStyle, 0);
+    public GestureOverlayView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.GestureOverlayView, defStyleAttr, defStyleRes);
 
         mGestureStrokeWidth = a.getFloat(R.styleable.GestureOverlayView_gestureStrokeWidth,
                 mGestureStrokeWidth);
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index feb47aa..9913e33 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -46,7 +46,6 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
-import java.util.concurrent.locks.ReentrantLock;
 
 /**
  * The Camera class is used to set image capture settings, start/stop preview,
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index b931313..8c23129 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -1056,8 +1056,8 @@
      *        is mapped.
      *
      * @param outR
-     *        the transformed rotation matrix. inR and outR can be the same
-     *        array, but it is not recommended for performance reason.
+     *        the transformed rotation matrix. inR and outR should not be the same
+     *        array.
      *
      * @return <code>true</code> on success. <code>false</code> if the input
      *         parameters are incorrect, for instance if X and Y define the same
diff --git a/core/java/android/hardware/SerialManager.java b/core/java/android/hardware/SerialManager.java
index c5e1c2b..e0680bf22 100644
--- a/core/java/android/hardware/SerialManager.java
+++ b/core/java/android/hardware/SerialManager.java
@@ -17,16 +17,12 @@
 
 package android.hardware;
 
-import android.app.PendingIntent;
 import android.content.Context;
-import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.os.SystemProperties;
 import android.util.Log;
 
 import java.io.IOException;
-import java.util.HashMap;
 
 /**
  * @hide
diff --git a/core/java/android/hardware/SerialPort.java b/core/java/android/hardware/SerialPort.java
index f50cdef..5d83d9c 100644
--- a/core/java/android/hardware/SerialPort.java
+++ b/core/java/android/hardware/SerialPort.java
@@ -17,14 +17,9 @@
 package android.hardware;
 
 import android.os.ParcelFileDescriptor;
-import android.util.Log;
 
 import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
 import java.io.IOException;
-import java.io.OutputStream;
 
 import java.nio.ByteBuffer;
 
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 65b6c7a..2ac50e4 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.hardware.ICameraService;
 import android.hardware.ICameraServiceListener;
-import android.hardware.IProCameraUser;
 import android.hardware.camera2.impl.CameraMetadataNative;
 import android.hardware.camera2.utils.CameraBinderDecorator;
 import android.hardware.camera2.utils.CameraRuntimeException;
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 1d6ff7d..5d0bb33 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -168,7 +168,7 @@
 
             Key lhs = (Key) o;
 
-            return mName.equals(lhs.mName);
+            return mName.equals(lhs.mName) && mType.equals(lhs.mType);
         }
 
         /**
diff --git a/core/java/android/hardware/camera2/CaptureFailure.java b/core/java/android/hardware/camera2/CaptureFailure.java
index 3b408cf..35f9af1 100644
--- a/core/java/android/hardware/camera2/CaptureFailure.java
+++ b/core/java/android/hardware/camera2/CaptureFailure.java
@@ -15,8 +15,6 @@
  */
 package android.hardware.camera2;
 
-import android.hardware.camera2.CameraDevice.CaptureListener;
-
 /**
  * A report of failed capture for a single image capture from the image sensor.
  *
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 898f123..00b02fa 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -17,7 +17,6 @@
 package android.hardware.camera2;
 
 import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.CameraDevice.CaptureListener;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.view.Surface;
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 535b963..7224577 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -16,8 +16,6 @@
 
 package android.hardware.camera2;
 
-import android.graphics.Point;
-import android.graphics.Rect;
 import android.hardware.camera2.impl.CameraMetadataNative;
 
 /**
@@ -784,6 +782,8 @@
      * <p>
      * Only available if faceDetectMode == FULL
      * </p>
+     *
+     * @hide
      */
     public static final Key<int[]> STATISTICS_FACE_IDS =
             new Key<int[]>("android.statistics.faceIds", int[].class);
@@ -796,6 +796,8 @@
      * <p>
      * Only available if faceDetectMode == FULL
      * </p>
+     *
+     * @hide
      */
     public static final Key<int[]> STATISTICS_FACE_LANDMARKS =
             new Key<int[]>("android.statistics.faceLandmarks", int[].class);
@@ -808,6 +810,8 @@
      * <p>
      * Only available if faceDetectMode != OFF
      * </p>
+     *
+     * @hide
      */
     public static final Key<android.graphics.Rect[]> STATISTICS_FACE_RECTANGLES =
             new Key<android.graphics.Rect[]>("android.statistics.faceRectangles", android.graphics.Rect[].class);
@@ -821,6 +825,8 @@
      * Only available if faceDetectMode != OFF. The value should be
      * meaningful (for example, setting 100 at all times is illegal).
      * </p>
+     *
+     * @hide
      */
     public static final Key<byte[]> STATISTICS_FACE_SCORES =
             new Key<byte[]>("android.statistics.faceScores", byte[].class);
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 072c5bb..2ddcb14 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -448,7 +448,7 @@
         } else if (key.equals(CaptureResult.STATISTICS_FACES)) {
             return (T) getFaces();
         } else if (key.equals(CaptureResult.STATISTICS_FACE_RECTANGLES)) {
-            return (T) fixFaceRectangles();
+            return (T) getFaceRectangles();
         }
 
         // For other keys, get() falls back to getBase()
@@ -457,12 +457,15 @@
 
     private int[] getAvailableFormats() {
         int[] availableFormats = getBase(CameraCharacteristics.SCALER_AVAILABLE_FORMATS);
-        for (int i = 0; i < availableFormats.length; i++) {
-            // JPEG has different value between native and managed side, need override.
-            if (availableFormats[i] == NATIVE_JPEG_FORMAT) {
-                availableFormats[i] = ImageFormat.JPEG;
+        if (availableFormats != null) {
+            for (int i = 0; i < availableFormats.length; i++) {
+                // JPEG has different value between native and managed side, need override.
+                if (availableFormats[i] == NATIVE_JPEG_FORMAT) {
+                    availableFormats[i] = ImageFormat.JPEG;
+                }
             }
         }
+
         return availableFormats;
     }
 
@@ -550,7 +553,7 @@
     // (left, top, width, height) at the native level, so the normal Rect
     // conversion that does (l, t, w, h) -> (l, t, r, b) is unnecessary. Undo
     // that conversion here for just the faces.
-    private Rect[] fixFaceRectangles() {
+    private Rect[] getFaceRectangles() {
         Rect[] faceRectangles = getBase(CaptureResult.STATISTICS_FACE_RECTANGLES);
         if (faceRectangles == null) return null;
 
@@ -590,6 +593,8 @@
     private <T> boolean setOverride(Key<T> key, T value) {
         if (key.equals(CameraCharacteristics.SCALER_AVAILABLE_FORMATS)) {
             return setAvailableFormats((int[]) value);
+        } else if (key.equals(CaptureResult.STATISTICS_FACE_RECTANGLES)) {
+            return setFaceRectangles((Rect[]) value);
         }
 
         // For other keys, set() falls back to setBase().
@@ -615,6 +620,36 @@
         return true;
     }
 
+    /**
+     * Convert Face Rectangles from managed side to native side as they have different definitions.
+     * <p>
+     * Managed side face rectangles are defined as: left, top, width, height.
+     * Native side face rectangles are defined as: left, top, right, bottom.
+     * The input face rectangle need to be converted to native side definition when set is called.
+     * </p>
+     *
+     * @param faceRects Input face rectangles.
+     * @return true if face rectangles can be set successfully. Otherwise, Let the caller
+     *             (setBase) to handle it appropriately.
+     */
+    private boolean setFaceRectangles(Rect[] faceRects) {
+        if (faceRects == null) {
+            return false;
+        }
+
+        Rect[] newFaceRects = new Rect[faceRects.length];
+        for (int i = 0; i < newFaceRects.length; i++) {
+            newFaceRects[i] = new Rect(
+                    faceRects[i].left,
+                    faceRects[i].top,
+                    faceRects[i].right + faceRects[i].left,
+                    faceRects[i].bottom + faceRects[i].top);
+        }
+
+        setBase(CaptureResult.STATISTICS_FACE_RECTANGLES, newFaceRects);
+        return true;
+    }
+
     private long mMetadataPtr; // native CameraMetadata*
 
     private native long nativeAllocate();
diff --git a/core/java/android/hardware/camera2/package.html b/core/java/android/hardware/camera2/package.html
index c619984..9f6c2a9 100644
--- a/core/java/android/hardware/camera2/package.html
+++ b/core/java/android/hardware/camera2/package.html
@@ -80,7 +80,5 @@
 asynchronously relative to the output CaptureResult, sometimes
 substantially later.</p>
 
-{@hide}
-
 </BODY>
 </HTML>
diff --git a/core/java/android/hardware/display/WifiDisplayStatus.java b/core/java/android/hardware/display/WifiDisplayStatus.java
index 5216727..b645662 100644
--- a/core/java/android/hardware/display/WifiDisplayStatus.java
+++ b/core/java/android/hardware/display/WifiDisplayStatus.java
@@ -20,8 +20,6 @@
 import android.os.Parcelable;
 
 import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * Describes the current global state of Wifi display connectivity, including the
diff --git a/core/java/android/hardware/location/GeofenceHardwareRequest.java b/core/java/android/hardware/location/GeofenceHardwareRequest.java
index 6e7b592..796d7f8 100644
--- a/core/java/android/hardware/location/GeofenceHardwareRequest.java
+++ b/core/java/android/hardware/location/GeofenceHardwareRequest.java
@@ -16,8 +16,6 @@
 
 package android.hardware.location;
 
-import android.location.Location;
-
 /**
  * This class represents the characteristics of the geofence.
  *
diff --git a/core/java/android/hardware/usb/UsbAccessory.java b/core/java/android/hardware/usb/UsbAccessory.java
index 5719452..2f9178c 100644
--- a/core/java/android/hardware/usb/UsbAccessory.java
+++ b/core/java/android/hardware/usb/UsbAccessory.java
@@ -16,10 +16,8 @@
 
 package android.hardware.usb;
 
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.util.Log;
 
 /**
  * A class representing a USB accessory, which is an external hardware component
diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
index 9bd38f9..ae6118c 100644
--- a/core/java/android/hardware/usb/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -16,12 +16,8 @@
 
 package android.hardware.usb;
 
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.util.Log;
-
-import java.io.FileDescriptor;
 
 /**
  * This class represents a USB device attached to the android device with the android device
diff --git a/core/java/android/hardware/usb/UsbEndpoint.java b/core/java/android/hardware/usb/UsbEndpoint.java
index 753a447..708d651 100644
--- a/core/java/android/hardware/usb/UsbEndpoint.java
+++ b/core/java/android/hardware/usb/UsbEndpoint.java
@@ -16,7 +16,6 @@
 
 package android.hardware.usb;
 
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
diff --git a/core/java/android/hardware/usb/UsbInterface.java b/core/java/android/hardware/usb/UsbInterface.java
index d6c54a8..e94baa1 100644
--- a/core/java/android/hardware/usb/UsbInterface.java
+++ b/core/java/android/hardware/usb/UsbInterface.java
@@ -16,7 +16,6 @@
 
 package android.hardware.usb;
 
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
diff --git a/core/java/android/inputmethodservice/ExtractButton.java b/core/java/android/inputmethodservice/ExtractButton.java
index b6b7595..fe63c1e 100644
--- a/core/java/android/inputmethodservice/ExtractButton.java
+++ b/core/java/android/inputmethodservice/ExtractButton.java
@@ -32,8 +32,12 @@
         super(context, attrs, com.android.internal.R.attr.buttonStyle);
     }
 
-    public ExtractButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ExtractButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ExtractButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
     
     /**
diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java
index 23ae21b..48b604c 100644
--- a/core/java/android/inputmethodservice/ExtractEditText.java
+++ b/core/java/android/inputmethodservice/ExtractEditText.java
@@ -38,8 +38,12 @@
         super(context, attrs, com.android.internal.R.attr.editTextStyle);
     }
 
-    public ExtractEditText(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ExtractEditText(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ExtractEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
     
     void setIME(InputMethodService ime) {
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index 726dcec..8437228 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -25,7 +25,6 @@
 import android.os.Bundle;
 import android.os.Looper;
 import android.os.Message;
-import android.os.RemoteException;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.InputChannel;
@@ -75,7 +74,15 @@
     @Override
     public void executeMessage(Message msg) {
         if (mInputMethodSession == null) {
-            // The session has been finished.
+            // The session has been finished. Args needs to be recycled
+            // for cases below.
+            switch (msg.what) {
+                case DO_UPDATE_SELECTION:
+                case DO_APP_PRIVATE_COMMAND: {
+                    SomeArgs args = (SomeArgs)msg.obj;
+                    args.recycle();
+                }
+            }
             return;
         }
 
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 1b7d9ea..81ad28b 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -2322,6 +2322,21 @@
     }
 
     /**
+     * @return The recommended height of the input method window.
+     * An IME author can get the last input method's height as the recommended height
+     * by calling this in
+     * {@link android.inputmethodservice.InputMethodService#onStartInputView(EditorInfo, boolean)}.
+     * If you don't need to use a predefined fixed height, you can avoid the window-resizing of IME
+     * switching by using this value as a visible inset height. It's efficient for the smooth
+     * transition between different IMEs. However, note that this may return 0 (or possibly
+     * unexpectedly low height). You should thus avoid relying on the return value of this method
+     * all the time. Please make sure to use a reasonable height for the IME.
+     */
+    public int getInputMethodWindowRecommendedHeight() {
+        return mImm.getInputMethodWindowVisibleHeight();
+    }
+
+    /**
      * Performs a dump of the InputMethodService's internal state.  Override
      * to add your own information to the dump.
      */
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 4916244..af75a0a 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -279,12 +279,15 @@
         this(context, attrs, com.android.internal.R.attr.keyboardViewStyle);
     }
 
-    public KeyboardView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public KeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a =
-            context.obtainStyledAttributes(
-                attrs, android.R.styleable.KeyboardView, defStyle, 0);
+    public KeyboardView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, android.R.styleable.KeyboardView, defStyleAttr, defStyleRes);
 
         LayoutInflater inflate =
                 (LayoutInflater) context
diff --git a/core/java/android/net/BaseNetworkStateTracker.java b/core/java/android/net/BaseNetworkStateTracker.java
index 476fefe..804f8ee 100644
--- a/core/java/android/net/BaseNetworkStateTracker.java
+++ b/core/java/android/net/BaseNetworkStateTracker.java
@@ -20,10 +20,10 @@
 import android.os.Handler;
 import android.os.Messenger;
 
-import com.android.internal.util.Preconditions;
-
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import com.android.internal.util.Preconditions;
+
 /**
  * Interface to control and observe state of a specific network, hiding
  * network-specific details from {@link ConnectivityManager}. Surfaces events
@@ -108,11 +108,6 @@
     }
 
     @Override
-    public void captivePortalCheckComplete() {
-        // not implemented
-    }
-
-    @Override
     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
         // not implemented
     }
diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java
index d678f1e..5b6f154 100644
--- a/core/java/android/net/CaptivePortalTracker.java
+++ b/core/java/android/net/CaptivePortalTracker.java
@@ -48,7 +48,6 @@
 import java.net.HttpURLConnection;
 import java.net.InetAddress;
 import java.net.Inet4Address;
-import java.net.SocketTimeoutException;
 import java.net.URL;
 import java.net.UnknownHostException;
 import java.util.List;
@@ -84,13 +83,12 @@
     private String mServer;
     private String mUrl;
     private boolean mIsCaptivePortalCheckEnabled = false;
-    private IConnectivityManager mConnService;
-    private TelephonyManager mTelephonyManager;
-    private WifiManager mWifiManager;
-    private Context mContext;
+    private final IConnectivityManager mConnService;
+    private final TelephonyManager mTelephonyManager;
+    private final WifiManager mWifiManager;
+    private final Context mContext;
     private NetworkInfo mNetworkInfo;
 
-    private static final int CMD_DETECT_PORTAL          = 0;
     private static final int CMD_CONNECTIVITY_CHANGE    = 1;
     private static final int CMD_DELAYED_CAPTIVE_CHECK  = 2;
 
@@ -98,14 +96,15 @@
     private static final int DELAYED_CHECK_INTERVAL_MS = 10000;
     private int mDelayedCheckToken = 0;
 
-    private State mDefaultState = new DefaultState();
-    private State mNoActiveNetworkState = new NoActiveNetworkState();
-    private State mActiveNetworkState = new ActiveNetworkState();
-    private State mDelayedCaptiveCheckState = new DelayedCaptiveCheckState();
+    private final State mDefaultState = new DefaultState();
+    private final State mNoActiveNetworkState = new NoActiveNetworkState();
+    private final State mActiveNetworkState = new ActiveNetworkState();
+    private final State mDelayedCaptiveCheckState = new DelayedCaptiveCheckState();
 
     private static final String SETUP_WIZARD_PACKAGE = "com.google.android.setupwizard";
     private boolean mDeviceProvisioned = false;
-    private ProvisioningObserver mProvisioningObserver;
+    @SuppressWarnings("unused")
+    private final ProvisioningObserver mProvisioningObserver;
 
     private CaptivePortalTracker(Context context, IConnectivityManager cs) {
         super(TAG);
@@ -174,29 +173,11 @@
         return captivePortal;
     }
 
-    public void detectCaptivePortal(NetworkInfo info) {
-        sendMessage(obtainMessage(CMD_DETECT_PORTAL, info));
-    }
-
     private class DefaultState extends State {
 
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) log(getName() + message.toString());
-            switch (message.what) {
-                case CMD_DETECT_PORTAL:
-                    NetworkInfo info = (NetworkInfo) message.obj;
-                    // Checking on a secondary connection is not supported
-                    // yet
-                    notifyPortalCheckComplete(info);
-                    break;
-                case CMD_CONNECTIVITY_CHANGE:
-                case CMD_DELAYED_CAPTIVE_CHECK:
-                    break;
-                default:
-                    loge("Ignoring " + message);
-                    break;
-            }
+            loge("Ignoring " + message);
             return HANDLED;
         }
     }
@@ -316,19 +297,6 @@
         }
     }
 
-    private void notifyPortalCheckComplete(NetworkInfo info) {
-        if (info == null) {
-            loge("notifyPortalCheckComplete on null");
-            return;
-        }
-        try {
-            if (DBG) log("notifyPortalCheckComplete: ni=" + info);
-            mConnService.captivePortalCheckComplete(info);
-        } catch(RemoteException e) {
-            e.printStackTrace();
-        }
-    }
-
     private void notifyPortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
         if (info == null) {
             loge("notifyPortalCheckComplete on null");
@@ -464,7 +432,6 @@
                 latencyBroadcast.putExtra(EXTRA_NETWORK_TYPE, mTelephonyManager.getNetworkType());
                 List<CellInfo> info = mTelephonyManager.getAllCellInfo();
                 if (info == null) return;
-                StringBuffer uniqueCellId = new StringBuffer();
                 int numRegisteredCellInfo = 0;
                 for (CellInfo cellInfo : info) {
                     if (cellInfo.isRegistered()) {
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index c78a973..a9b2533 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -25,7 +25,6 @@
 import android.os.Build.VERSION_CODES;
 import android.os.Messenger;
 import android.os.RemoteException;
-import android.os.ResultReceiver;
 import android.provider.Settings;
 
 import java.net.InetAddress;
@@ -1330,24 +1329,6 @@
 
     /**
      * Signal that the captive portal check on the indicated network
-     * is complete and we can turn the network on for general use.
-     *
-     * @param info the {@link NetworkInfo} object for the networkType
-     *        in question.
-     *
-     * <p>This method requires the call to hold the permission
-     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
-     * {@hide}
-     */
-    public void captivePortalCheckComplete(NetworkInfo info) {
-        try {
-            mService.captivePortalCheckComplete(info);
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
-     * Signal that the captive portal check on the indicated network
      * is complete and whether its a captive portal or not.
      *
      * @param info the {@link NetworkInfo} object for the networkType
diff --git a/core/java/android/net/DhcpInfo.java b/core/java/android/net/DhcpInfo.java
index 3bede5d..788d7d9 100644
--- a/core/java/android/net/DhcpInfo.java
+++ b/core/java/android/net/DhcpInfo.java
@@ -18,7 +18,6 @@
 
 import android.os.Parcelable;
 import android.os.Parcel;
-import java.net.InetAddress;
 
 /**
  * A simple object for retrieving the results of a DHCP request.
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index a3f70da..22b26b1 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -23,9 +23,6 @@
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
 
 /**
  * A simple object for retrieving the results of a DHCP request.
diff --git a/core/java/android/net/DummyDataStateTracker.java b/core/java/android/net/DummyDataStateTracker.java
index 51a1191..a5d059e 100644
--- a/core/java/android/net/DummyDataStateTracker.java
+++ b/core/java/android/net/DummyDataStateTracker.java
@@ -117,11 +117,6 @@
     }
 
     @Override
-    public void captivePortalCheckComplete() {
-        // not implemented
-    }
-
-    @Override
     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
         // not implemented
     }
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
index 501484c..95faa77 100644
--- a/core/java/android/net/EthernetDataTracker.java
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -270,11 +270,6 @@
     }
 
     @Override
-    public void captivePortalCheckComplete() {
-        // not implemented
-    }
-
-    @Override
     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
         // not implemented
     }
@@ -402,7 +397,7 @@
      * for this network.
      */
     public String getTcpBufferSizesPropName() {
-        return "net.tcp.buffersize.wifi";
+        return "net.tcp.buffersize.ethernet";
     }
 
     public void setDependencyMet(boolean met) {
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index c1da2e3..b3217eb 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -129,8 +129,6 @@
 
     boolean updateLockdownVpn();
 
-    void captivePortalCheckComplete(in NetworkInfo info);
-
     void captivePortalCheckCompleted(in NetworkInfo info, boolean isCaptivePortal);
 
     void supplyMessenger(int networkType, in Messenger messenger);
diff --git a/core/java/android/net/INetworkManagementEventObserver.aidl b/core/java/android/net/INetworkManagementEventObserver.aidl
index b76e4c2..405a897 100644
--- a/core/java/android/net/INetworkManagementEventObserver.aidl
+++ b/core/java/android/net/INetworkManagementEventObserver.aidl
@@ -16,6 +16,8 @@
 
 package android.net;
 
+import android.net.LinkAddress;
+
 /**
  * Callback class for receiving events from an INetworkManagementService
  *
@@ -62,7 +64,7 @@
      * @param flags The address flags.
      * @param scope The address scope.
      */
-    void addressUpdated(String address, String iface, int flags, int scope);
+    void addressUpdated(in LinkAddress address, String iface, int flags, int scope);
 
     /**
      * An interface address has been removed
@@ -72,7 +74,7 @@
      * @param flags The address flags.
      * @param scope The address scope.
      */
-    void addressRemoved(String address, String iface, int flags, int scope);
+    void addressRemoved(in LinkAddress address, String iface, int flags, int scope);
 
     /**
      * A networking quota limit has been reached. The quota might not
@@ -90,4 +92,13 @@
      * @param active  True if the interface is actively transmitting data, false if it is idle.
      */
     void interfaceClassDataActivityChanged(String label, boolean active);
+
+    /**
+     * Information about available DNS servers has been received.
+     *
+     * @param iface The interface on which the information was received.
+     * @param lifetime The time in seconds for which the DNS servers may be used.
+     * @param servers The IP addresses of the DNS servers.
+     */
+    void interfaceDnsServerInfo(String iface, long lifetime, in String[] servers);
 }
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index a390add..570b6fe 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -25,7 +25,7 @@
 import java.net.UnknownHostException;
 
 /**
- * Identifies an address of a network link
+ * Identifies an IP address on a network link.
  * @hide
  */
 public class LinkAddress implements Parcelable {
@@ -35,7 +35,7 @@
     private InetAddress address;
 
     /**
-     * Network prefix length
+     * Prefix length.
      */
     private int prefixLength;
 
@@ -50,10 +50,19 @@
         this.prefixLength = prefixLength;
     }
 
+    /**
+     * Constructs a new {@code LinkAddress} from an {@code InetAddress} and a prefix length.
+     * @param address The IP address.
+     * @param prefixLength The prefix length.
+     */
     public LinkAddress(InetAddress address, int prefixLength) {
         init(address, prefixLength);
     }
 
+    /**
+     * Constructs a new {@code LinkAddress} from an {@code InterfaceAddress}.
+     * @param interfaceAddress The interface address.
+     */
     public LinkAddress(InterfaceAddress interfaceAddress) {
         init(interfaceAddress.getAddress(),
              interfaceAddress.getNetworkPrefixLength());
@@ -86,13 +95,13 @@
 
     @Override
     public String toString() {
-        return (address == null ? "" : (address.getHostAddress() + "/" + prefixLength));
+        return address.getHostAddress() + "/" + prefixLength;
     }
 
     /**
      * Compares this {@code LinkAddress} instance against the specified address
      * in {@code obj}. Two addresses are equal if their InetAddress and prefixLength
-     * are equal
+     * are equal.
      *
      * @param obj the object to be tested for equality.
      * @return {@code true} if both objects are equal, {@code false} otherwise.
@@ -107,30 +116,30 @@
             this.prefixLength == linkAddress.prefixLength;
     }
 
-    @Override
-    /*
-     * generate hashcode based on significant fields
+    /**
+     * Returns a hashcode for this address.
      */
+    @Override
     public int hashCode() {
-        return ((null == address) ? 0 : address.hashCode()) + prefixLength;
+        return address.hashCode() + 11 * prefixLength;
     }
 
     /**
-     * Returns the InetAddress for this address.
+     * Returns the InetAddress of this address.
      */
     public InetAddress getAddress() {
         return address;
     }
 
     /**
-     * Get network prefix length
+     * Returns the prefix length of this address.
      */
     public int getNetworkPrefixLength() {
         return prefixLength;
     }
 
     /**
-     * Implement the Parcelable interface
+     * Implement the Parcelable interface.
      * @hide
      */
     public int describeContents() {
@@ -142,13 +151,8 @@
      * @hide
      */
     public void writeToParcel(Parcel dest, int flags) {
-        if (address != null) {
-            dest.writeByte((byte)1);
-            dest.writeByteArray(address.getAddress());
-            dest.writeInt(prefixLength);
-        } else {
-            dest.writeByte((byte)0);
-        }
+        dest.writeByteArray(address.getAddress());
+        dest.writeInt(prefixLength);
     }
 
     /**
@@ -159,13 +163,14 @@
         new Creator<LinkAddress>() {
             public LinkAddress createFromParcel(Parcel in) {
                 InetAddress address = null;
-                int prefixLength = 0;
-                if (in.readByte() == 1) {
-                    try {
-                        address = InetAddress.getByAddress(in.createByteArray());
-                        prefixLength = in.readInt();
-                    } catch (UnknownHostException e) { }
+                try {
+                    address = InetAddress.getByAddress(in.createByteArray());
+                } catch (UnknownHostException e) {
+                    // Nothing we can do here. When we call the constructor, we'll throw an
+                    // IllegalArgumentException, because a LinkAddress can't have a null
+                    // InetAddress.
                 }
+                int prefixLength = in.readInt();
                 return new LinkAddress(address, prefixLength);
             }
 
diff --git a/core/java/android/net/LinkSocketNotifier.java b/core/java/android/net/LinkSocketNotifier.java
index 28e2834..e2429d8 100644
--- a/core/java/android/net/LinkSocketNotifier.java
+++ b/core/java/android/net/LinkSocketNotifier.java
@@ -16,8 +16,6 @@
 
 package android.net;
 
-import java.util.Map;
-
 /**
  * Interface used to get feedback about a {@link android.net.LinkSocket}.  Instance is optionally
  * passed when a LinkSocket is constructed.  Multiple LinkSockets may use the same notifier.
diff --git a/core/java/android/net/MailTo.java b/core/java/android/net/MailTo.java
index b90dcb1..dadb6d9 100644
--- a/core/java/android/net/MailTo.java
+++ b/core/java/android/net/MailTo.java
@@ -19,7 +19,6 @@
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 
 /**
  *
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index c106514..d9c35c0 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -460,11 +460,6 @@
     }
 
     @Override
-    public void captivePortalCheckComplete() {
-        // not implemented
-    }
-
-    @Override
     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
         if (mIsCaptivePortal.getAndSet(isCaptivePortal) != isCaptivePortal) {
             // Captive portal change enable/disable failing fast
diff --git a/core/java/android/net/NetworkConfig.java b/core/java/android/net/NetworkConfig.java
index 5d95f41..32a2cda 100644
--- a/core/java/android/net/NetworkConfig.java
+++ b/core/java/android/net/NetworkConfig.java
@@ -16,7 +16,6 @@
 
 package android.net;
 
-import android.util.Log;
 import java.util.Locale;
 
 /**
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 4d2a70d..53b1308 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -156,18 +156,20 @@
     /** {@hide} */
     public NetworkInfo(NetworkInfo source) {
         if (source != null) {
-            mNetworkType = source.mNetworkType;
-            mSubtype = source.mSubtype;
-            mTypeName = source.mTypeName;
-            mSubtypeName = source.mSubtypeName;
-            mState = source.mState;
-            mDetailedState = source.mDetailedState;
-            mReason = source.mReason;
-            mExtraInfo = source.mExtraInfo;
-            mIsFailover = source.mIsFailover;
-            mIsRoaming = source.mIsRoaming;
-            mIsAvailable = source.mIsAvailable;
-            mIsConnectedToProvisioningNetwork = source.mIsConnectedToProvisioningNetwork;
+            synchronized (source) {
+                mNetworkType = source.mNetworkType;
+                mSubtype = source.mSubtype;
+                mTypeName = source.mTypeName;
+                mSubtypeName = source.mSubtypeName;
+                mState = source.mState;
+                mDetailedState = source.mDetailedState;
+                mReason = source.mReason;
+                mExtraInfo = source.mExtraInfo;
+                mIsFailover = source.mIsFailover;
+                mIsRoaming = source.mIsRoaming;
+                mIsAvailable = source.mIsAvailable;
+                mIsConnectedToProvisioningNetwork = source.mIsConnectedToProvisioningNetwork;
+            }
         }
     }
 
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 1ca9255..c49b1d1 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -144,11 +144,6 @@
     public boolean reconnect();
 
     /**
-     * Ready to switch on to the network after captive portal check
-     */
-    public void captivePortalCheckComplete();
-
-    /**
      * Captive portal check has completed
      */
     public void captivePortalCheckCompleted(boolean isCaptive);
diff --git a/core/java/android/net/ProxyProperties.java b/core/java/android/net/ProxyProperties.java
index 010e527..54fc01d 100644
--- a/core/java/android/net/ProxyProperties.java
+++ b/core/java/android/net/ProxyProperties.java
@@ -22,7 +22,6 @@
 import android.text.TextUtils;
 
 import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
 import java.util.Locale;
 
 /**
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index 208b212..12e8791 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -135,7 +135,8 @@
      * disabled, using an optional handshake timeout and SSL session cache.
      *
      * <p class="caution"><b>Warning:</b> Sockets created using this factory
-     * are vulnerable to man-in-the-middle attacks!</p>
+     * are vulnerable to man-in-the-middle attacks!</p>. The caller must implement
+     * its own verification.
      *
      * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
      *         for none.  The socket timeout is reset to 0 after the handshake.
@@ -223,8 +224,6 @@
             if (mInsecureFactory == null) {
                 if (mSecure) {
                     Log.w(TAG, "*** BYPASSING SSL SECURITY CHECKS (socket.relaxsslcheck=yes) ***");
-                } else {
-                    Log.w(TAG, "Bypassing SSL security checks at caller's request");
                 }
                 mInsecureFactory = makeSocketFactory(mKeyManagers, INSECURE_TRUST_MANAGER);
             }
@@ -431,6 +430,7 @@
         s.setAlpnProtocols(mAlpnProtocols);
         s.setHandshakeTimeout(mHandshakeTimeoutMillis);
         s.setChannelIdPrivateKey(mChannelIdPrivateKey);
+        s.setHostname(host);
         if (mSecure) {
             verifyHostname(s, host);
         }
@@ -533,7 +533,7 @@
 
     @Override
     public String[] getDefaultCipherSuites() {
-        return getDelegate().getSupportedCipherSuites();
+        return getDelegate().getDefaultCipherSuites();
     }
 
     @Override
diff --git a/core/java/android/net/SSLSessionCache.java b/core/java/android/net/SSLSessionCache.java
index 15421de..65db2c3 100644
--- a/core/java/android/net/SSLSessionCache.java
+++ b/core/java/android/net/SSLSessionCache.java
@@ -19,12 +19,16 @@
 import android.content.Context;
 import android.util.Log;
 
+import com.android.org.conscrypt.ClientSessionContext;
 import com.android.org.conscrypt.FileClientSessionCache;
 import com.android.org.conscrypt.SSLClientSessionCache;
 
 import java.io.File;
 import java.io.IOException;
 
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSessionContext;
+
 /**
  * File-based cache of established SSL sessions.  When re-establishing a
  * connection to the same server, using an SSL session cache can save some time,
@@ -38,6 +42,40 @@
     /* package */ final SSLClientSessionCache mSessionCache;
 
     /**
+     * Installs a {@link SSLSessionCache} on a {@link SSLContext}. The cache will
+     * be used on all socket factories created by this context (including factories
+     * created before this call).
+     *
+     * @param cache the cache instance to install, or {@code null} to uninstall any
+     *         existing cache.
+     * @param context the context to install it on.
+     * @throws IllegalArgumentException if the context does not support a session
+     *         cache.
+     *
+     * @hide candidate for public API
+     */
+    public static void install(SSLSessionCache cache, SSLContext context) {
+        SSLSessionContext clientContext = context.getClientSessionContext();
+        if (clientContext instanceof ClientSessionContext) {
+            ((ClientSessionContext) clientContext).setPersistentCache(
+                    cache == null ? null : cache.mSessionCache);
+        } else {
+            throw new IllegalArgumentException("Incompatible SSLContext: " + context);
+        }
+    }
+
+    /**
+     * NOTE: This needs to be Object (and not SSLClientSessionCache) because apps
+     * that build directly against the framework (and not the SDK) might not declare
+     * a dependency on conscrypt. Javac will then has fail while resolving constructors.
+     *
+     * @hide For unit test use only
+     */
+    public SSLSessionCache(Object cache) {
+        mSessionCache = (SSLClientSessionCache) cache;
+    }
+
+    /**
      * Create a session cache using the specified directory.
      * Individual session entries will be files within the directory.
      * Multiple instances for the same directory share data internally.
diff --git a/core/java/android/net/SntpClient.java b/core/java/android/net/SntpClient.java
index 316440f..7673011 100644
--- a/core/java/android/net/SntpClient.java
+++ b/core/java/android/net/SntpClient.java
@@ -19,7 +19,6 @@
 import android.os.SystemClock;
 import android.util.Log;
 
-import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
diff --git a/core/java/android/net/arp/ArpPeer.java b/core/java/android/net/arp/ArpPeer.java
deleted file mode 100644
index 2013b11..0000000
--- a/core/java/android/net/arp/ArpPeer.java
+++ /dev/null
@@ -1,174 +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.net.arp;
-
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.RouteInfo;
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Inet6Address;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Arrays;
-
-import libcore.net.RawSocket;
-
-/**
- * This class allows simple ARP exchanges over an uninitialized network
- * interface.
- *
- * @hide
- */
-public class ArpPeer {
-    private static final boolean DBG = false;
-    private static final String TAG = "ArpPeer";
-    private String mInterfaceName;
-    private final InetAddress mMyAddr;
-    private final byte[] mMyMac = new byte[6];
-    private final InetAddress mPeer;
-    private final RawSocket mSocket;
-    private final byte[] L2_BROADCAST;  // TODO: refactor from DhcpClient.java
-    private static final int MAX_LENGTH = 1500; // refactor from DhcpPacket.java
-    private static final int ETHERNET_TYPE = 1;
-    private static final int ARP_LENGTH = 28;
-    private static final int MAC_ADDR_LENGTH = 6;
-    private static final int IPV4_LENGTH = 4;
-
-    public ArpPeer(String interfaceName, InetAddress myAddr, String mac,
-                   InetAddress peer) throws SocketException {
-        mInterfaceName = interfaceName;
-        mMyAddr = myAddr;
-
-        if (mac != null) {
-            for (int i = 0; i < MAC_ADDR_LENGTH; i++) {
-                mMyMac[i] = (byte) Integer.parseInt(mac.substring(
-                            i*3, (i*3) + 2), 16);
-            }
-        }
-
-        if (myAddr instanceof Inet6Address || peer instanceof Inet6Address) {
-            throw new IllegalArgumentException("IPv6 unsupported");
-        }
-
-        mPeer = peer;
-        L2_BROADCAST = new byte[MAC_ADDR_LENGTH];
-        Arrays.fill(L2_BROADCAST, (byte) 0xFF);
-
-        mSocket = new RawSocket(mInterfaceName, RawSocket.ETH_P_ARP);
-    }
-
-    /**
-     * Returns the MAC address (or null if timeout) for the requested
-     * peer.
-     */
-    public byte[] doArp(int timeoutMillis) {
-        ByteBuffer buf = ByteBuffer.allocate(MAX_LENGTH);
-        byte[] desiredIp = mPeer.getAddress();
-        long timeout = SystemClock.elapsedRealtime() + timeoutMillis;
-
-        // construct ARP request packet, using a ByteBuffer as a
-        // convenient container
-        buf.clear();
-        buf.order(ByteOrder.BIG_ENDIAN);
-
-        buf.putShort((short) ETHERNET_TYPE); // Ethernet type, 16 bits
-        buf.putShort(RawSocket.ETH_P_IP); // Protocol type IP, 16 bits
-        buf.put((byte)MAC_ADDR_LENGTH);  // MAC address length, 6 bytes
-        buf.put((byte)IPV4_LENGTH);  // IPv4 protocol size
-        buf.putShort((short) 1); // ARP opcode 1: 'request'
-        buf.put(mMyMac);        // six bytes: sender MAC
-        buf.put(mMyAddr.getAddress());  // four bytes: sender IP address
-        buf.put(new byte[MAC_ADDR_LENGTH]); // target MAC address: unknown
-        buf.put(desiredIp); // target IP address, 4 bytes
-        buf.flip();
-        mSocket.write(L2_BROADCAST, buf.array(), 0, buf.limit());
-
-        byte[] recvBuf = new byte[MAX_LENGTH];
-
-        while (SystemClock.elapsedRealtime() < timeout) {
-            long duration = (long) timeout - SystemClock.elapsedRealtime();
-            int readLen = mSocket.read(recvBuf, 0, recvBuf.length, -1,
-                (int) duration);
-
-            // Verify packet details. see RFC 826
-            if ((readLen >= ARP_LENGTH) // trailing bytes at times
-                && (recvBuf[0] == 0) && (recvBuf[1] == ETHERNET_TYPE) // type Ethernet
-                && (recvBuf[2] == 8) && (recvBuf[3] == 0) // protocol IP
-                && (recvBuf[4] == MAC_ADDR_LENGTH) // mac length
-                && (recvBuf[5] == IPV4_LENGTH) // IPv4 protocol size
-                && (recvBuf[6] == 0) && (recvBuf[7] == 2) // ARP reply
-                // verify desired IP address
-                && (recvBuf[14] == desiredIp[0]) && (recvBuf[15] == desiredIp[1])
-                && (recvBuf[16] == desiredIp[2]) && (recvBuf[17] == desiredIp[3]))
-            {
-                // looks good.  copy out the MAC
-                byte[] result = new byte[MAC_ADDR_LENGTH];
-                System.arraycopy(recvBuf, 8, result, 0, MAC_ADDR_LENGTH);
-                return result;
-            }
-        }
-
-        return null;
-    }
-
-    public static boolean doArp(String myMacAddress, LinkProperties linkProperties,
-            int timeoutMillis, int numArpPings, int minArpResponses) {
-        String interfaceName = linkProperties.getInterfaceName();
-        InetAddress inetAddress = null;
-        InetAddress gateway = null;
-        boolean success;
-
-        for (LinkAddress la : linkProperties.getLinkAddresses()) {
-            inetAddress = la.getAddress();
-            break;
-        }
-
-        for (RouteInfo route : linkProperties.getRoutes()) {
-            gateway = route.getGateway();
-            break;
-        }
-
-        try {
-            ArpPeer peer = new ArpPeer(interfaceName, inetAddress, myMacAddress, gateway);
-            int responses = 0;
-            for (int i=0; i < numArpPings; i++) {
-                if(peer.doArp(timeoutMillis) != null) responses++;
-            }
-            if (DBG) Log.d(TAG, "ARP test result: " + responses + "/" + numArpPings);
-            success = (responses >= minArpResponses);
-            peer.close();
-        } catch (SocketException se) {
-            //Consider an Arp socket creation issue as a successful Arp
-            //test to avoid any wifi connectivity issues
-            Log.e(TAG, "ARP test initiation failure: " + se);
-            success = true;
-        }
-        return success;
-    }
-
-    public void close() {
-        try {
-            mSocket.close();
-        } catch (IOException ex) {
-        }
-    }
-}
diff --git a/core/java/android/net/dhcp/DhcpAckPacket.java b/core/java/android/net/dhcp/DhcpAckPacket.java
index 4eca531..7b8be9c 100644
--- a/core/java/android/net/dhcp/DhcpAckPacket.java
+++ b/core/java/android/net/dhcp/DhcpAckPacket.java
@@ -19,7 +19,6 @@
 import java.net.InetAddress;
 import java.net.Inet4Address;
 import java.nio.ByteBuffer;
-import java.util.List;
 
 /**
  * This class implements the DHCP-ACK packet.
diff --git a/core/java/android/net/dhcp/DhcpOfferPacket.java b/core/java/android/net/dhcp/DhcpOfferPacket.java
index 3d79f4d..f1c30e1 100644
--- a/core/java/android/net/dhcp/DhcpOfferPacket.java
+++ b/core/java/android/net/dhcp/DhcpOfferPacket.java
@@ -19,7 +19,6 @@
 import java.net.InetAddress;
 import java.net.Inet4Address;
 import java.nio.ByteBuffer;
-import java.util.List;
 
 /**
  * This class implements the DHCP-OFFER packet.
diff --git a/core/java/android/net/dhcp/DhcpPacket.java b/core/java/android/net/dhcp/DhcpPacket.java
index 317a9b4..c7c25f0 100644
--- a/core/java/android/net/dhcp/DhcpPacket.java
+++ b/core/java/android/net/dhcp/DhcpPacket.java
@@ -1,8 +1,5 @@
 package android.net.dhcp;
 
-import android.util.Log;
-
-import java.io.UnsupportedEncodingException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
diff --git a/core/java/android/net/dhcp/DhcpStateMachine.java b/core/java/android/net/dhcp/DhcpStateMachine.java
index b6c384d..bc9a798 100644
--- a/core/java/android/net/dhcp/DhcpStateMachine.java
+++ b/core/java/android/net/dhcp/DhcpStateMachine.java
@@ -17,7 +17,6 @@
 package android.net.dhcp;
 
 import java.net.InetAddress;
-import java.nio.ByteBuffer;
 import java.util.List;
 
 /**
diff --git a/core/java/android/net/http/AndroidHttpClientConnection.java b/core/java/android/net/http/AndroidHttpClientConnection.java
index eb96679..6d48fce 100644
--- a/core/java/android/net/http/AndroidHttpClientConnection.java
+++ b/core/java/android/net/http/AndroidHttpClientConnection.java
@@ -16,8 +16,6 @@
 
 package android.net.http;
 
-import org.apache.http.Header;
-
 import org.apache.http.HttpConnection;
 import org.apache.http.HttpClientConnection;
 import org.apache.http.HttpConnectionMetrics;
@@ -27,12 +25,10 @@
 import org.apache.http.HttpInetConnection;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseFactory;
 import org.apache.http.NoHttpResponseException;
 import org.apache.http.StatusLine;
 import org.apache.http.entity.BasicHttpEntity;
 import org.apache.http.entity.ContentLengthStrategy;
-import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.impl.HttpConnectionMetricsImpl;
 import org.apache.http.impl.entity.EntitySerializer;
 import org.apache.http.impl.entity.StrictContentLengthStrategy;
diff --git a/core/java/android/net/http/Connection.java b/core/java/android/net/http/Connection.java
index 95cecd2..834ad69 100644
--- a/core/java/android/net/http/Connection.java
+++ b/core/java/android/net/http/Connection.java
@@ -21,7 +21,6 @@
 
 import java.io.IOException;
 import java.net.UnknownHostException;
-import java.util.ListIterator;
 import java.util.LinkedList;
 
 import javax.net.ssl.SSLHandshakeException;
diff --git a/core/java/android/net/http/ConnectionThread.java b/core/java/android/net/http/ConnectionThread.java
index 32191d2..d825530 100644
--- a/core/java/android/net/http/ConnectionThread.java
+++ b/core/java/android/net/http/ConnectionThread.java
@@ -19,8 +19,6 @@
 import android.content.Context;
 import android.os.SystemClock;
 
-import org.apache.http.HttpHost;
-
 import java.lang.Thread;
 
 /**
diff --git a/core/java/android/net/http/HttpConnection.java b/core/java/android/net/http/HttpConnection.java
index 6df86bf..edf8fed3 100644
--- a/core/java/android/net/http/HttpConnection.java
+++ b/core/java/android/net/http/HttpConnection.java
@@ -21,9 +21,7 @@
 import java.net.Socket;
 import java.io.IOException;
 
-import org.apache.http.HttpClientConnection;
 import org.apache.http.HttpHost;
-import org.apache.http.impl.DefaultHttpClientConnection;
 import org.apache.http.params.BasicHttpParams;
 import org.apache.http.params.HttpConnectionParams;
 
diff --git a/core/java/android/net/http/HttpResponseCache.java b/core/java/android/net/http/HttpResponseCache.java
index 269dfb8..2785a15 100644
--- a/core/java/android/net/http/HttpResponseCache.java
+++ b/core/java/android/net/http/HttpResponseCache.java
@@ -17,9 +17,6 @@
 package android.net.http;
 
 import android.content.Context;
-import com.android.okhttp.OkResponseCache;
-import com.android.okhttp.ResponseSource;
-import com.android.okhttp.internal.DiskLruCache;
 import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
@@ -32,7 +29,6 @@
 import java.util.List;
 import java.util.Map;
 import javax.net.ssl.HttpsURLConnection;
-import libcore.io.IoUtils;
 import org.apache.http.impl.client.DefaultHttpClient;
 
 /**
diff --git a/core/java/android/net/http/HttpsConnection.java b/core/java/android/net/http/HttpsConnection.java
index 7a12e53..6bf01e2 100644
--- a/core/java/android/net/http/HttpsConnection.java
+++ b/core/java/android/net/http/HttpsConnection.java
@@ -40,7 +40,6 @@
 import javax.net.ssl.X509TrustManager;
 import java.io.File;
 import java.io.IOException;
-import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.security.KeyManagementException;
 import java.security.cert.X509Certificate;
diff --git a/core/java/android/net/http/Request.java b/core/java/android/net/http/Request.java
index 8c0d503..76d7bb9 100644
--- a/core/java/android/net/http/Request.java
+++ b/core/java/android/net/http/Request.java
@@ -26,15 +26,12 @@
 
 import org.apache.http.entity.InputStreamEntity;
 import org.apache.http.Header;
-import org.apache.http.HttpClientConnection;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
-import org.apache.http.HttpVersion;
 import org.apache.http.ParseException;
 import org.apache.http.ProtocolVersion;
 
diff --git a/core/java/android/net/http/RequestQueue.java b/core/java/android/net/http/RequestQueue.java
index ce6b1ad..7d2da1b 100644
--- a/core/java/android/net/http/RequestQueue.java
+++ b/core/java/android/net/http/RequestQueue.java
@@ -29,10 +29,6 @@
 import android.net.NetworkInfo;
 import android.net.Proxy;
 import android.net.WebAddress;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.text.TextUtils;
 import android.util.Log;
 
 import java.io.InputStream;
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index 9c3e405..6840207 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -19,8 +19,6 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
-import android.os.Binder;
-import android.os.IBinder;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index 2b58818..de481cf 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -269,6 +269,7 @@
             "urn:epc:pat:", // 0x20
             "urn:epc:raw:", // 0x21
             "urn:epc:", // 0x22
+            "urn:nfc:", // 0x23
     };
 
     private static final int MAX_PAYLOAD_SIZE = 10 * (1 << 20);  // 10 MB payload limit
diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java
index 64aa2996..8240ea6 100644
--- a/core/java/android/nfc/tech/Ndef.java
+++ b/core/java/android/nfc/tech/Ndef.java
@@ -20,7 +20,6 @@
 import android.nfc.FormatException;
 import android.nfc.INfcTag;
 import android.nfc.NdefMessage;
-import android.nfc.NfcAdapter;
 import android.nfc.Tag;
 import android.nfc.TagLostException;
 import android.os.Bundle;
diff --git a/core/java/android/nfc/tech/NdefFormatable.java b/core/java/android/nfc/tech/NdefFormatable.java
index ffa6a2b..4175cd0 100644
--- a/core/java/android/nfc/tech/NdefFormatable.java
+++ b/core/java/android/nfc/tech/NdefFormatable.java
@@ -20,7 +20,6 @@
 import android.nfc.FormatException;
 import android.nfc.INfcTag;
 import android.nfc.NdefMessage;
-import android.nfc.NfcAdapter;
 import android.nfc.Tag;
 import android.nfc.TagLostException;
 import android.os.RemoteException;
diff --git a/core/java/android/os/BatteryProperties.java b/core/java/android/os/BatteryProperties.java
index 5df5214..2d67264 100644
--- a/core/java/android/os/BatteryProperties.java
+++ b/core/java/android/os/BatteryProperties.java
@@ -30,8 +30,6 @@
     public boolean batteryPresent;
     public int batteryLevel;
     public int batteryVoltage;
-    public int batteryCurrentNow;
-    public int batteryChargeCounter;
     public int batteryTemperature;
     public String batteryTechnology;
 
@@ -49,8 +47,6 @@
         batteryPresent = p.readInt() == 1 ? true : false;
         batteryLevel = p.readInt();
         batteryVoltage = p.readInt();
-        batteryCurrentNow = p.readInt();
-        batteryChargeCounter = p.readInt();
         batteryTemperature = p.readInt();
         batteryTechnology = p.readString();
     }
@@ -64,8 +60,6 @@
         p.writeInt(batteryPresent ? 1 : 0);
         p.writeInt(batteryLevel);
         p.writeInt(batteryVoltage);
-        p.writeInt(batteryCurrentNow);
-        p.writeInt(batteryChargeCounter);
         p.writeInt(batteryTemperature);
         p.writeString(batteryTechnology);
     }
diff --git a/core/java/android/os/BatteryProperty.aidl b/core/java/android/os/BatteryProperty.aidl
new file mode 100644
index 0000000..b3f2ec3
--- /dev/null
+++ b/core/java/android/os/BatteryProperty.aidl
@@ -0,0 +1,19 @@
+/*
+** 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.os;
+
+parcelable BatteryProperty;
diff --git a/core/java/android/os/BatteryProperty.java b/core/java/android/os/BatteryProperty.java
new file mode 100644
index 0000000..346f5de
--- /dev/null
+++ b/core/java/android/os/BatteryProperty.java
@@ -0,0 +1,70 @@
+/* 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.os;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * {@hide}
+ */
+public class BatteryProperty implements Parcelable {
+    /*
+     * Battery property identifiers.  These must match the values in
+     * frameworks/native/include/batteryservice/BatteryService.h
+     */
+    public static final int BATTERY_PROP_CHARGE_COUNTER = 1;
+    public static final int BATTERY_PROP_CURRENT_NOW = 2;
+    public static final int BATTERY_PROP_CURRENT_AVG = 3;
+
+    public int valueInt;
+
+    public BatteryProperty() {
+        valueInt = Integer.MIN_VALUE;
+    }
+
+    /*
+     * Parcel read/write code must be kept in sync with
+     * frameworks/native/services/batteryservice/BatteryProperty.cpp
+     */
+
+    private BatteryProperty(Parcel p) {
+        readFromParcel(p);
+    }
+
+    public void readFromParcel(Parcel p) {
+        valueInt = p.readInt();
+    }
+
+    public void writeToParcel(Parcel p, int flags) {
+        p.writeInt(valueInt);
+    }
+
+    public static final Parcelable.Creator<BatteryProperty> CREATOR
+        = new Parcelable.Creator<BatteryProperty>() {
+        public BatteryProperty createFromParcel(Parcel p) {
+            return new BatteryProperty(p);
+        }
+
+        public BatteryProperty[] newArray(int size) {
+            return new BatteryProperty[size];
+        }
+    };
+
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 9ada6e6..06fd8fb 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -26,7 +26,6 @@
 
 import android.content.pm.ApplicationInfo;
 import android.telephony.SignalStrength;
-import android.util.Log;
 import android.util.Printer;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -460,7 +459,7 @@
         public byte batteryHealth;
         public byte batteryPlugType;
         
-        public char batteryTemperature;
+        public short batteryTemperature;
         public char batteryVoltage;
         
         // Constants from SCREEN_BRIGHTNESS_*
@@ -537,7 +536,7 @@
             batteryHealth = (byte)((bat>>20)&0xf);
             batteryPlugType = (byte)((bat>>24)&0xf);
             bat = src.readInt();
-            batteryTemperature = (char)(bat&0xffff);
+            batteryTemperature = (short)(bat&0xffff);
             batteryVoltage = (char)((bat>>16)&0xffff);
             states = src.readInt();
         }
@@ -606,7 +605,7 @@
                 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
                         + Integer.toHexString(batteryLevelInt)
                         + " batteryLevel=" + batteryLevel
-                        + " batteryTemp=" + (int)batteryTemperature
+                        + " batteryTemp=" + batteryTemperature
                         + " batteryVolt=" + (int)batteryVoltage);
             }
             if (stateIntChanged) {
@@ -621,8 +620,8 @@
         }
         
         private int buildBatteryLevelInt() {
-            return ((((int)batteryLevel)<<24)&0xff000000)
-                    | ((((int)batteryTemperature)<<14)&0x00ffc000)
+            return ((((int)batteryLevel)<<25)&0xfe000000)
+                    | ((((int)batteryTemperature)<<14)&0x01ffc000)
                     | (((int)batteryVoltage)&0x00003fff);
         }
         
@@ -658,13 +657,13 @@
             
             if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
                 int batteryLevelInt = src.readInt();
-                batteryLevel = (byte)((batteryLevelInt>>24)&0xff);
-                batteryTemperature = (char)((batteryLevelInt>>14)&0x3ff);
+                batteryLevel = (byte)((batteryLevelInt>>25)&0x7f);
+                batteryTemperature = (short)((batteryLevelInt<<7)>>21);
                 batteryVoltage = (char)(batteryLevelInt&0x3fff);
                 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
                         + Integer.toHexString(batteryLevelInt)
                         + " batteryLevel=" + batteryLevel
-                        + " batteryTemp=" + (int)batteryTemperature
+                        + " batteryTemp=" + batteryTemperature
                         + " batteryVolt=" + (int)batteryVoltage);
             }
             
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index bc51a60..22e1476 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -49,7 +49,7 @@
     /** The manufacturer of the product/hardware. */
     public static final String MANUFACTURER = getString("ro.product.manufacturer");
 
-    /** The brand (e.g., carrier) the software is customized for, if any. */
+    /** The consumer-visible brand with which the product/hardware will be associated, if any. */
     public static final String BRAND = getString("ro.product.brand");
 
     /** The end-user-visible name for the end product. */
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index f9c1d31..af57507 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -380,7 +380,7 @@
                         SparseArray<? extends Parcelable> array =
                                 (SparseArray<? extends Parcelable>) obj;
                         for (int n = array.size() - 1; n >= 0; n--) {
-                            if ((array.get(n).describeContents()
+                            if ((array.valueAt(n).describeContents()
                                     & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
                                 fdFound = true;
                                 break;
diff --git a/core/java/android/os/CommonClock.java b/core/java/android/os/CommonClock.java
index 3a1da97..2ecf317 100644
--- a/core/java/android/os/CommonClock.java
+++ b/core/java/android/os/CommonClock.java
@@ -15,17 +15,8 @@
  */
 package android.os;
 
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
 import java.net.InetSocketAddress;
 import java.util.NoSuchElementException;
-import static libcore.io.OsConstants.*;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
 import android.os.Binder;
 import android.os.CommonTimeUtils;
 import android.os.IBinder;
diff --git a/core/java/android/os/CommonTimeConfig.java b/core/java/android/os/CommonTimeConfig.java
index 3355ee3..1f9fab5 100644
--- a/core/java/android/os/CommonTimeConfig.java
+++ b/core/java/android/os/CommonTimeConfig.java
@@ -15,7 +15,6 @@
  */
 package android.os;
 
-import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.NoSuchElementException;
 
diff --git a/core/java/android/os/CountDownTimer.java b/core/java/android/os/CountDownTimer.java
index 15e6405..c5b1146 100644
--- a/core/java/android/os/CountDownTimer.java
+++ b/core/java/android/os/CountDownTimer.java
@@ -16,8 +16,6 @@
 
 package android.os;
 
-import android.util.Log;
-
 /**
  * Schedule a countdown until a time in the future, with
  * regular notifications on intervals along the way.
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 974bf8d..7f167d5 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -26,7 +26,6 @@
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
-import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.io.Reader;
 import java.lang.reflect.Field;
@@ -41,7 +40,6 @@
 import org.apache.harmony.dalvik.ddmc.DdmServer;
 
 import dalvik.bytecode.OpcodeInfo;
-import dalvik.bytecode.Opcodes;
 import dalvik.system.VMDebug;
 
 
diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java
index e1c1678..27001dc 100644
--- a/core/java/android/os/DropBoxManager.java
+++ b/core/java/android/os/DropBoxManager.java
@@ -16,14 +16,11 @@
 
 package android.os;
 
-import android.util.Log;
-
 import com.android.internal.os.IDropBoxManagerService;
 
 import java.io.ByteArrayInputStream;
 import java.io.Closeable;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.zip.GZIPInputStream;
diff --git a/core/java/android/os/FileObserver.java b/core/java/android/os/FileObserver.java
index d633486..4e705e0 100644
--- a/core/java/android/os/FileObserver.java
+++ b/core/java/android/os/FileObserver.java
@@ -18,10 +18,7 @@
 
 import android.util.Log;
 
-import com.android.internal.os.RuntimeInit;
-
 import java.lang.ref.WeakReference;
-import java.util.ArrayList;
 import java.util.HashMap;
 
 /**
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index ff3e277..2d60df0 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -20,9 +20,7 @@
 import android.util.Slog;
 
 import libcore.io.ErrnoException;
-import libcore.io.IoUtils;
 import libcore.io.Libcore;
-import libcore.io.OsConstants;
 
 import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
diff --git a/core/java/android/os/IBatteryPropertiesRegistrar.aidl b/core/java/android/os/IBatteryPropertiesRegistrar.aidl
index 376f6c9..fd01802 100644
--- a/core/java/android/os/IBatteryPropertiesRegistrar.aidl
+++ b/core/java/android/os/IBatteryPropertiesRegistrar.aidl
@@ -17,6 +17,7 @@
 package android.os;
 
 import android.os.IBatteryPropertiesListener;
+import android.os.BatteryProperty;
 
 /**
  * {@hide}
@@ -25,4 +26,5 @@
 interface IBatteryPropertiesRegistrar {
     void registerListener(IBatteryPropertiesListener listener);
     void unregisterListener(IBatteryPropertiesListener listener);
+    int getProperty(in int id, out BatteryProperty prop);
 }
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index a2432d6..73a0f65 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -17,7 +17,6 @@
 package android.os;
 
 import java.io.FileDescriptor;
-import java.io.PrintWriter;
 
 /**
  * Base interface for a remotable object, the core part of a lightweight
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 21e9f6b..ff31130 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -18,7 +18,6 @@
 
 import android.util.Log;
 import android.util.Printer;
-import android.util.PrefixPrinter;
 
 /**
   * Class used to run a message loop for a thread.  Threads by default do
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index 799de5c..e90a457 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -126,6 +126,14 @@
     }
 
     Message next() {
+        // Return here if the message loop has already quit and been disposed.
+        // This can happen if the application tries to restart a looper after quit
+        // which is not supported.
+        final int ptr = mPtr;
+        if (ptr == 0) {
+            return null;
+        }
+
         int pendingIdleHandlerCount = -1; // -1 only during first iteration
         int nextPollTimeoutMillis = 0;
         for (;;) {
@@ -133,9 +141,7 @@
                 Binder.flushPendingCommands();
             }
 
-            // We can assume mPtr != 0 because the loop is obviously still running.
-            // The looper will not call this method after the loop quits.
-            nativePollOnce(mPtr, nextPollTimeoutMillis);
+            nativePollOnce(ptr, nextPollTimeoutMillis);
 
             synchronized (this) {
                 // Try to retrieve the next message.  Return if found.
diff --git a/core/java/android/os/NullVibrator.java b/core/java/android/os/NullVibrator.java
index ac6027f..af90bdb 100644
--- a/core/java/android/os/NullVibrator.java
+++ b/core/java/android/os/NullVibrator.java
@@ -16,8 +16,6 @@
 
 package android.os;
 
-import android.util.Log;
-
 /**
  * Vibrator implementation that does nothing.
  *
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 5273c20..86dc8b4 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -872,6 +872,8 @@
      */
     @Override
     public void writeToParcel(Parcel out, int flags) {
+        // WARNING: This must stay in sync with Parcel::readParcelFileDescriptor()
+        // in frameworks/native/libs/binder/Parcel.cpp
         if (mWrapped != null) {
             try {
                 mWrapped.writeToParcel(out, flags);
@@ -897,6 +899,8 @@
             = new Parcelable.Creator<ParcelFileDescriptor>() {
         @Override
         public ParcelFileDescriptor createFromParcel(Parcel in) {
+            // WARNING: This must stay in sync with Parcel::writeParcelFileDescriptor()
+            // in frameworks/native/libs/binder/Parcel.cpp
             final FileDescriptor fd = in.readRawFileDescriptor();
             FileDescriptor commChannel = null;
             if (in.readInt() != 0) {
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index cf9ddb3..057f516 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -377,7 +377,7 @@
      * @param gids Additional group-ids associated with the process.
      * @param debugFlags Additional flags.
      * @param targetSdkVersion The target SDK version for the app.
-     * @param seInfo null-ok SE Android information for the new process.
+     * @param seInfo null-ok SELinux information for the new process.
      * @param zygoteArgs Additional arguments to supply to the zygote process.
      * 
      * @return An object that describes the result of the attempt to start the process.
@@ -557,7 +557,7 @@
      * new process should setgroup() to.
      * @param debugFlags Additional flags.
      * @param targetSdkVersion The target SDK version for the app.
-     * @param seInfo null-ok SE Android information for the new process.
+     * @param seInfo null-ok SELinux information for the new process.
      * @param extraArgs Additional arguments to supply to the zygote process.
      * @return An object that describes the result of the attempt to start the process.
      * @throws ZygoteStartFailedEx if process start failed for any reason
@@ -892,19 +892,6 @@
     }
 
     /**
-     * Set the out-of-memory badness adjustment for a process.
-     * 
-     * @param pid The process identifier to set.
-     * @param amt Adjustment value -- linux allows -16 to +15.
-     * 
-     * @return Returns true if the underlying system supports this
-     *         feature, else false.
-     *         
-     * {@hide}
-     */
-    public static final native boolean setOomAdj(int pid, int amt);
-
-    /**
      * Adjust the swappiness level for a process.
      *
      * @param pid The process identifier to set.
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 5e20dec..b692ffde 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -32,10 +32,8 @@
 import java.security.PublicKey;
 import java.security.Signature;
 import java.security.SignatureException;
-import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
-import java.util.Collection;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -48,7 +46,7 @@
 import org.apache.harmony.security.pkcs7.ContentInfo;
 import org.apache.harmony.security.pkcs7.SignedData;
 import org.apache.harmony.security.pkcs7.SignerInfo;
-import org.apache.harmony.security.provider.cert.X509CertImpl;
+import org.apache.harmony.security.x509.Certificate;
 
 /**
  * RecoverySystem contains methods for interacting with the Android
@@ -93,9 +91,9 @@
     }
 
     /** @return the set of certs that can be used to sign an OTA package. */
-    private static HashSet<Certificate> getTrustedCerts(File keystore)
+    private static HashSet<X509Certificate> getTrustedCerts(File keystore)
         throws IOException, GeneralSecurityException {
-        HashSet<Certificate> trusted = new HashSet<Certificate>();
+        HashSet<X509Certificate> trusted = new HashSet<X509Certificate>();
         if (keystore == null) {
             keystore = DEFAULT_KEYSTORE;
         }
@@ -107,7 +105,7 @@
                 ZipEntry entry = entries.nextElement();
                 InputStream is = zip.getInputStream(entry);
                 try {
-                    trusted.add(cf.generateCertificate(is));
+                    trusted.add((X509Certificate) cf.generateCertificate(is));
                 } finally {
                     is.close();
                 }
@@ -201,21 +199,23 @@
             if (signedData == null) {
                 throw new IOException("signedData is null");
             }
-            Collection encCerts = signedData.getCertificates();
+            List<Certificate> encCerts = signedData.getCertificates();
             if (encCerts.isEmpty()) {
                 throw new IOException("encCerts is empty");
             }
             // Take the first certificate from the signature (packages
             // should contain only one).
-            Iterator it = encCerts.iterator();
+            Iterator<Certificate> it = encCerts.iterator();
             X509Certificate cert = null;
             if (it.hasNext()) {
-                cert = new X509CertImpl((org.apache.harmony.security.x509.Certificate)it.next());
+                CertificateFactory cf = CertificateFactory.getInstance("X.509");
+                InputStream is = new ByteArrayInputStream(it.next().getEncoded());
+                cert = (X509Certificate) cf.generateCertificate(is);
             } else {
                 throw new SignatureException("signature contains no certificates");
             }
 
-            List sigInfos = signedData.getSignerInfos();
+            List<SignerInfo> sigInfos = signedData.getSignerInfos();
             SignerInfo sigInfo;
             if (!sigInfos.isEmpty()) {
                 sigInfo = (SignerInfo)sigInfos.get(0);
@@ -226,12 +226,12 @@
             // Check that the public key of the certificate contained
             // in the package equals one of our trusted public keys.
 
-            HashSet<Certificate> trusted = getTrustedCerts(
+            HashSet<X509Certificate> trusted = getTrustedCerts(
                 deviceCertsZipFile == null ? DEFAULT_KEYSTORE : deviceCertsZipFile);
 
             PublicKey signatureKey = cert.getPublicKey();
             boolean verified = false;
-            for (Certificate c : trusted) {
+            for (X509Certificate c : trusted) {
                 if (c.getPublicKey().equals(signatureKey)) {
                     verified = true;
                     break;
diff --git a/core/java/android/os/Registrant.java b/core/java/android/os/Registrant.java
index c1780b9..705cc5d 100644
--- a/core/java/android/os/Registrant.java
+++ b/core/java/android/os/Registrant.java
@@ -20,7 +20,6 @@
 import android.os.Message;
 
 import java.lang.ref.WeakReference;
-import java.util.HashMap;
 
 /** @hide */
 public class Registrant
diff --git a/core/java/android/os/RegistrantList.java b/core/java/android/os/RegistrantList.java
index 56b9e2b..9ab61f5 100644
--- a/core/java/android/os/RegistrantList.java
+++ b/core/java/android/os/RegistrantList.java
@@ -17,10 +17,8 @@
 package android.os;
 
 import android.os.Handler;         
-import android.os.Message;         
 
 import java.util.ArrayList;
-import java.util.HashMap;
 
 /** @hide */
 public class RegistrantList
diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java
index c05a974..c9dd5d7 100644
--- a/core/java/android/os/SELinux.java
+++ b/core/java/android/os/SELinux.java
@@ -45,7 +45,7 @@
 
     /**
      * Set whether SELinux is permissive or enforcing.
-     * @param boolean representing whether to set SELinux to enforcing
+     * @param value representing whether to set SELinux to enforcing
      * @return a boolean representing whether the desired mode was set
      */
     public static final native boolean setSELinuxEnforce(boolean value);
@@ -60,7 +60,7 @@
     /**
      * Change the security context of an existing file object.
      * @param path representing the path of file object to relabel.
-     * @param con new security context given as a String.
+     * @param context new security context given as a String.
      * @return a boolean indicating whether the operation succeeded.
      */
     public static final native boolean setFileContext(String path, String context);
@@ -87,8 +87,6 @@
 
     /**
      * Gets the security context of a given process id.
-     * Use of this function is discouraged for Binder transactions.
-     * Use Binder.getCallingSecctx() instead.
      * @param pid an int representing the process id to check.
      * @return a String representing the security context of the given pid.
      */
@@ -102,15 +100,15 @@
 
     /**
      * Gets the value for the given SELinux boolean name.
-     * @param String The name of the SELinux boolean.
+     * @param name The name of the SELinux boolean.
      * @return a boolean indicating whether the SELinux boolean is set.
      */
     public static final native boolean getBooleanValue(String name);
 
     /**
      * Sets the value for the given SELinux boolean name.
-     * @param String The name of the SELinux boolean.
-     * @param Boolean The new value of the SELinux boolean.
+     * @param name The name of the SELinux boolean.
+     * @param value The new value of the SELinux boolean.
      * @return a boolean indicating whether or not the operation succeeded.
      */
     public static final native boolean setBooleanValue(String name, boolean value);
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 156600e..1479035 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -18,8 +18,6 @@
 
 import java.util.ArrayList;
 
-import android.util.Log;
-
 
 /**
  * Gives access to the system properties store.  The system properties
diff --git a/core/java/android/os/SystemService.java b/core/java/android/os/SystemService.java
index f345271..41e7546 100644
--- a/core/java/android/os/SystemService.java
+++ b/core/java/android/os/SystemService.java
@@ -16,8 +16,6 @@
 
 package android.os;
 
-import android.util.Slog;
-
 import com.google.android.collect.Maps;
 
 import java.util.HashMap;
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index bb3d296..57ed979 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -16,15 +16,16 @@
 
 package android.os;
 
-import android.util.Log;
-
 /**
  * Writes trace events to the system trace buffer.  These trace events can be
  * collected and visualized using the Systrace tool.
  *
- * This tracing mechanism is independent of the method tracing mechanism
+ * <p>This tracing mechanism is independent of the method tracing mechanism
  * offered by {@link Debug#startMethodTracing}.  In particular, it enables
  * tracing of events that occur across multiple processes.
+ * <p>For information about using the Systrace tool, read <a
+ * href="{@docRoot}tools/debugging/systrace.html">Analyzing Display and Performance
+ * with Systrace</a>.
  */
 public final class Trace {
     /*
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a3752a1..5d087ea 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -17,7 +17,6 @@
 
 import android.app.ActivityManagerNative;
 import android.content.Context;
-import android.content.RestrictionEntry;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
diff --git a/core/java/android/preference/CheckBoxPreference.java b/core/java/android/preference/CheckBoxPreference.java
index 1536760..1ce98b8 100644
--- a/core/java/android/preference/CheckBoxPreference.java
+++ b/core/java/android/preference/CheckBoxPreference.java
@@ -34,11 +34,16 @@
  */
 public class CheckBoxPreference extends TwoStatePreference {
 
-    public CheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.CheckBoxPreference, defStyle, 0);
+    public CheckBoxPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public CheckBoxPreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.CheckBoxPreference, defStyleAttr, defStyleRes);
         setSummaryOn(a.getString(com.android.internal.R.styleable.CheckBoxPreference_summaryOn));
         setSummaryOff(a.getString(com.android.internal.R.styleable.CheckBoxPreference_summaryOff));
         setDisableDependentsState(a.getBoolean(
diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java
index a643c8a..5275bc0 100644
--- a/core/java/android/preference/DialogPreference.java
+++ b/core/java/android/preference/DialogPreference.java
@@ -64,12 +64,13 @@
 
     /** Which button was clicked. */
     private int mWhichButtonClicked;
-    
-    public DialogPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.DialogPreference, defStyle, 0);
+
+    public DialogPreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.DialogPreference, defStyleAttr, defStyleRes);
         mDialogTitle = a.getString(com.android.internal.R.styleable.DialogPreference_dialogTitle);
         if (mDialogTitle == null) {
             // Fallback on the regular title of the preference
@@ -83,13 +84,20 @@
         mDialogLayoutResId = a.getResourceId(com.android.internal.R.styleable.DialogPreference_dialogLayout,
                 mDialogLayoutResId);
         a.recycle();
-        
+    }
+
+    public DialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
     public DialogPreference(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle);
     }
-    
+
+    public DialogPreference(Context context) {
+        this(context, null);
+    }
+
     /**
      * Sets the title of the dialog. This will be shown on subsequent dialogs.
      * 
diff --git a/core/java/android/preference/EditTextPreference.java b/core/java/android/preference/EditTextPreference.java
index aa27627..ff37042 100644
--- a/core/java/android/preference/EditTextPreference.java
+++ b/core/java/android/preference/EditTextPreference.java
@@ -49,9 +49,9 @@
     private EditText mEditText;
     
     private String mText;
-    
-    public EditTextPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+
+    public EditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         
         mEditText = new EditText(context, attrs);
         
@@ -67,6 +67,10 @@
         mEditText.setEnabled(true);
     }
 
+    public EditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public EditTextPreference(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.editTextPreferenceStyle);
     }
diff --git a/core/java/android/preference/ListPreference.java b/core/java/android/preference/ListPreference.java
index 9edf112..8081a54 100644
--- a/core/java/android/preference/ListPreference.java
+++ b/core/java/android/preference/ListPreference.java
@@ -42,12 +42,12 @@
     private String mSummary;
     private int mClickedDialogEntryIndex;
     private boolean mValueSet;
-    
-    public ListPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.ListPreference, 0, 0);
+
+    public ListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ListPreference, defStyleAttr, defStyleRes);
         mEntries = a.getTextArray(com.android.internal.R.styleable.ListPreference_entries);
         mEntryValues = a.getTextArray(com.android.internal.R.styleable.ListPreference_entryValues);
         a.recycle();
@@ -56,11 +56,19 @@
          * in the Preference class.
          */
         a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.Preference, 0, 0);
+                com.android.internal.R.styleable.Preference, defStyleAttr, defStyleRes);
         mSummary = a.getString(com.android.internal.R.styleable.Preference_summary);
         a.recycle();
     }
 
+    public ListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ListPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle);
+    }
+
     public ListPreference(Context context) {
         this(context, null);
     }
diff --git a/core/java/android/preference/MultiCheckPreference.java b/core/java/android/preference/MultiCheckPreference.java
index 6953075..57c906d 100644
--- a/core/java/android/preference/MultiCheckPreference.java
+++ b/core/java/android/preference/MultiCheckPreference.java
@@ -40,12 +40,13 @@
     private boolean[] mSetValues;
     private boolean[] mOrigValues;
     private String mSummary;
-    
-    public MultiCheckPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.ListPreference, 0, 0);
+
+    public MultiCheckPreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ListPreference, defStyleAttr, defStyleRes);
         mEntries = a.getTextArray(com.android.internal.R.styleable.ListPreference_entries);
         if (mEntries != null) {
             setEntries(mEntries);
@@ -63,6 +64,14 @@
         a.recycle();
     }
 
+    public MultiCheckPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public MultiCheckPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle);
+    }
+
     public MultiCheckPreference(Context context) {
         this(context, null);
     }
diff --git a/core/java/android/preference/MultiSelectListPreference.java b/core/java/android/preference/MultiSelectListPreference.java
index 553ce80..6c4c20f 100644
--- a/core/java/android/preference/MultiSelectListPreference.java
+++ b/core/java/android/preference/MultiSelectListPreference.java
@@ -44,16 +44,26 @@
     private Set<String> mValues = new HashSet<String>();
     private Set<String> mNewValues = new HashSet<String>();
     private boolean mPreferenceChanged;
-    
-    public MultiSelectListPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.MultiSelectListPreference, 0, 0);
+
+    public MultiSelectListPreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.MultiSelectListPreference, defStyleAttr,
+                defStyleRes);
         mEntries = a.getTextArray(com.android.internal.R.styleable.MultiSelectListPreference_entries);
         mEntryValues = a.getTextArray(com.android.internal.R.styleable.MultiSelectListPreference_entryValues);
         a.recycle();
     }
+
+    public MultiSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public MultiSelectListPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle);
+    }
     
     public MultiSelectListPreference(Context context) {
         this(context, null);
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index f7d1eb7..76fccc7 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -188,30 +188,33 @@
 
     /**
      * Perform inflation from XML and apply a class-specific base style. This
-     * constructor of Preference allows subclasses to use their own base
-     * style when they are inflating. For example, a {@link CheckBoxPreference}
+     * constructor of Preference allows subclasses to use their own base style
+     * when they are inflating. For example, a {@link CheckBoxPreference}
      * constructor calls this version of the super class constructor and
-     * supplies {@code android.R.attr.checkBoxPreferenceStyle} for <var>defStyle</var>.
-     * This allows the theme's checkbox preference style to modify all of the base
-     * preference attributes as well as the {@link CheckBoxPreference} class's
-     * attributes.
-     * 
+     * supplies {@code android.R.attr.checkBoxPreferenceStyle} for
+     * <var>defStyleAttr</var>. This allows the theme's checkbox preference
+     * style to modify all of the base preference attributes as well as the
+     * {@link CheckBoxPreference} class's attributes.
+     *
      * @param context The Context this is associated with, through which it can
-     *            access the current theme, resources, {@link SharedPreferences},
-     *            etc.
-     * @param attrs The attributes of the XML tag that is inflating the preference.
-     * @param defStyle The default style to apply to this preference. If 0, no style
-     *            will be applied (beyond what is included in the theme). This
-     *            may either be an attribute resource, whose value will be
-     *            retrieved from the current theme, or an explicit style
-     *            resource.
+     *            access the current theme, resources,
+     *            {@link SharedPreferences}, etc.
+     * @param attrs The attributes of the XML tag that is inflating the
+     *            preference.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *            reference to a style resource that supplies default values for
+     *            the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *            supplies default values for the view, used only if
+     *            defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *            to not look for defaults.
      * @see #Preference(Context, AttributeSet)
      */
-    public Preference(Context context, AttributeSet attrs, int defStyle) {
+    public Preference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         mContext = context;
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.Preference, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.Preference, defStyleAttr, defStyleRes);
         for (int i = a.getIndexCount(); i >= 0; i--) {
             int attr = a.getIndex(i); 
             switch (attr) {
@@ -281,6 +284,30 @@
             mCanRecycleLayout = false;
         }
     }
+
+    /**
+     * Perform inflation from XML and apply a class-specific base style. This
+     * constructor of Preference allows subclasses to use their own base style
+     * when they are inflating. For example, a {@link CheckBoxPreference}
+     * constructor calls this version of the super class constructor and
+     * supplies {@code android.R.attr.checkBoxPreferenceStyle} for
+     * <var>defStyleAttr</var>. This allows the theme's checkbox preference
+     * style to modify all of the base preference attributes as well as the
+     * {@link CheckBoxPreference} class's attributes.
+     *
+     * @param context The Context this is associated with, through which it can
+     *            access the current theme, resources,
+     *            {@link SharedPreferences}, etc.
+     * @param attrs The attributes of the XML tag that is inflating the
+     *            preference.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *            reference to a style resource that supplies default values for
+     *            the view. Can be 0 to not look for defaults.
+     * @see #Preference(Context, AttributeSet)
+     */
+    public Preference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
     
     /**
      * Constructor that is called when inflating a Preference from XML. This is
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 2ab5a91..0d14a9e2 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -794,8 +794,8 @@
                 if ("header".equals(nodeName)) {
                     Header header = new Header();
 
-                    TypedArray sa = getResources().obtainAttributes(attrs,
-                            com.android.internal.R.styleable.PreferenceHeader);
+                    TypedArray sa = obtainStyledAttributes(
+                            attrs, com.android.internal.R.styleable.PreferenceHeader);
                     header.id = sa.getResourceId(
                             com.android.internal.R.styleable.PreferenceHeader_id,
                             (int)HEADER_ID_UNDEFINED);
diff --git a/core/java/android/preference/PreferenceCategory.java b/core/java/android/preference/PreferenceCategory.java
index 229a96a..253481b 100644
--- a/core/java/android/preference/PreferenceCategory.java
+++ b/core/java/android/preference/PreferenceCategory.java
@@ -16,8 +16,6 @@
 
 package android.preference;
 
-import java.util.Map;
-
 import android.content.Context;
 import android.util.AttributeSet;
 
@@ -34,9 +32,14 @@
  */
 public class PreferenceCategory extends PreferenceGroup {
     private static final String TAG = "PreferenceCategory";
-    
-    public PreferenceCategory(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+
+    public PreferenceCategory(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public PreferenceCategory(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
     public PreferenceCategory(Context context, AttributeSet attrs) {
diff --git a/core/java/android/preference/PreferenceFrameLayout.java b/core/java/android/preference/PreferenceFrameLayout.java
index 75372aa..886338f 100644
--- a/core/java/android/preference/PreferenceFrameLayout.java
+++ b/core/java/android/preference/PreferenceFrameLayout.java
@@ -16,7 +16,6 @@
 
 package android.preference;
 
-import android.app.FragmentBreadCrumbs;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
@@ -45,10 +44,15 @@
         this(context, attrs, com.android.internal.R.attr.preferenceFrameLayoutStyle);
     }
 
-    public PreferenceFrameLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.PreferenceFrameLayout, defStyle, 0);
+    public PreferenceFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public PreferenceFrameLayout(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.PreferenceFrameLayout, defStyleAttr, defStyleRes);
 
         float density = context.getResources().getDisplayMetrics().density;
         int defaultBorderTop = (int) (density * DEFAULT_BORDER_TOP + 0.5f);
diff --git a/core/java/android/preference/PreferenceGroup.java b/core/java/android/preference/PreferenceGroup.java
index 5f8c78d..2d35b1b 100644
--- a/core/java/android/preference/PreferenceGroup.java
+++ b/core/java/android/preference/PreferenceGroup.java
@@ -55,19 +55,23 @@
     private int mCurrentPreferenceOrder = 0;
 
     private boolean mAttachedToActivity = false;
-    
-    public PreferenceGroup(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+
+    public PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         mPreferenceList = new ArrayList<Preference>();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.PreferenceGroup, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.PreferenceGroup, defStyleAttr, defStyleRes);
         mOrderingAsAdded = a.getBoolean(com.android.internal.R.styleable.PreferenceGroup_orderingFromXml,
                 mOrderingAsAdded);
         a.recycle();
     }
 
+    public PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public PreferenceGroup(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
diff --git a/core/java/android/preference/PreferenceInflater.java b/core/java/android/preference/PreferenceInflater.java
index c21aa18..727fbca 100644
--- a/core/java/android/preference/PreferenceInflater.java
+++ b/core/java/android/preference/PreferenceInflater.java
@@ -19,16 +19,13 @@
 import com.android.internal.util.XmlUtils;
 
 import java.io.IOException;
-import java.util.Map;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
-import android.app.AliasActivity;
 import android.content.Context;
 import android.content.Intent;
 import android.util.AttributeSet;
-import android.util.Log;
 
 /**
  * The {@link PreferenceInflater} is used to inflate preference hierarchies from
diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java
index db80676..b1317e6 100644
--- a/core/java/android/preference/PreferenceScreen.java
+++ b/core/java/android/preference/PreferenceScreen.java
@@ -27,7 +27,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.Window;
-import android.widget.AbsListView;
 import android.widget.Adapter;
 import android.widget.AdapterView;
 import android.widget.ListAdapter;
diff --git a/core/java/android/preference/RingtonePreference.java b/core/java/android/preference/RingtonePreference.java
index 2ebf294..488a0c4 100644
--- a/core/java/android/preference/RingtonePreference.java
+++ b/core/java/android/preference/RingtonePreference.java
@@ -50,11 +50,11 @@
     
     private int mRequestCode;
 
-    public RingtonePreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.RingtonePreference, defStyle, 0);
+    public RingtonePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.RingtonePreference, defStyleAttr, defStyleRes);
         mRingtoneType = a.getInt(com.android.internal.R.styleable.RingtonePreference_ringtoneType,
                 RingtoneManager.TYPE_RINGTONE);
         mShowDefault = a.getBoolean(com.android.internal.R.styleable.RingtonePreference_showDefault,
@@ -64,6 +64,10 @@
         a.recycle();
     }
 
+    public RingtonePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public RingtonePreference(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.ringtonePreferenceStyle);
     }
diff --git a/core/java/android/preference/SeekBarDialogPreference.java b/core/java/android/preference/SeekBarDialogPreference.java
index 0e89b16..9a08827 100644
--- a/core/java/android/preference/SeekBarDialogPreference.java
+++ b/core/java/android/preference/SeekBarDialogPreference.java
@@ -32,8 +32,9 @@
 
     private Drawable mMyIcon;
 
-    public SeekBarDialogPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
+    public SeekBarDialogPreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         setDialogLayoutResource(com.android.internal.R.layout.seekbar_dialog);
         createActionButtons();
@@ -43,6 +44,18 @@
         setDialogIcon(null);
     }
 
+    public SeekBarDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public SeekBarDialogPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle);
+    }
+
+    public SeekBarDialogPreference(Context context) {
+        this(context, null);
+    }
+
     // Allow subclasses to override the action buttons
     public void createActionButtons() {
         setPositiveButtonText(android.R.string.ok);
diff --git a/core/java/android/preference/SeekBarPreference.java b/core/java/android/preference/SeekBarPreference.java
index 7133d3a..e32890d 100644
--- a/core/java/android/preference/SeekBarPreference.java
+++ b/core/java/android/preference/SeekBarPreference.java
@@ -37,15 +37,20 @@
     private boolean mTrackingTouch;
 
     public SeekBarPreference(
-            Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.ProgressBar, defStyle, 0);
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ProgressBar, defStyleAttr, defStyleRes);
         setMax(a.getInt(com.android.internal.R.styleable.ProgressBar_max, mMax));
         a.recycle();
         setLayoutResource(com.android.internal.R.layout.preference_widget_seekbar);
     }
 
+    public SeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public SeekBarPreference(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
diff --git a/core/java/android/preference/SwitchPreference.java b/core/java/android/preference/SwitchPreference.java
index 8bac6bd..76ef544 100644
--- a/core/java/android/preference/SwitchPreference.java
+++ b/core/java/android/preference/SwitchPreference.java
@@ -60,13 +60,19 @@
      *
      * @param context The Context that will style this preference
      * @param attrs Style attributes that differ from the default
-     * @param defStyle Theme attribute defining the default style options
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
      */
-    public SwitchPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.SwitchPreference, defStyle, 0);
+                com.android.internal.R.styleable.SwitchPreference, defStyleAttr, defStyleRes);
         setSummaryOn(a.getString(com.android.internal.R.styleable.SwitchPreference_summaryOn));
         setSummaryOff(a.getString(com.android.internal.R.styleable.SwitchPreference_summaryOff));
         setSwitchTextOn(a.getString(
@@ -83,6 +89,19 @@
      *
      * @param context The Context that will style this preference
      * @param attrs Style attributes that differ from the default
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     */
+    public SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * Construct a new SwitchPreference with the given style options.
+     *
+     * @param context The Context that will style this preference
+     * @param attrs Style attributes that differ from the default
      */
     public SwitchPreference(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.switchPreferenceStyle);
diff --git a/core/java/android/preference/TwoStatePreference.java b/core/java/android/preference/TwoStatePreference.java
index af83953..6f8be1f 100644
--- a/core/java/android/preference/TwoStatePreference.java
+++ b/core/java/android/preference/TwoStatePreference.java
@@ -42,9 +42,13 @@
     private boolean mSendClickAccessibilityEvent;
     private boolean mDisableDependentsState;
 
+    public TwoStatePreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
 
-    public TwoStatePreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TwoStatePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
     public TwoStatePreference(Context context, AttributeSet attrs) {
diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java
index dc683a6..29f2545 100644
--- a/core/java/android/preference/VolumePreference.java
+++ b/core/java/android/preference/VolumePreference.java
@@ -51,15 +51,24 @@
     /** May be null if the dialog isn't visible. */
     private SeekBarVolumizer mSeekBarVolumizer;
 
-    public VolumePreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
+    public VolumePreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.VolumePreference, 0, 0);
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.VolumePreference, defStyleAttr, defStyleRes);
         mStreamType = a.getInt(android.R.styleable.VolumePreference_streamType, 0);
         a.recycle();
     }
 
+    public VolumePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public VolumePreference(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
     public void setStreamType(int streamType) {
         mStreamType = streamType;
     }
diff --git a/core/java/android/provider/Contacts.java b/core/java/android/provider/Contacts.java
index c7e3c08..9e2aacd 100644
--- a/core/java/android/provider/Contacts.java
+++ b/core/java/android/provider/Contacts.java
@@ -26,7 +26,6 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.net.Uri;
-import android.os.Build;
 import android.text.TextUtils;
 import android.util.Log;
 import android.widget.ImageView;
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index b16df28..daa9881 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -45,9 +45,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * <p>
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 86d3cf8..f0520b5 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -257,8 +257,6 @@
          * {@link #MIME_TYPE_DIR}.
          *
          * @see #COLUMN_FLAGS
-         * @see DocumentsContract#createDocument(ContentResolver, Uri, String,
-         *      String)
          * @see DocumentsProvider#createDocument(String, String, String)
          */
         public static final int FLAG_DIR_SUPPORTS_CREATE = 1 << 3;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7f24539..0dffc17 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3252,9 +3252,14 @@
 
         /**
          * A 64-bit number (as a hex string) that is randomly
-         * generated on the device's first boot and should remain
-         * constant for the lifetime of the device.  (The value may
-         * change if a factory reset is performed on the device.)
+         * generated when the user first sets up the device and should remain
+         * constant for the lifetime of the user's device. The value may
+         * change if a factory reset is performed on the device.
+         * <p class="note"><strong>Note:</strong> When a device has <a
+         * href="{@docRoot}about/versions/android-4.2.html#MultipleUsers">multiple users</a>
+         * (available on certain devices running Android 4.2 or higher), each user appears as a
+         * completely separate device, so the {@code ANDROID_ID} value is unique to each
+         * user.</p>
          */
         public static final String ANDROID_ID = "android_id";
 
@@ -3759,6 +3764,97 @@
                 "accessibility_captioning_font_scale";
 
         /**
+         * Setting that specifies whether the quick setting tile for display
+         * color inversion is enabled.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_INVERSION_QUICK_SETTING_ENABLED =
+                "accessibility_display_inversion_quick_setting_enabled";
+
+        /**
+         * Setting that specifies whether display color inversion is enabled.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED =
+                "accessibility_display_inversion_enabled";
+
+        /**
+         * Integer property that specifies the type of color inversion to
+         * perform. Valid values are defined in AccessibilityManager.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_INVERSION =
+                "accessibility_display_inversion";
+
+        /**
+         * Setting that specifies whether the quick setting tile for display
+         * color space adjustment is enabled.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_DALTONIZER_QUICK_SETTING_ENABLED =
+                "accessibility_display_daltonizer_quick_setting_enabled";
+
+        /**
+         * Setting that specifies whether display color space adjustment is
+         * enabled.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED =
+                "accessibility_display_daltonizer_enabled";
+
+        /**
+         * Integer property that specifies the type of color space adjustment to
+         * perform. Valid values are defined in AccessibilityManager.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_DALTONIZER =
+                "accessibility_display_daltonizer";
+
+        /**
+         * Setting that specifies whether the quick setting tile for display
+         * contrast enhancement is enabled.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_CONTRAST_QUICK_SETTING_ENABLED =
+                "accessibility_display_contrast_quick_setting_enabled";
+
+        /**
+         * Setting that specifies whether display contrast enhancement is
+         * enabled.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED =
+                "accessibility_display_contrast_enabled";
+
+        /**
+         * Floating point property that specifies display contrast adjustment.
+         * Valid range is [0, ...] where 0 is gray, 1 is normal, and higher
+         * values indicate enhanced contrast.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_CONTRAST =
+                "accessibility_display_contrast";
+
+        /**
+         * Floating point property that specifies display brightness adjustment.
+         * Valid range is [-1, 1] where -1 is black, 0 is default, and 1 is
+         * white.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_BRIGHTNESS =
+                "accessibility_display_brightness";
+
+        /**
          * The timout for considering a press to be a long press in milliseconds.
          * @hide
          */
diff --git a/core/java/android/service/textservice/SpellCheckerService.java b/core/java/android/service/textservice/SpellCheckerService.java
index 77b22ed..acfef82 100644
--- a/core/java/android/service/textservice/SpellCheckerService.java
+++ b/core/java/android/service/textservice/SpellCheckerService.java
@@ -32,7 +32,6 @@
 import android.view.textservice.SentenceSuggestionsInfo;
 import android.view.textservice.SuggestionsInfo;
 import android.view.textservice.TextInfo;
-import android.widget.SpellChecker;
 
 import java.lang.ref.WeakReference;
 import java.text.BreakIterator;
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 5db8168..03ce4e0 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -38,7 +38,6 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.util.Log;
-import android.util.LogPrinter;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.IWindowSession;
diff --git a/core/java/android/speech/srec/Recognizer.java b/core/java/android/speech/srec/Recognizer.java
index db5d8fd..4bdaf5b 100644
--- a/core/java/android/speech/srec/Recognizer.java
+++ b/core/java/android/speech/srec/Recognizer.java
@@ -22,8 +22,6 @@
 
 package android.speech.srec;
 
-import android.util.Log;
-
 import java.io.File;
 import java.io.InputStream;
 import java.io.IOException;
diff --git a/core/java/android/speech/tts/AbstractEventLogger.java b/core/java/android/speech/tts/AbstractEventLogger.java
new file mode 100644
index 0000000..37f8656
--- /dev/null
+++ b/core/java/android/speech/tts/AbstractEventLogger.java
@@ -0,0 +1,124 @@
+/*
+ * 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.speech.tts;
+
+import android.os.SystemClock;
+
+/**
+ * Base class for storing data about a given speech synthesis request to the
+ * event logs. The data that is logged depends on actual implementation. Note
+ * that {@link AbstractEventLogger#onAudioDataWritten()} and
+ * {@link AbstractEventLogger#onEngineComplete()} must be called from a single
+ * thread (usually the audio playback thread}.
+ */
+abstract class AbstractEventLogger {
+    protected final String mServiceApp;
+    protected final int mCallerUid;
+    protected final int mCallerPid;
+    protected final long mReceivedTime;
+    protected long mPlaybackStartTime = -1;
+
+    private volatile long mRequestProcessingStartTime = -1;
+    private volatile long mEngineStartTime = -1;
+    private volatile long mEngineCompleteTime = -1;
+
+    private boolean mLogWritten = false;
+
+    AbstractEventLogger(int callerUid, int callerPid, String serviceApp) {
+        mCallerUid = callerUid;
+        mCallerPid = callerPid;
+        mServiceApp = serviceApp;
+        mReceivedTime = SystemClock.elapsedRealtime();
+    }
+
+    /**
+     * Notifies the logger that this request has been selected from
+     * the processing queue for processing. Engine latency / total time
+     * is measured from this baseline.
+     */
+    public void onRequestProcessingStart() {
+        mRequestProcessingStartTime = SystemClock.elapsedRealtime();
+    }
+
+    /**
+     * Notifies the logger that a chunk of data has been received from
+     * the engine. Might be called multiple times.
+     */
+    public void onEngineDataReceived() {
+        if (mEngineStartTime == -1) {
+            mEngineStartTime = SystemClock.elapsedRealtime();
+        }
+    }
+
+    /**
+     * Notifies the logger that the engine has finished processing data.
+     * Will be called exactly once.
+     */
+    public void onEngineComplete() {
+        mEngineCompleteTime = SystemClock.elapsedRealtime();
+    }
+
+    /**
+     * Notifies the logger that audio playback has started for some section
+     * of the synthesis. This is normally some amount of time after the engine
+     * has synthesized data and varies depending on utterances and
+     * other audio currently in the queue.
+     */
+    public void onAudioDataWritten() {
+        // For now, keep track of only the first chunk of audio
+        // that was played.
+        if (mPlaybackStartTime == -1) {
+            mPlaybackStartTime = SystemClock.elapsedRealtime();
+        }
+    }
+
+    /**
+     * Notifies the logger that the current synthesis has completed.
+     * All available data is not logged.
+     */
+    public void onCompleted(int statusCode) {
+        if (mLogWritten) {
+            return;
+        } else {
+            mLogWritten = true;
+        }
+
+        long completionTime = SystemClock.elapsedRealtime();
+
+        // We don't report latency for stopped syntheses because their overall
+        // total time spent will be inaccurate (will not correlate with
+        // the length of the utterance).
+
+        // onAudioDataWritten() should normally always be called, and hence mPlaybackStartTime
+        // should be set, if an error does not occur.
+        if (statusCode != TextToSpeechClient.Status.SUCCESS
+                || mPlaybackStartTime == -1 || mEngineCompleteTime == -1) {
+            logFailure(statusCode);
+            return;
+        }
+
+        final long audioLatency = mPlaybackStartTime - mReceivedTime;
+        final long engineLatency = mEngineStartTime - mRequestProcessingStartTime;
+        final long engineTotal = mEngineCompleteTime - mRequestProcessingStartTime;
+        logSuccess(audioLatency, engineLatency, engineTotal);
+    }
+
+    protected abstract void logFailure(int statusCode);
+    protected abstract void logSuccess(long audioLatency, long engineLatency,
+            long engineTotal);
+
+
+}
diff --git a/core/java/android/speech/tts/AbstractSynthesisCallback.java b/core/java/android/speech/tts/AbstractSynthesisCallback.java
index c7a4af0..91e119b 100644
--- a/core/java/android/speech/tts/AbstractSynthesisCallback.java
+++ b/core/java/android/speech/tts/AbstractSynthesisCallback.java
@@ -15,15 +15,28 @@
  */
 package android.speech.tts;
 
+
 /**
  * Defines additional methods the synthesis callback must implement that
  * are private to the TTS service implementation.
+ *
+ * All of these class methods (with the exception of {@link #stop()}) can be only called on the
+ * synthesis thread, while inside
+ * {@link TextToSpeechService#onSynthesizeText} or {@link TextToSpeechService#onSynthesizeTextV2}.
+ * {@link #stop()} is the exception, it may be called from multiple threads.
  */
 abstract class AbstractSynthesisCallback implements SynthesisCallback {
+    /** If true, request comes from V2 TTS interface */
+    protected final boolean mClientIsUsingV2;
+
     /**
-     * Checks whether the synthesis request completed successfully.
+     * Constructor.
+     * @param clientIsUsingV2 If true, this callback will be used inside
+     *         {@link TextToSpeechService#onSynthesizeTextV2} method.
      */
-    abstract boolean isDone();
+    AbstractSynthesisCallback(boolean clientIsUsingV2) {
+        mClientIsUsingV2 = clientIsUsingV2;
+    }
 
     /**
      * Aborts the speech request.
@@ -31,4 +44,16 @@
      * Can be called from multiple threads.
      */
     abstract void stop();
+
+    /**
+     * Get status code for a "stop".
+     *
+     * V2 Clients will receive special status, V1 clients will receive standard error.
+     *
+     * This method should only be called on the synthesis thread,
+     * while in {@link TextToSpeechService#onSynthesizeText}.
+     */
+    int errorCodeOnStop() {
+        return mClientIsUsingV2 ? TextToSpeechClient.Status.STOPPED : TextToSpeech.ERROR;
+    }
 }
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java
index d63f605..dcf49b0 100644
--- a/core/java/android/speech/tts/AudioPlaybackHandler.java
+++ b/core/java/android/speech/tts/AudioPlaybackHandler.java
@@ -43,7 +43,7 @@
             return;
         }
 
-        item.stop(false);
+        item.stop(TextToSpeechClient.Status.STOPPED);
     }
 
     public void enqueue(PlaybackQueueItem item) {
diff --git a/core/java/android/speech/tts/AudioPlaybackQueueItem.java b/core/java/android/speech/tts/AudioPlaybackQueueItem.java
index 1a1fda81..c514639 100644
--- a/core/java/android/speech/tts/AudioPlaybackQueueItem.java
+++ b/core/java/android/speech/tts/AudioPlaybackQueueItem.java
@@ -53,7 +53,7 @@
         dispatcher.dispatchOnStart();
         mPlayer = MediaPlayer.create(mContext, mUri);
         if (mPlayer == null) {
-            dispatcher.dispatchOnError();
+            dispatcher.dispatchOnError(TextToSpeechClient.Status.ERROR_OUTPUT);
             return;
         }
 
@@ -83,9 +83,9 @@
         }
 
         if (mFinished) {
-            dispatcher.dispatchOnDone();
+            dispatcher.dispatchOnSuccess();
         } else {
-            dispatcher.dispatchOnError();
+            dispatcher.dispatchOnStop();
         }
     }
 
@@ -99,7 +99,7 @@
     }
 
     @Override
-    void stop(boolean isError) {
+    void stop(int errorCode) {
         mDone.open();
     }
 }
diff --git a/core/java/android/speech/tts/EventLogTags.logtags b/core/java/android/speech/tts/EventLogTags.logtags
index f8654ad..e209a28 100644
--- a/core/java/android/speech/tts/EventLogTags.logtags
+++ b/core/java/android/speech/tts/EventLogTags.logtags
@@ -4,3 +4,6 @@
 
 76001 tts_speak_success (engine|3),(caller_uid|1),(caller_pid|1),(length|1),(locale|3),(rate|1),(pitch|1),(engine_latency|2|3),(engine_total|2|3),(audio_latency|2|3)
 76002 tts_speak_failure (engine|3),(caller_uid|1),(caller_pid|1),(length|1),(locale|3),(rate|1),(pitch|1)
+
+76003 tts_v2_speak_success (engine|3),(caller_uid|1),(caller_pid|1),(length|1),(request_config|3),(engine_latency|2|3),(engine_total|2|3),(audio_latency|2|3)
+76004 tts_v2_speak_failure (engine|3),(caller_uid|1),(caller_pid|1),(length|1),(request_config|3), (statusCode|1)
diff --git a/core/java/android/speech/tts/EventLogger.java b/core/java/android/speech/tts/EventLogger.java
deleted file mode 100644
index 82ed4dd..0000000
--- a/core/java/android/speech/tts/EventLogger.java
+++ /dev/null
@@ -1,178 +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.speech.tts;
-
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.Log;
-
-/**
- * Writes data about a given speech synthesis request to the event logs.
- * The data that is logged includes the calling app, length of the utterance,
- * speech rate / pitch and the latency and overall time taken.
- *
- * Note that {@link EventLogger#onStopped()} and {@link EventLogger#onError()}
- * might be called from any thread, but on {@link EventLogger#onAudioDataWritten()} and
- * {@link EventLogger#onComplete()} must be called from a single thread
- * (usually the audio playback thread}
- */
-class EventLogger {
-    private final SynthesisRequest mRequest;
-    private final String mServiceApp;
-    private final int mCallerUid;
-    private final int mCallerPid;
-    private final long mReceivedTime;
-    private long mPlaybackStartTime = -1;
-    private volatile long mRequestProcessingStartTime = -1;
-    private volatile long mEngineStartTime = -1;
-    private volatile long mEngineCompleteTime = -1;
-
-    private volatile boolean mError = false;
-    private volatile boolean mStopped = false;
-    private boolean mLogWritten = false;
-
-    EventLogger(SynthesisRequest request, int callerUid, int callerPid, String serviceApp) {
-        mRequest = request;
-        mCallerUid = callerUid;
-        mCallerPid = callerPid;
-        mServiceApp = serviceApp;
-        mReceivedTime = SystemClock.elapsedRealtime();
-    }
-
-    /**
-     * Notifies the logger that this request has been selected from
-     * the processing queue for processing. Engine latency / total time
-     * is measured from this baseline.
-     */
-    public void onRequestProcessingStart() {
-        mRequestProcessingStartTime = SystemClock.elapsedRealtime();
-    }
-
-    /**
-     * Notifies the logger that a chunk of data has been received from
-     * the engine. Might be called multiple times.
-     */
-    public void onEngineDataReceived() {
-        if (mEngineStartTime == -1) {
-            mEngineStartTime = SystemClock.elapsedRealtime();
-        }
-    }
-
-    /**
-     * Notifies the logger that the engine has finished processing data.
-     * Will be called exactly once.
-     */
-    public void onEngineComplete() {
-        mEngineCompleteTime = SystemClock.elapsedRealtime();
-    }
-
-    /**
-     * Notifies the logger that audio playback has started for some section
-     * of the synthesis. This is normally some amount of time after the engine
-     * has synthesized data and varies depending on utterances and
-     * other audio currently in the queue.
-     */
-    public void onAudioDataWritten() {
-        // For now, keep track of only the first chunk of audio
-        // that was played.
-        if (mPlaybackStartTime == -1) {
-            mPlaybackStartTime = SystemClock.elapsedRealtime();
-        }
-    }
-
-    /**
-     * Notifies the logger that the current synthesis was stopped.
-     * Latency numbers are not reported for stopped syntheses.
-     */
-    public void onStopped() {
-        mStopped = false;
-    }
-
-    /**
-     * Notifies the logger that the current synthesis resulted in
-     * an error. This is logged using {@link EventLogTags#writeTtsSpeakFailure}.
-     */
-    public void onError() {
-        mError = true;
-    }
-
-    /**
-     * Notifies the logger that the current synthesis has completed.
-     * All available data is not logged.
-     */
-    public void onWriteData() {
-        if (mLogWritten) {
-            return;
-        } else {
-            mLogWritten = true;
-        }
-
-        long completionTime = SystemClock.elapsedRealtime();
-        // onAudioDataWritten() should normally always be called if an
-        // error does not occur.
-        if (mError || mPlaybackStartTime == -1 || mEngineCompleteTime == -1) {
-            EventLogTags.writeTtsSpeakFailure(mServiceApp, mCallerUid, mCallerPid,
-                    getUtteranceLength(), getLocaleString(),
-                    mRequest.getSpeechRate(), mRequest.getPitch());
-            return;
-        }
-
-        // We don't report stopped syntheses because their overall
-        // total time spent will be innacurate (will not correlate with
-        // the length of the utterance).
-        if (mStopped) {
-            return;
-        }
-
-        final long audioLatency = mPlaybackStartTime - mReceivedTime;
-        final long engineLatency = mEngineStartTime - mRequestProcessingStartTime;
-        final long engineTotal = mEngineCompleteTime - mRequestProcessingStartTime;
-
-        EventLogTags.writeTtsSpeakSuccess(mServiceApp, mCallerUid, mCallerPid,
-                getUtteranceLength(), getLocaleString(),
-                mRequest.getSpeechRate(), mRequest.getPitch(),
-                engineLatency, engineTotal, audioLatency);
-    }
-
-    /**
-     * @return the length of the utterance for the given synthesis, 0
-     *          if the utterance was {@code null}.
-     */
-    private int getUtteranceLength() {
-        final String utterance = mRequest.getText();
-        return utterance == null ? 0 : utterance.length();
-    }
-
-    /**
-     * Returns a formatted locale string from the synthesis params of the
-     * form lang-country-variant.
-     */
-    private String getLocaleString() {
-        StringBuilder sb = new StringBuilder(mRequest.getLanguage());
-        if (!TextUtils.isEmpty(mRequest.getCountry())) {
-            sb.append('-');
-            sb.append(mRequest.getCountry());
-
-            if (!TextUtils.isEmpty(mRequest.getVariant())) {
-                sb.append('-');
-                sb.append(mRequest.getVariant());
-            }
-        }
-
-        return sb.toString();
-    }
-
-}
diff --git a/core/java/android/speech/tts/EventLoggerV1.java b/core/java/android/speech/tts/EventLoggerV1.java
new file mode 100644
index 0000000..f484347
--- /dev/null
+++ b/core/java/android/speech/tts/EventLoggerV1.java
@@ -0,0 +1,80 @@
+/*
+ * 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.speech.tts;
+
+import android.text.TextUtils;
+
+/**
+ * Writes data about a given speech synthesis request for V1 API to the event
+ * logs. The data that is logged includes the calling app, length of the
+ * utterance, speech rate / pitch, the latency, and overall time taken.
+ */
+class EventLoggerV1 extends AbstractEventLogger {
+    private final SynthesisRequest mRequest;
+
+    EventLoggerV1(SynthesisRequest request, int callerUid, int callerPid, String serviceApp) {
+        super(callerUid, callerPid, serviceApp);
+        mRequest = request;
+    }
+
+    @Override
+    protected void logFailure(int statusCode) {
+        // We don't report stopped syntheses because their overall
+        // total time spent will be inaccurate (will not correlate with
+        // the length of the utterance).
+        if (statusCode != TextToSpeechClient.Status.STOPPED) {
+            EventLogTags.writeTtsSpeakFailure(mServiceApp, mCallerUid, mCallerPid,
+                    getUtteranceLength(), getLocaleString(),
+                    mRequest.getSpeechRate(), mRequest.getPitch());
+        }
+    }
+
+    @Override
+    protected void logSuccess(long audioLatency, long engineLatency, long engineTotal) {
+        EventLogTags.writeTtsSpeakSuccess(mServiceApp, mCallerUid, mCallerPid,
+                getUtteranceLength(), getLocaleString(),
+                mRequest.getSpeechRate(), mRequest.getPitch(),
+                engineLatency, engineTotal, audioLatency);
+    }
+
+    /**
+     * @return the length of the utterance for the given synthesis, 0
+     *          if the utterance was {@code null}.
+     */
+    private int getUtteranceLength() {
+        final String utterance = mRequest.getText();
+        return utterance == null ? 0 : utterance.length();
+    }
+
+    /**
+     * Returns a formatted locale string from the synthesis params of the
+     * form lang-country-variant.
+     */
+    private String getLocaleString() {
+        StringBuilder sb = new StringBuilder(mRequest.getLanguage());
+        if (!TextUtils.isEmpty(mRequest.getCountry())) {
+            sb.append('-');
+            sb.append(mRequest.getCountry());
+
+            if (!TextUtils.isEmpty(mRequest.getVariant())) {
+                sb.append('-');
+                sb.append(mRequest.getVariant());
+            }
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/core/java/android/speech/tts/EventLoggerV2.java b/core/java/android/speech/tts/EventLoggerV2.java
new file mode 100644
index 0000000..b8e4dae
--- /dev/null
+++ b/core/java/android/speech/tts/EventLoggerV2.java
@@ -0,0 +1,73 @@
+/*
+ * 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.speech.tts;
+
+
+
+/**
+ * Writes data about a given speech synthesis request for V2 API to the event logs.
+ * The data that is logged includes the calling app, length of the utterance,
+ * synthesis request configuration and the latency and overall time taken.
+ */
+class EventLoggerV2 extends AbstractEventLogger {
+    private final SynthesisRequestV2 mRequest;
+
+    EventLoggerV2(SynthesisRequestV2 request, int callerUid, int callerPid, String serviceApp) {
+        super(callerUid, callerPid, serviceApp);
+        mRequest = request;
+    }
+
+    @Override
+    protected void logFailure(int statusCode) {
+        // We don't report stopped syntheses because their overall
+        // total time spent will be inaccurate (will not correlate with
+        // the length of the utterance).
+        if (statusCode != TextToSpeechClient.Status.STOPPED) {
+            EventLogTags.writeTtsV2SpeakFailure(mServiceApp,
+                    mCallerUid, mCallerPid, getUtteranceLength(), getRequestConfigString(), statusCode);
+        }
+    }
+
+    @Override
+    protected void logSuccess(long audioLatency, long engineLatency, long engineTotal) {
+        EventLogTags.writeTtsV2SpeakSuccess(mServiceApp,
+                mCallerUid, mCallerPid, getUtteranceLength(), getRequestConfigString(),
+                engineLatency, engineTotal, audioLatency);
+    }
+
+    /**
+     * @return the length of the utterance for the given synthesis, 0
+     *          if the utterance was {@code null}.
+     */
+    private int getUtteranceLength() {
+        final String utterance = mRequest.getText();
+        return utterance == null ? 0 : utterance.length();
+    }
+
+    /**
+     * Returns a string representation of the synthesis request configuration.
+     */
+    private String getRequestConfigString() {
+        // Ensure the bundles are unparceled.
+        mRequest.getVoiceParams().size();
+        mRequest.getAudioParams().size();
+
+        return new StringBuilder(64).append("VoiceName: ").append(mRequest.getVoiceName())
+            .append(" ,VoiceParams: ").append(mRequest.getVoiceParams())
+            .append(" ,SystemParams: ").append(mRequest.getAudioParams())
+            .append("]").toString();
+    }
+}
diff --git a/core/java/android/speech/tts/FileSynthesisCallback.java b/core/java/android/speech/tts/FileSynthesisCallback.java
index ab8f82f..717aeb6 100644
--- a/core/java/android/speech/tts/FileSynthesisCallback.java
+++ b/core/java/android/speech/tts/FileSynthesisCallback.java
@@ -16,13 +16,10 @@
 package android.speech.tts;
 
 import android.media.AudioFormat;
-import android.os.FileUtils;
+import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
 import android.util.Log;
 
-import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.channels.FileChannel;
@@ -48,19 +45,39 @@
 
     private FileChannel mFileChannel;
 
+    private final UtteranceProgressDispatcher mDispatcher;
+    private final Object mCallerIdentity;
+
     private boolean mStarted = false;
-    private boolean mStopped = false;
     private boolean mDone = false;
 
-    FileSynthesisCallback(FileChannel fileChannel) {
+    /** Status code of synthesis */
+    protected int mStatusCode;
+
+    FileSynthesisCallback(FileChannel fileChannel, UtteranceProgressDispatcher dispatcher,
+            Object callerIdentity, boolean clientIsUsingV2) {
+        super(clientIsUsingV2);
         mFileChannel = fileChannel;
+        mDispatcher = dispatcher;
+        mCallerIdentity = callerIdentity;
+        mStatusCode = TextToSpeechClient.Status.SUCCESS;
     }
 
     @Override
     void stop() {
         synchronized (mStateLock) {
-            mStopped = true;
+            if (mDone) {
+                return;
+            }
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+                return;
+            }
+
+            mStatusCode = TextToSpeechClient.Status.STOPPED;
             cleanUp();
+            if (mDispatcher != null) {
+                mDispatcher.dispatchOnStop();
+            }
         }
     }
 
@@ -75,14 +92,8 @@
      * Must be called while holding the monitor on {@link #mStateLock}.
      */
     private void closeFile() {
-        try {
-            if (mFileChannel != null) {
-                mFileChannel.close();
-                mFileChannel = null;
-            }
-        } catch (IOException ex) {
-            Log.e(TAG, "Failed to close output file descriptor", ex);
-        }
+        // File will be closed by the SpeechItem in the speech service.
+        mFileChannel = null;
     }
 
     @Override
@@ -91,38 +102,46 @@
     }
 
     @Override
-    boolean isDone() {
-        return mDone;
-    }
-
-    @Override
     public int start(int sampleRateInHz, int audioFormat, int channelCount) {
         if (DBG) {
             Log.d(TAG, "FileSynthesisRequest.start(" + sampleRateInHz + "," + audioFormat
                     + "," + channelCount + ")");
         }
+        FileChannel fileChannel = null;
         synchronized (mStateLock) {
-            if (mStopped) {
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                 if (DBG) Log.d(TAG, "Request has been aborted.");
+                return errorCodeOnStop();
+            }
+            if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
+                if (DBG) Log.d(TAG, "Error was raised");
                 return TextToSpeech.ERROR;
             }
             if (mStarted) {
-                cleanUp();
-                throw new IllegalArgumentException("FileSynthesisRequest.start() called twice");
+                Log.e(TAG, "Start called twice");
+                return TextToSpeech.ERROR;
             }
             mStarted = true;
             mSampleRateInHz = sampleRateInHz;
             mAudioFormat = audioFormat;
             mChannelCount = channelCount;
 
-            try {
-                mFileChannel.write(ByteBuffer.allocate(WAV_HEADER_LENGTH));
-                return TextToSpeech.SUCCESS;
-            } catch (IOException ex) {
-                Log.e(TAG, "Failed to write wav header to output file descriptor" + ex);
-                cleanUp();
-                return TextToSpeech.ERROR;
+            if (mDispatcher != null) {
+                mDispatcher.dispatchOnStart();
             }
+            fileChannel = mFileChannel;
+        }
+
+        try {
+            fileChannel.write(ByteBuffer.allocate(WAV_HEADER_LENGTH));
+                return TextToSpeech.SUCCESS;
+        } catch (IOException ex) {
+            Log.e(TAG, "Failed to write wav header to output file descriptor", ex);
+            synchronized (mStateLock) {
+                cleanUp();
+                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
+            }
+            return TextToSpeech.ERROR;
         }
     }
 
@@ -132,66 +151,128 @@
             Log.d(TAG, "FileSynthesisRequest.audioAvailable(" + buffer + "," + offset
                     + "," + length + ")");
         }
+        FileChannel fileChannel = null;
         synchronized (mStateLock) {
-            if (mStopped) {
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                 if (DBG) Log.d(TAG, "Request has been aborted.");
+                return errorCodeOnStop();
+            }
+            if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
+                if (DBG) Log.d(TAG, "Error was raised");
                 return TextToSpeech.ERROR;
             }
             if (mFileChannel == null) {
                 Log.e(TAG, "File not open");
+                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
                 return TextToSpeech.ERROR;
             }
-            try {
-                mFileChannel.write(ByteBuffer.wrap(buffer,  offset,  length));
-                return TextToSpeech.SUCCESS;
-            } catch (IOException ex) {
-                Log.e(TAG, "Failed to write to output file descriptor", ex);
+            if (!mStarted) {
+                Log.e(TAG, "Start method was not called");
+                return TextToSpeech.ERROR;
+            }
+            fileChannel = mFileChannel;
+        }
+
+        try {
+            fileChannel.write(ByteBuffer.wrap(buffer,  offset,  length));
+            return TextToSpeech.SUCCESS;
+        } catch (IOException ex) {
+            Log.e(TAG, "Failed to write to output file descriptor", ex);
+            synchronized (mStateLock) {
                 cleanUp();
-                return TextToSpeech.ERROR;
+                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
             }
+            return TextToSpeech.ERROR;
         }
     }
 
     @Override
     public int done() {
         if (DBG) Log.d(TAG, "FileSynthesisRequest.done()");
+        FileChannel fileChannel = null;
+
+        int sampleRateInHz = 0;
+        int audioFormat = 0;
+        int channelCount = 0;
+
         synchronized (mStateLock) {
             if (mDone) {
-                if (DBG) Log.d(TAG, "Duplicate call to done()");
-                // This preserves existing behaviour. Earlier, if done was called twice
-                // we'd return ERROR because mFile == null and we'd add to logspam.
+                Log.w(TAG, "Duplicate call to done()");
+                // This is not an error that would prevent synthesis. Hence no
+                // setStatusCode is set.
                 return TextToSpeech.ERROR;
             }
-            if (mStopped) {
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                 if (DBG) Log.d(TAG, "Request has been aborted.");
+                return errorCodeOnStop();
+            }
+            if (mDispatcher != null && mStatusCode != TextToSpeechClient.Status.SUCCESS &&
+                    mStatusCode != TextToSpeechClient.Status.STOPPED) {
+                mDispatcher.dispatchOnError(mStatusCode);
                 return TextToSpeech.ERROR;
             }
             if (mFileChannel == null) {
                 Log.e(TAG, "File not open");
                 return TextToSpeech.ERROR;
             }
-            try {
-                // Write WAV header at start of file
-                mFileChannel.position(0);
-                int dataLength = (int) (mFileChannel.size() - WAV_HEADER_LENGTH);
-                mFileChannel.write(
-                        makeWavHeader(mSampleRateInHz, mAudioFormat, mChannelCount, dataLength));
+            mDone = true;
+            fileChannel = mFileChannel;
+            sampleRateInHz = mSampleRateInHz;
+            audioFormat = mAudioFormat;
+            channelCount = mChannelCount;
+        }
+
+        try {
+            // Write WAV header at start of file
+            fileChannel.position(0);
+            int dataLength = (int) (fileChannel.size() - WAV_HEADER_LENGTH);
+            fileChannel.write(
+                    makeWavHeader(sampleRateInHz, audioFormat, channelCount, dataLength));
+
+            synchronized (mStateLock) {
                 closeFile();
-                mDone = true;
+                if (mDispatcher != null) {
+                    mDispatcher.dispatchOnSuccess();
+                }
                 return TextToSpeech.SUCCESS;
-            } catch (IOException ex) {
-                Log.e(TAG, "Failed to write to output file descriptor", ex);
-                cleanUp();
-                return TextToSpeech.ERROR;
             }
+        } catch (IOException ex) {
+            Log.e(TAG, "Failed to write to output file descriptor", ex);
+            synchronized (mStateLock) {
+                cleanUp();
+            }
+            return TextToSpeech.ERROR;
         }
     }
 
     @Override
     public void error() {
+        error(TextToSpeechClient.Status.ERROR_SYNTHESIS);
+    }
+
+    @Override
+    public void error(int errorCode) {
         if (DBG) Log.d(TAG, "FileSynthesisRequest.error()");
         synchronized (mStateLock) {
+            if (mDone) {
+                return;
+            }
             cleanUp();
+            mStatusCode = errorCode;
+        }
+    }
+
+    @Override
+    public boolean hasStarted() {
+        synchronized (mStateLock) {
+            return mStarted;
+        }
+    }
+
+    @Override
+    public boolean hasFinished() {
+        synchronized (mStateLock) {
+            return mDone;
         }
     }
 
@@ -225,4 +306,16 @@
         return header;
     }
 
+    @Override
+    public int fallback() {
+        synchronized (mStateLock) {
+            if (hasStarted() || hasFinished()) {
+                return TextToSpeech.ERROR;
+            }
+
+            mDispatcher.dispatchOnFallback();
+            mStatusCode = TextToSpeechClient.Status.SUCCESS;
+            return TextToSpeechClient.Status.SUCCESS;
+        }
+    }
 }
diff --git a/core/java/android/speech/tts/ITextToSpeechCallback.aidl b/core/java/android/speech/tts/ITextToSpeechCallback.aidl
index f0287d4..3c808ff 100644
--- a/core/java/android/speech/tts/ITextToSpeechCallback.aidl
+++ b/core/java/android/speech/tts/ITextToSpeechCallback.aidl
@@ -15,13 +15,53 @@
  */
 package android.speech.tts;
 
+import android.speech.tts.VoiceInfo;
+
 /**
  * Interface for callbacks from TextToSpeechService
  *
  * {@hide}
  */
 oneway interface ITextToSpeechCallback {
+    /**
+     * Tells the client that the synthesis has started.
+     *
+     * @param utteranceId Unique id identifying synthesis request.
+     */
     void onStart(String utteranceId);
-    void onDone(String utteranceId);
-    void onError(String utteranceId);
+
+    /**
+     * Tells the client that the synthesis has finished.
+     *
+     * @param utteranceId Unique id identifying synthesis request.
+     */
+    void onSuccess(String utteranceId);
+
+    /**
+     * Tells the client that the synthesis was stopped.
+     *
+     * @param utteranceId Unique id identifying synthesis request.
+     */
+    void onStop(String utteranceId);
+
+    /**
+     * Tells the client that the synthesis failed, and fallback synthesis will be attempted.
+     *
+     * @param utteranceId Unique id identifying synthesis request.
+     */
+    void onFallback(String utteranceId);
+
+    /**
+     * Tells the client that the synthesis has failed.
+     *
+     * @param utteranceId Unique id identifying synthesis request.
+     * @param errorCode One of the values from
+     *        {@link android.speech.tts.v2.TextToSpeechClient.Status}.
+     */
+    void onError(String utteranceId, int errorCode);
+
+    /**
+     * Inform the client that set of available voices changed.
+     */
+    void onVoicesInfoChange(in List<VoiceInfo> voices);
 }
diff --git a/core/java/android/speech/tts/ITextToSpeechService.aidl b/core/java/android/speech/tts/ITextToSpeechService.aidl
index b7bc70c..9cf49ff 100644
--- a/core/java/android/speech/tts/ITextToSpeechService.aidl
+++ b/core/java/android/speech/tts/ITextToSpeechService.aidl
@@ -20,6 +20,8 @@
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.speech.tts.ITextToSpeechCallback;
+import android.speech.tts.VoiceInfo;
+import android.speech.tts.SynthesisRequestV2;
 
 /**
  * Interface for TextToSpeech to talk to TextToSpeechService.
@@ -70,9 +72,10 @@
      *        TextToSpeech object.
      * @param duration Number of milliseconds of silence to play.
      * @param queueMode Determines what to do to requests already in the queue.
-     * @param param Request parameters.
+     * @param utteranceId Unique id used to identify this request in callbacks.
      */
-    int playSilence(in IBinder callingInstance, in long duration, in int queueMode, in Bundle params);
+    int playSilence(in IBinder callingInstance, in long duration, in int queueMode,
+        in String utteranceId);
 
     /**
      * Checks whether the service is currently playing some audio.
@@ -90,7 +93,6 @@
 
     /**
      * Returns the language, country and variant currently being used by the TTS engine.
-     *
      * Can be called from multiple threads.
      *
      * @return A 3-element array, containing language (ISO 3-letter code),
@@ -99,7 +101,7 @@
      *         be empty too.
      */
     String[] getLanguage();
-    
+
     /**
      * Returns a default TTS language, country and variant as set by the user.
      *
@@ -111,7 +113,7 @@
      *         be empty too.
      */
     String[] getClientDefaultLanguage();
-    
+
     /**
      * Checks whether the engine supports a given language.
      *
@@ -137,7 +139,7 @@
      * @param country ISO-3 country code. May be empty or null.
      * @param variant Language variant. May be empty or null.
      * @return An array of strings containing the set of features supported for
-     *         the supplied locale. The array of strings must not contain 
+     *         the supplied locale. The array of strings must not contain
      *         duplicates.
      */
     String[] getFeaturesForLanguage(in String lang, in String country, in String variant);
@@ -169,4 +171,44 @@
      */
     void setCallback(in IBinder caller, ITextToSpeechCallback cb);
 
+    /**
+     * Tells the engine to synthesize some speech and play it back.
+     *
+     * @param callingInstance a binder representing the identity of the calling
+     *        TextToSpeech object.
+     * @param text The text to synthesize.
+     * @param queueMode Determines what to do to requests already in the queue.
+     * @param request Request parameters.
+     */
+    int speakV2(in IBinder callingInstance, in SynthesisRequestV2 request);
+
+    /**
+     * Tells the engine to synthesize some speech and write it to a file.
+     *
+     * @param callingInstance a binder representing the identity of the calling
+     *        TextToSpeech object.
+     * @param text The text to synthesize.
+     * @param fileDescriptor The file descriptor to write the synthesized audio to. Has to be
+              writable.
+     * @param request Request parameters.
+     */
+    int synthesizeToFileDescriptorV2(in IBinder callingInstance,
+        in ParcelFileDescriptor fileDescriptor, in SynthesisRequestV2 request);
+
+    /**
+     * Plays an existing audio resource. V2 version
+     *
+     * @param callingInstance a binder representing the identity of the calling
+     *        TextToSpeech object.
+     * @param audioUri URI for the audio resource (a file or android.resource URI)
+     * @param utteranceId Unique identifier.
+     * @param audioParameters Parameters for audio playback (from {@link SynthesisRequestV2}).
+     */
+    int playAudioV2(in IBinder callingInstance, in Uri audioUri, in String utteranceId,
+        in Bundle audioParameters);
+
+    /**
+     * Request the list of available voices from the service.
+     */
+    List<VoiceInfo> getVoicesInfo();
 }
diff --git a/core/java/android/speech/tts/PlaybackQueueItem.java b/core/java/android/speech/tts/PlaybackQueueItem.java
index d0957ff..b2e323e 100644
--- a/core/java/android/speech/tts/PlaybackQueueItem.java
+++ b/core/java/android/speech/tts/PlaybackQueueItem.java
@@ -22,6 +22,16 @@
         return mDispatcher;
     }
 
+    @Override
     public abstract void run();
-    abstract void stop(boolean isError);
+
+    /**
+     * Stop the playback.
+     *
+     * @param errorCode Cause of the stop. Can be either one of the error codes from
+     *         {@link android.speech.tts.TextToSpeechClient.Status} or
+     *         {@link android.speech.tts.TextToSpeechClient.Status#STOPPED}
+     *         if stopped on a client request.
+     */
+    abstract void stop(int errorCode);
 }
diff --git a/core/java/android/speech/tts/PlaybackSynthesisCallback.java b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
index c99f201..e345e89 100644
--- a/core/java/android/speech/tts/PlaybackSynthesisCallback.java
+++ b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
@@ -55,20 +55,20 @@
     private final AudioPlaybackHandler mAudioTrackHandler;
     // A request "token", which will be non null after start() has been called.
     private SynthesisPlaybackQueueItem mItem = null;
-    // Whether this request has been stopped. This is useful for keeping
-    // track whether stop() has been called before start(). In all other cases,
-    // a non-null value of mItem will provide the same information.
-    private boolean mStopped = false;
 
     private volatile boolean mDone = false;
 
+    /** Status code of synthesis */
+    protected int mStatusCode;
+
     private final UtteranceProgressDispatcher mDispatcher;
     private final Object mCallerIdentity;
-    private final EventLogger mLogger;
+    private final AbstractEventLogger mLogger;
 
     PlaybackSynthesisCallback(int streamType, float volume, float pan,
             AudioPlaybackHandler audioTrackHandler, UtteranceProgressDispatcher dispatcher,
-            Object callerIdentity, EventLogger logger) {
+            Object callerIdentity, AbstractEventLogger logger, boolean clientIsUsingV2) {
+        super(clientIsUsingV2);
         mStreamType = streamType;
         mVolume = volume;
         mPan = pan;
@@ -76,28 +76,25 @@
         mDispatcher = dispatcher;
         mCallerIdentity = callerIdentity;
         mLogger = logger;
+        mStatusCode = TextToSpeechClient.Status.SUCCESS;
     }
 
     @Override
     void stop() {
-        stopImpl(false);
-    }
-
-    void stopImpl(boolean wasError) {
         if (DBG) Log.d(TAG, "stop()");
 
-        // Note that mLogger.mError might be true too at this point.
-        mLogger.onStopped();
-
         SynthesisPlaybackQueueItem item;
         synchronized (mStateLock) {
-            if (mStopped) {
+            if (mDone) {
+                return;
+            }
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                 Log.w(TAG, "stop() called twice");
                 return;
             }
 
             item = mItem;
-            mStopped = true;
+            mStatusCode = TextToSpeechClient.Status.STOPPED;
         }
 
         if (item != null) {
@@ -105,19 +102,15 @@
             // point it will write an additional buffer to the item - but we
             // won't worry about that because the audio playback queue will be cleared
             // soon after (see SynthHandler#stop(String).
-            item.stop(wasError);
+            item.stop(TextToSpeechClient.Status.STOPPED);
         } else {
             // This happens when stop() or error() were called before start() was.
 
             // In all other cases, mAudioTrackHandler.stop() will
             // result in onSynthesisDone being called, and we will
             // write data there.
-            mLogger.onWriteData();
-
-            if (wasError) {
-                // We have to dispatch the error ourselves.
-                mDispatcher.dispatchOnError();
-            }
+            mLogger.onCompleted(TextToSpeechClient.Status.STOPPED);
+            mDispatcher.dispatchOnStop();
         }
     }
 
@@ -129,26 +122,42 @@
     }
 
     @Override
-    boolean isDone() {
-        return mDone;
+    public boolean hasStarted() {
+        synchronized (mStateLock) {
+            return mItem != null;
+        }
+    }
+
+    @Override
+    public boolean hasFinished() {
+        synchronized (mStateLock) {
+            return mDone;
+        }
     }
 
     @Override
     public int start(int sampleRateInHz, int audioFormat, int channelCount) {
-        if (DBG) {
-            Log.d(TAG, "start(" + sampleRateInHz + "," + audioFormat
-                    + "," + channelCount + ")");
-        }
+        if (DBG) Log.d(TAG, "start(" + sampleRateInHz + "," + audioFormat + "," + channelCount
+                + ")");
 
         int channelConfig = BlockingAudioTrack.getChannelConfig(channelCount);
-        if (channelConfig == 0) {
-            Log.e(TAG, "Unsupported number of channels :" + channelCount);
-            return TextToSpeech.ERROR;
-        }
 
         synchronized (mStateLock) {
-            if (mStopped) {
+            if (channelConfig == 0) {
+                Log.e(TAG, "Unsupported number of channels :" + channelCount);
+                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
+                return TextToSpeech.ERROR;
+            }
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                 if (DBG) Log.d(TAG, "stop() called before start(), returning.");
+                return errorCodeOnStop();
+            }
+            if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
+                if (DBG) Log.d(TAG, "Error was raised");
+                return TextToSpeech.ERROR;
+            }
+            if (mItem != null) {
+                Log.e(TAG, "Start called twice");
                 return TextToSpeech.ERROR;
             }
             SynthesisPlaybackQueueItem item = new SynthesisPlaybackQueueItem(
@@ -161,13 +170,11 @@
         return TextToSpeech.SUCCESS;
     }
 
-
     @Override
     public int audioAvailable(byte[] buffer, int offset, int length) {
-        if (DBG) {
-            Log.d(TAG, "audioAvailable(byte[" + buffer.length + "],"
-                    + offset + "," + length + ")");
-        }
+        if (DBG) Log.d(TAG, "audioAvailable(byte[" + buffer.length + "]," + offset + "," + length
+                + ")");
+
         if (length > getMaxBufferSize() || length <= 0) {
             throw new IllegalArgumentException("buffer is too large or of zero length (" +
                     + length + " bytes)");
@@ -175,9 +182,17 @@
 
         SynthesisPlaybackQueueItem item = null;
         synchronized (mStateLock) {
-            if (mItem == null || mStopped) {
+            if (mItem == null) {
+                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
                 return TextToSpeech.ERROR;
             }
+            if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
+                if (DBG) Log.d(TAG, "Error was raised");
+                return TextToSpeech.ERROR;
+            }
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+                return errorCodeOnStop();
+            }
             item = mItem;
         }
 
@@ -190,11 +205,13 @@
         try {
             item.put(bufferCopy);
         } catch (InterruptedException ie) {
-            return TextToSpeech.ERROR;
+            synchronized (mStateLock) {
+                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
+                return TextToSpeech.ERROR;
+            }
         }
 
         mLogger.onEngineDataReceived();
-
         return TextToSpeech.SUCCESS;
     }
 
@@ -202,35 +219,74 @@
     public int done() {
         if (DBG) Log.d(TAG, "done()");
 
+        int statusCode = 0;
         SynthesisPlaybackQueueItem item = null;
         synchronized (mStateLock) {
             if (mDone) {
                 Log.w(TAG, "Duplicate call to done()");
+                // Not an error that would prevent synthesis. Hence no
+                // setStatusCode
                 return TextToSpeech.ERROR;
             }
-
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+                if (DBG) Log.d(TAG, "Request has been aborted.");
+                return errorCodeOnStop();
+            }
             mDone = true;
 
             if (mItem == null) {
+                // .done() was called before .start. Treat it as successful synthesis
+                // for a client, despite service bad implementation.
+                Log.w(TAG, "done() was called before start() call");
+                if (mStatusCode == TextToSpeechClient.Status.SUCCESS) {
+                    mDispatcher.dispatchOnSuccess();
+                } else {
+                    mDispatcher.dispatchOnError(mStatusCode);
+                }
+                mLogger.onEngineComplete();
                 return TextToSpeech.ERROR;
             }
 
             item = mItem;
+            statusCode = mStatusCode;
         }
 
-        item.done();
+        // Signal done or error to item
+        if (statusCode == TextToSpeechClient.Status.SUCCESS) {
+            item.done();
+        } else {
+            item.stop(statusCode);
+        }
         mLogger.onEngineComplete();
-
         return TextToSpeech.SUCCESS;
     }
 
     @Override
     public void error() {
-        if (DBG) Log.d(TAG, "error() [will call stop]");
-        // Currently, this call will not be logged if error( ) is called
-        // before start.
-        mLogger.onError();
-        stopImpl(true);
+        error(TextToSpeechClient.Status.ERROR_SYNTHESIS);
     }
 
+    @Override
+    public void error(int errorCode) {
+        if (DBG) Log.d(TAG, "error() [will call stop]");
+        synchronized (mStateLock) {
+            if (mDone) {
+                return;
+            }
+            mStatusCode = errorCode;
+        }
+    }
+
+    @Override
+    public int fallback() {
+        synchronized (mStateLock) {
+            if (hasStarted() || hasFinished()) {
+                return TextToSpeech.ERROR;
+            }
+
+            mDispatcher.dispatchOnFallback();
+            mStatusCode = TextToSpeechClient.Status.SUCCESS;
+            return TextToSpeechClient.Status.SUCCESS;
+        }
+    }
 }
diff --git a/core/java/android/speech/tts/RequestConfig.java b/core/java/android/speech/tts/RequestConfig.java
new file mode 100644
index 0000000..4b5385f
--- /dev/null
+++ b/core/java/android/speech/tts/RequestConfig.java
@@ -0,0 +1,213 @@
+package android.speech.tts;
+
+import android.media.AudioManager;
+import android.os.Bundle;
+
+/**
+ * Synthesis request configuration.
+ *
+ * This class is immutable, and can only be constructed using
+ * {@link RequestConfig.Builder}.
+ */
+public final class RequestConfig {
+
+    /** Builder for constructing RequestConfig objects. */
+    public static final class Builder {
+        private VoiceInfo mCurrentVoiceInfo;
+        private Bundle mVoiceParams;
+        private Bundle mAudioParams;
+
+        Builder(VoiceInfo currentVoiceInfo, Bundle voiceParams, Bundle audioParams) {
+            mCurrentVoiceInfo = currentVoiceInfo;
+            mVoiceParams = voiceParams;
+            mAudioParams = audioParams;
+        }
+
+        /**
+         * Create new RequestConfig builder.
+         */
+        public static Builder newBuilder() {
+            return new Builder(null, new Bundle(), new Bundle());
+        }
+
+        /**
+         * Create new RequestConfig builder.
+         * @param prototype
+         *            Prototype of new RequestConfig. Copies all fields of the
+         *            prototype to the constructed object.
+         */
+        public static Builder newBuilder(RequestConfig prototype) {
+            return new Builder(prototype.mCurrentVoiceInfo,
+                    (Bundle)prototype.mVoiceParams.clone(),
+                    (Bundle)prototype.mAudioParams.clone());
+        }
+
+        /** Set voice for request. Will reset voice parameters to the defaults. */
+        public Builder setVoice(VoiceInfo voice) {
+            mCurrentVoiceInfo = voice;
+            mVoiceParams = (Bundle)voice.getParamsWithDefaults().clone();
+            return this;
+        }
+
+        /**
+         * Set request voice parameter.
+         *
+         * @param paramName
+         *            The name of the parameter. It has to be one of the keys
+         *            from {@link VoiceInfo#getParamsWithDefaults()}
+         * @param value
+         *            Value of the parameter. Its type can be one of: Integer, Float,
+         *            Boolean, String, VoiceInfo (will be set as a String, result of a call to
+         *            the {@link VoiceInfo#getName()}) or byte[]. It has to be of the same type
+         *            as the default value from {@link VoiceInfo#getParamsWithDefaults()}
+         *            for that parameter.
+         * @throws IllegalArgumentException
+         *            If paramName is not a valid parameter name or its value is of a wrong
+         *            type.
+         * @throws IllegalStateException
+         *            If no voice is set.
+         */
+        public Builder setVoiceParam(String paramName, Object value){
+            if (mCurrentVoiceInfo == null) {
+                throw new IllegalStateException(
+                        "Couldn't set voice parameter, no voice is set");
+            }
+            Object defaultValue = mCurrentVoiceInfo.getParamsWithDefaults().get(paramName);
+            if (defaultValue == null) {
+                throw new IllegalArgumentException(
+                        "Parameter \"" + paramName + "\" is not available in set voice with " +
+                                "name: " + mCurrentVoiceInfo.getName());
+            }
+
+            // If it's VoiceInfo, get its name
+            if (value instanceof VoiceInfo) {
+                value = ((VoiceInfo)value).getName();
+            }
+
+            // Check type information
+            if (!defaultValue.getClass().equals(value.getClass())) {
+                throw new IllegalArgumentException(
+                        "Parameter \"" + paramName +"\" is of different type. Value passed has " +
+                                "type " + value.getClass().getSimpleName() + " but should have " +
+                                "type " + defaultValue.getClass().getSimpleName());
+            }
+
+            setParam(mVoiceParams, paramName, value);
+            return this;
+        }
+
+        /**
+         * Set request audio parameter.
+         *
+         * Doesn't requires a set voice.
+         *
+         * @param paramName
+         *            Name of parameter.
+         * @param value
+         *            Value of parameter. Its type can be one of: Integer, Float, Boolean, String
+         *            or byte[].
+         */
+        public Builder setAudioParam(String paramName, Object value) {
+            setParam(mAudioParams, paramName, value);
+            return this;
+        }
+
+        /**
+         * Set the {@link TextToSpeechClient.Params#AUDIO_PARAM_STREAM} audio parameter.
+         *
+         * @param streamId One of the STREAM_ constants defined in {@link AudioManager}.
+         */
+        public void setAudioParamStream(int streamId) {
+            setAudioParam(TextToSpeechClient.Params.AUDIO_PARAM_STREAM, streamId);
+        }
+
+        /**
+         * Set the {@link TextToSpeechClient.Params#AUDIO_PARAM_VOLUME} audio parameter.
+         *
+         * @param volume Float in range of 0.0 to 1.0.
+         */
+        public void setAudioParamVolume(float volume) {
+            setAudioParam(TextToSpeechClient.Params.AUDIO_PARAM_VOLUME, volume);
+        }
+
+        /**
+         * Set the {@link TextToSpeechClient.Params#AUDIO_PARAM_PAN} audio parameter.
+         *
+         * @param pan Float in range of -1.0 to +1.0.
+         */
+        public void setAudioParamPan(float pan) {
+            setAudioParam(TextToSpeechClient.Params.AUDIO_PARAM_PAN, pan);
+        }
+
+        private void setParam(Bundle bundle, String featureName, Object value) {
+            if (value instanceof String) {
+                bundle.putString(featureName, (String)value);
+            } else if(value instanceof byte[]) {
+                bundle.putByteArray(featureName, (byte[])value);
+            } else if(value instanceof Integer) {
+                bundle.putInt(featureName, (Integer)value);
+            } else if(value instanceof Float) {
+                bundle.putFloat(featureName, (Float)value);
+            } else if(value instanceof Double) {
+                bundle.putFloat(featureName, (Float)value);
+            } else if(value instanceof Boolean) {
+                bundle.putBoolean(featureName, (Boolean)value);
+            } else {
+                throw new IllegalArgumentException("Illegal type of object");
+            }
+            return;
+        }
+
+        /**
+         * Build new RequestConfig instance.
+         */
+        public RequestConfig build() {
+            RequestConfig config =
+                    new RequestConfig(mCurrentVoiceInfo, mVoiceParams, mAudioParams);
+            return config;
+        }
+    }
+
+    private RequestConfig(VoiceInfo voiceInfo, Bundle voiceParams, Bundle audioParams) {
+        mCurrentVoiceInfo = voiceInfo;
+        mVoiceParams = voiceParams;
+        mAudioParams = audioParams;
+    }
+
+    /**
+     * Currently set voice.
+     */
+    private final VoiceInfo mCurrentVoiceInfo;
+
+    /**
+     * Voice parameters bundle.
+     */
+    private final Bundle mVoiceParams;
+
+    /**
+     * Audio parameters bundle.
+     */
+    private final Bundle mAudioParams;
+
+    /**
+     * @return Currently set request voice.
+     */
+    public VoiceInfo getVoice() {
+        return mCurrentVoiceInfo;
+    }
+
+    /**
+     * @return Request audio parameters.
+     */
+    public Bundle getAudioParams() {
+        return mAudioParams;
+    }
+
+    /**
+     * @return Request voice parameters.
+     */
+    public Bundle getVoiceParams() {
+        return mVoiceParams;
+    }
+
+}
diff --git a/core/java/android/speech/tts/RequestConfigHelper.java b/core/java/android/speech/tts/RequestConfigHelper.java
new file mode 100644
index 0000000..b25c985
--- /dev/null
+++ b/core/java/android/speech/tts/RequestConfigHelper.java
@@ -0,0 +1,170 @@
+package android.speech.tts;
+
+import android.speech.tts.TextToSpeechClient.EngineStatus;
+
+import java.util.Locale;
+
+/**
+ * Set of common heuristics for selecting {@link VoiceInfo} from
+ * {@link TextToSpeechClient#getEngineStatus()} output.
+ */
+public final class RequestConfigHelper {
+    private RequestConfigHelper() {}
+
+    /**
+     * Interface for scoring VoiceInfo object.
+     */
+    public static interface VoiceScorer {
+        /**
+         * Score VoiceInfo. If the score is less than or equal to zero, that voice is discarded.
+         * If two voices have same desired primary characteristics (highest quality, lowest
+         * latency or others), the one with the higher score is selected.
+         */
+        public int scoreVoice(VoiceInfo voiceInfo);
+    }
+
+    /**
+     * Score positively voices that exactly match the locale supplied to the constructor.
+     */
+    public static final class ExactLocaleMatcher implements VoiceScorer {
+        private final Locale mLocale;
+
+        /**
+         * Score positively voices that exactly match the given locale
+         * @param locale Reference locale. If null, the default locale will be used.
+         */
+        public ExactLocaleMatcher(Locale locale) {
+            if (locale == null) {
+                mLocale = Locale.getDefault();
+            } else {
+                mLocale = locale;
+            }
+        }
+        @Override
+        public int scoreVoice(VoiceInfo voiceInfo) {
+            return mLocale.equals(voiceInfo.getLocale()) ? 1 : 0;
+        }
+    }
+
+    /**
+     * Score positively voices that match exactly the given locale (score 3)
+     * or that share same language and country (score 2), or that share just a language (score 1).
+     */
+    public static final class LanguageMatcher implements VoiceScorer {
+        private final Locale mLocale;
+
+        /**
+         * Score positively voices with similar locale.
+         * @param locale Reference locale. If null, default will be used.
+         */
+        public LanguageMatcher(Locale locale) {
+            if (locale == null) {
+                mLocale = Locale.getDefault();
+            } else {
+                mLocale = locale;
+            }
+        }
+
+        @Override
+        public int scoreVoice(VoiceInfo voiceInfo) {
+            final Locale voiceLocale = voiceInfo.getLocale();
+            if (mLocale.equals(voiceLocale)) {
+                return 3;
+            } else {
+                if (mLocale.getLanguage().equals(voiceLocale.getLanguage())) {
+                    if (mLocale.getCountry().equals(voiceLocale.getCountry())) {
+                        return 2;
+                    }
+                    return 1;
+                }
+                return 0;
+            }
+        }
+    }
+
+    /**
+     * Get the highest quality voice from voices that score more than zero from the passed scorer.
+     * If there is more than one voice with the same highest quality, then this method returns one
+     * with the highest score. If they share same score as well, one with the lower index in the
+     * voices list is returned.
+     *
+     * @param engineStatus
+     *            Voices status received from a {@link TextToSpeechClient#getEngineStatus()} call.
+     * @param voiceScorer
+     *            Used to discard unsuitable voices and help settle cases where more than
+     *            one voice has the desired characteristic.
+     * @param hasToBeEmbedded
+     *            If true, require the voice to be an embedded voice (no network
+     *            access will be required for synthesis).
+     */
+    private static VoiceInfo getHighestQualityVoice(EngineStatus engineStatus,
+            VoiceScorer voiceScorer, boolean hasToBeEmbedded) {
+        VoiceInfo bestVoice = null;
+        int bestScoreMatch = 1;
+        int bestVoiceQuality = 0;
+
+        for (VoiceInfo voice : engineStatus.getVoices()) {
+            int score = voiceScorer.scoreVoice(voice);
+            if (score <= 0 || hasToBeEmbedded && voice.getRequiresNetworkConnection()
+                    || voice.getQuality() < bestVoiceQuality) {
+                continue;
+            }
+
+            if (bestVoice == null ||
+                    voice.getQuality() > bestVoiceQuality ||
+                    score > bestScoreMatch) {
+                bestVoice = voice;
+                bestScoreMatch = score;
+                bestVoiceQuality = voice.getQuality();
+            }
+        }
+        return bestVoice;
+    }
+
+    /**
+     * Get highest quality voice.
+     *
+     * Highest quality voice is selected from voices that score more than zero from the passed
+     * scorer. If there is more than one voice with the same highest quality, then this method
+     * will return one with the highest score. If they share same score as well, one with the lower
+     * index in the voices list is returned.
+
+     * @param engineStatus
+     *            Voices status received from a {@link TextToSpeechClient#getEngineStatus()} call.
+     * @param hasToBeEmbedded
+     *            If true, require the voice to be an embedded voice (no network
+     *            access will be required for synthesis).
+     * @param voiceScorer
+     *            Scorer is used to discard unsuitable voices and help settle cases where more than
+     *            one voice has highest quality.
+     * @return RequestConfig with selected voice or null if suitable voice was not found.
+     */
+    public static RequestConfig highestQuality(EngineStatus engineStatus,
+            boolean hasToBeEmbedded, VoiceScorer voiceScorer) {
+        VoiceInfo voice = getHighestQualityVoice(engineStatus, voiceScorer, hasToBeEmbedded);
+        if (voice == null) {
+            return null;
+        }
+        return RequestConfig.Builder.newBuilder().setVoice(voice).build();
+    }
+
+    /**
+     * Get highest quality voice for the default locale.
+     *
+     * Call {@link #highestQuality(EngineStatus, boolean, VoiceScorer)} with
+     * {@link LanguageMatcher} set to device default locale.
+     *
+     * @param engineStatus
+     *            Voices status received from a {@link TextToSpeechClient#getEngineStatus()} call.
+     * @param hasToBeEmbedded
+     *            If true, require the voice to be an embedded voice (no network
+     *            access will be required for synthesis).
+     * @return RequestConfig with selected voice or null if suitable voice was not found.
+     */
+    public static RequestConfig highestQuality(EngineStatus engineStatus,
+            boolean hasToBeEmbedded) {
+        return highestQuality(engineStatus, hasToBeEmbedded,
+                new LanguageMatcher(Locale.getDefault()));
+    }
+
+}
diff --git a/core/java/android/speech/tts/SilencePlaybackQueueItem.java b/core/java/android/speech/tts/SilencePlaybackQueueItem.java
index a5e47ae..88b7c70 100644
--- a/core/java/android/speech/tts/SilencePlaybackQueueItem.java
+++ b/core/java/android/speech/tts/SilencePlaybackQueueItem.java
@@ -17,7 +17,6 @@
 
 import android.os.ConditionVariable;
 import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
-import android.util.Log;
 
 class SilencePlaybackQueueItem extends PlaybackQueueItem {
     private final ConditionVariable mCondVar = new ConditionVariable();
@@ -32,14 +31,20 @@
     @Override
     public void run() {
         getDispatcher().dispatchOnStart();
+        boolean wasStopped = false;
         if (mSilenceDurationMs > 0) {
-            mCondVar.block(mSilenceDurationMs);
+          wasStopped = mCondVar.block(mSilenceDurationMs);
         }
-        getDispatcher().dispatchOnDone();
+        if (wasStopped) {
+            getDispatcher().dispatchOnStop();
+        } else {
+            getDispatcher().dispatchOnSuccess();
+        }
+
     }
 
     @Override
-    void stop(boolean isError) {
+    void stop(int errorCode) {
         mCondVar.open();
     }
 }
diff --git a/core/java/android/speech/tts/SynthesisCallback.java b/core/java/android/speech/tts/SynthesisCallback.java
index f98bb09..bc2f239 100644
--- a/core/java/android/speech/tts/SynthesisCallback.java
+++ b/core/java/android/speech/tts/SynthesisCallback.java
@@ -26,7 +26,9 @@
  * indicate that an error has occurred, but if the call is made after a call
  * to {@link #done}, it might be discarded.
  *
- * After {@link #start} been called, {@link #done} must be called regardless of errors.
+ * {@link #done} must be called at the end of synthesis, regardless of errors.
+ *
+ * All methods can be only called on the synthesis thread.
  */
 public interface SynthesisCallback {
     /**
@@ -41,13 +43,16 @@
      * request.
      *
      * This method should only be called on the synthesis thread,
-     * while in {@link TextToSpeechService#onSynthesizeText}.
+     * while in {@link TextToSpeechService#onSynthesizeText} or
+     * {@link TextToSpeechService#onSynthesizeTextV2}.
      *
      * @param sampleRateInHz Sample rate in HZ of the generated audio.
      * @param audioFormat Audio format of the generated audio. Must be one of
      *         the ENCODING_ constants defined in {@link android.media.AudioFormat}.
      * @param channelCount The number of channels. Must be {@code 1} or {@code 2}.
-     * @return {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
+     * @return {@link TextToSpeech#SUCCESS}, {@link TextToSpeech#ERROR}.
+     *          {@link TextToSpeechClient.Status#STOPPED} is also possible if called in context of
+     *          {@link TextToSpeechService#onSynthesizeTextV2}.
      */
     public int start(int sampleRateInHz, int audioFormat, int channelCount);
 
@@ -55,7 +60,8 @@
      * The service should call this method when synthesized audio is ready for consumption.
      *
      * This method should only be called on the synthesis thread,
-     * while in {@link TextToSpeechService#onSynthesizeText}.
+     * while in {@link TextToSpeechService#onSynthesizeText} or
+     * {@link TextToSpeechService#onSynthesizeTextV2}.
      *
      * @param buffer The generated audio data. This method will not hold on to {@code buffer},
      *         so the caller is free to modify it after this method returns.
@@ -63,6 +69,8 @@
      * @param length The number of bytes of audio data in {@code buffer}. This must be
      *         less than or equal to the return value of {@link #getMaxBufferSize}.
      * @return {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
+     *          {@link TextToSpeechClient.Status#STOPPED} is also possible if called in context of
+     *          {@link TextToSpeechService#onSynthesizeTextV2}.
      */
     public int audioAvailable(byte[] buffer, int offset, int length);
 
@@ -71,11 +79,14 @@
      * been passed to {@link #audioAvailable}.
      *
      * This method should only be called on the synthesis thread,
-     * while in {@link TextToSpeechService#onSynthesizeText}.
+     * while in {@link TextToSpeechService#onSynthesizeText} or
+     * {@link TextToSpeechService#onSynthesizeTextV2}.
      *
-     * This method has to be called if {@link #start} was called.
+     * This method has to be called if {@link #start} and/or {@link #error} was called.
      *
      * @return {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
+     *          {@link TextToSpeechClient.Status#STOPPED} is also possible if called in context of
+     *          {@link TextToSpeechService#onSynthesizeTextV2}.
      */
     public int done();
 
@@ -87,4 +98,58 @@
      */
     public void error();
 
-}
\ No newline at end of file
+
+    /**
+     * The service should call this method if the speech synthesis fails.
+     *
+     * This method should only be called on the synthesis thread,
+     * while in {@link TextToSpeechService#onSynthesizeText} or
+     * {@link TextToSpeechService#onSynthesizeTextV2}.
+     *
+     * @param errorCode Error code to pass to the client. One of the ERROR_ values from
+     *      {@link TextToSpeechClient.Status}
+     */
+    public void error(int errorCode);
+
+    /**
+     * Communicate to client that the original request can't be done and client-requested
+     * fallback is happening.
+     *
+     * Fallback can be requested by the client by setting
+     * {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter with a id of
+     * the voice that is expected to be used for the fallback.
+     *
+     * This method will fail if user called {@link #start(int, int, int)} and/or
+     * {@link #done()}.
+     *
+     * This method should only be called on the synthesis thread,
+     * while in {@link TextToSpeechService#onSynthesizeTextV2}.
+     *
+     * @return {@link TextToSpeech#SUCCESS}, {@link TextToSpeech#ERROR} if client already
+     *          called {@link #start(int, int, int)}, {@link TextToSpeechClient.Status#STOPPED}
+     *          if stop was requested.
+     */
+    public int fallback();
+
+    /**
+     * Check if {@link #start} was called or not.
+     *
+     * This method should only be called on the synthesis thread,
+     * while in {@link TextToSpeechService#onSynthesizeText} or
+     * {@link TextToSpeechService#onSynthesizeTextV2}.
+     *
+     * Useful for checking if a fallback from network request is possible.
+     */
+    public boolean hasStarted();
+
+    /**
+     * Check if {@link #done} was called or not.
+     *
+     * This method should only be called on the synthesis thread,
+     * while in {@link TextToSpeechService#onSynthesizeText} or
+     * {@link TextToSpeechService#onSynthesizeTextV2}.
+     *
+     * Useful for checking if a fallback from network request is possible.
+     */
+    public boolean hasFinished();
+}
diff --git a/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java b/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java
index e853c9e..b424356 100644
--- a/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java
+++ b/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java
@@ -57,23 +57,22 @@
      */
     private volatile boolean mStopped;
     private volatile boolean mDone;
-    private volatile boolean mIsError;
+    private volatile int mStatusCode;
 
     private final BlockingAudioTrack mAudioTrack;
-    private final EventLogger mLogger;
-
+    private final AbstractEventLogger mLogger;
 
     SynthesisPlaybackQueueItem(int streamType, int sampleRate,
             int audioFormat, int channelCount,
             float volume, float pan, UtteranceProgressDispatcher dispatcher,
-            Object callerIdentity, EventLogger logger) {
+            Object callerIdentity, AbstractEventLogger logger) {
         super(dispatcher, callerIdentity);
 
         mUnconsumedBytes = 0;
 
         mStopped = false;
         mDone = false;
-        mIsError = false;
+        mStatusCode = TextToSpeechClient.Status.SUCCESS;
 
         mAudioTrack = new BlockingAudioTrack(streamType, sampleRate, audioFormat,
                 channelCount, volume, pan);
@@ -86,9 +85,8 @@
         final UtteranceProgressDispatcher dispatcher = getDispatcher();
         dispatcher.dispatchOnStart();
 
-
         if (!mAudioTrack.init()) {
-            dispatcher.dispatchOnError();
+            dispatcher.dispatchOnError(TextToSpeechClient.Status.ERROR_OUTPUT);
             return;
         }
 
@@ -112,23 +110,25 @@
 
         mAudioTrack.waitAndRelease();
 
-        if (mIsError) {
-            dispatcher.dispatchOnError();
+        if (mStatusCode == TextToSpeechClient.Status.SUCCESS) {
+            dispatcher.dispatchOnSuccess();
+        } else if(mStatusCode == TextToSpeechClient.Status.STOPPED) {
+            dispatcher.dispatchOnStop();
         } else {
-            dispatcher.dispatchOnDone();
+            dispatcher.dispatchOnError(mStatusCode);
         }
 
-        mLogger.onWriteData();
+        mLogger.onCompleted(mStatusCode);
     }
 
     @Override
-    void stop(boolean isError) {
+    void stop(int statusCode) {
         try {
             mListLock.lock();
 
             // Update our internal state.
             mStopped = true;
-            mIsError = isError;
+            mStatusCode = statusCode;
 
             // Wake up the audio playback thread if it was waiting on take().
             // take() will return null since mStopped was true, and will then
diff --git a/core/java/android/speech/tts/SynthesisRequestV2.aidl b/core/java/android/speech/tts/SynthesisRequestV2.aidl
new file mode 100644
index 0000000..2ac7da6
--- /dev/null
+++ b/core/java/android/speech/tts/SynthesisRequestV2.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** 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.speech.tts;
+
+parcelable SynthesisRequestV2;
\ No newline at end of file
diff --git a/core/java/android/speech/tts/SynthesisRequestV2.java b/core/java/android/speech/tts/SynthesisRequestV2.java
new file mode 100644
index 0000000..ed268b7
--- /dev/null
+++ b/core/java/android/speech/tts/SynthesisRequestV2.java
@@ -0,0 +1,132 @@
+package android.speech.tts;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.speech.tts.TextToSpeechClient.UtteranceId;
+
+/**
+ * Service-side representation of a synthesis request from a V2 API client. Contains:
+ * <ul>
+ *   <li>The utterance to synthesize</li>
+ *   <li>The id of the utterance (String, result of {@link UtteranceId#toUniqueString()}</li>
+ *   <li>The synthesis voice name (String, result of {@link VoiceInfo#getName()})</li>
+ *   <li>Voice parameters (Bundle of parameters)</li>
+ *   <li>Audio parameters (Bundle of parameters)</li>
+ * </ul>
+ */
+public final class SynthesisRequestV2 implements Parcelable {
+    /** Synthesis utterance. */
+    private final String mText;
+
+    /** Synthesis id. */
+    private final String mUtteranceId;
+
+    /** Voice ID. */
+    private final String mVoiceName;
+
+    /** Voice Parameters. */
+    private final Bundle mVoiceParams;
+
+    /** Audio Parameters. */
+    private final Bundle mAudioParams;
+
+    /**
+     * Parcel based constructor.
+     *
+     * @hide
+     */
+    public SynthesisRequestV2(Parcel in) {
+        this.mText = in.readString();
+        this.mUtteranceId = in.readString();
+        this.mVoiceName = in.readString();
+        this.mVoiceParams = in.readBundle();
+        this.mAudioParams = in.readBundle();
+    }
+
+    SynthesisRequestV2(String text, String utteranceId, RequestConfig rconfig) {
+        this.mText = text;
+        this.mUtteranceId = utteranceId;
+        this.mVoiceName = rconfig.getVoice().getName();
+        this.mVoiceParams = rconfig.getVoiceParams();
+        this.mAudioParams = rconfig.getAudioParams();
+    }
+
+    /**
+     * Write to parcel.
+     *
+     * @hide
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mText);
+        dest.writeString(mUtteranceId);
+        dest.writeString(mVoiceName);
+        dest.writeBundle(mVoiceParams);
+        dest.writeBundle(mAudioParams);
+    }
+
+    /**
+     * @return the text which should be synthesized.
+     */
+    public String getText() {
+        return mText;
+    }
+
+    /**
+     * @return the id of the synthesis request. It's an output of a call to the
+     * {@link UtteranceId#toUniqueString()} method of the {@link UtteranceId} associated with
+     * this request.
+     */
+    public String getUtteranceId() {
+        return mUtteranceId;
+    }
+
+    /**
+     * @return the name of the voice to use for this synthesis request. Result of a call to
+     * the {@link VoiceInfo#getName()} method.
+     */
+    public String getVoiceName() {
+        return mVoiceName;
+    }
+
+    /**
+     * @return bundle of voice parameters.
+     */
+    public Bundle getVoiceParams() {
+        return mVoiceParams;
+    }
+
+    /**
+     * @return bundle of audio parameters.
+     */
+    public Bundle getAudioParams() {
+        return mAudioParams;
+    }
+
+    /**
+     * Parcel creators.
+     *
+     * @hide
+     */
+    public static final Parcelable.Creator<SynthesisRequestV2> CREATOR =
+            new Parcelable.Creator<SynthesisRequestV2>() {
+        @Override
+        public SynthesisRequestV2 createFromParcel(Parcel source) {
+            return new SynthesisRequestV2(source);
+        }
+
+        @Override
+        public SynthesisRequestV2[] newArray(int size) {
+            return new SynthesisRequestV2[size];
+        }
+    };
+
+    /**
+     * @hide
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 2752085..02152fb 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -54,7 +54,9 @@
  * When you are done using the TextToSpeech instance, call the {@link #shutdown()} method
  * to release the native resources used by the TextToSpeech engine.
  *
+ * @deprecated Use {@link TextToSpeechClient} instead
  */
+@Deprecated
 public class TextToSpeech {
 
     private static final String TAG = "TextToSpeech";
@@ -970,7 +972,7 @@
             @Override
             public Integer run(ITextToSpeechService service) throws RemoteException {
                 return service.playSilence(getCallerIdentity(), durationInMs, queueMode,
-                        getParams(params));
+                        params == null ? null : params.get(Engine.KEY_PARAM_UTTERANCE_ID));
             }
         }, ERROR, "playSilence");
     }
@@ -1443,8 +1445,17 @@
         private boolean mEstablished;
 
         private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() {
+            public void onStop(String utteranceId) throws RemoteException {
+                // do nothing
+            };
+
             @Override
-            public void onDone(String utteranceId) {
+            public void onFallback(String utteranceId) throws RemoteException {
+                // do nothing
+            }
+
+            @Override
+            public void onSuccess(String utteranceId) {
                 UtteranceProgressListener listener = mUtteranceProgressListener;
                 if (listener != null) {
                     listener.onDone(utteranceId);
@@ -1452,7 +1463,7 @@
             }
 
             @Override
-            public void onError(String utteranceId) {
+            public void onError(String utteranceId, int errorCode) {
                 UtteranceProgressListener listener = mUtteranceProgressListener;
                 if (listener != null) {
                     listener.onError(utteranceId);
@@ -1466,6 +1477,11 @@
                     listener.onStart(utteranceId);
                 }
             }
+
+            @Override
+            public void onVoicesInfoChange(List<VoiceInfo> voicesInfo) throws RemoteException {
+                // Ignore it
+            }
         };
 
         private class SetupConnectionAsyncTask extends AsyncTask<Void, Void, Integer> {
diff --git a/core/java/android/speech/tts/TextToSpeechClient.java b/core/java/android/speech/tts/TextToSpeechClient.java
new file mode 100644
index 0000000..0d8d42c
--- /dev/null
+++ b/core/java/android/speech/tts/TextToSpeechClient.java
@@ -0,0 +1,1054 @@
+/*
+ * 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.speech.tts;
+
+import android.app.Activity;
+import android.app.Application;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.speech.tts.ITextToSpeechCallback;
+import android.speech.tts.ITextToSpeechService;
+import android.util.Log;
+import android.util.Pair;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Synthesizes speech from text for immediate playback or to create a sound
+ * file.
+ * <p>
+ * This is an updated version of the speech synthesis client that supersedes
+ * {@link android.speech.tts.TextToSpeech}.
+ * <p>
+ * A TextToSpeechClient instance can only be used to synthesize text once it has
+ * connected to the service. The TextToSpeechClient instance will start establishing
+ * the connection after a call to the {@link #connect()} method. This is usually done in
+ * {@link Application#onCreate()} or {@link Activity#onCreate}. When the connection
+ * is established, the instance will call back using the
+ * {@link TextToSpeechClient.ConnectionCallbacks} interface. Only after a
+ * successful callback is the client usable.
+ * <p>
+ * After successful connection, the list of all available voices can be obtained
+ * by calling the {@link TextToSpeechClient#getEngineStatus() method. The client can
+ * choose a voice using some custom heuristic and build a {@link RequestConfig} object
+ * using {@link RequestConfig.Builder}, or can use one of the common heuristics found
+ * in ({@link RequestConfigHelper}.
+ * <p>
+ * When you are done using the TextToSpeechClient instance, call the
+ * {@link #disconnect()} method to release the connection.
+ * <p>
+ * In the rare case of a change to the set of available voices, the service will call to the
+ * {@link ConnectionCallbacks#onEngineStatusChange} with new set of available voices as argument.
+ * In response, the client HAVE to recreate all {@link RequestConfig} instances in use.
+ */
+public final class TextToSpeechClient {
+    private static final String TAG = TextToSpeechClient.class.getSimpleName();
+
+    private final Object mLock = new Object();
+    private final TtsEngines mEnginesHelper;
+    private final Context mContext;
+
+    // Guarded by mLock
+    private Connection mServiceConnection;
+    private final RequestCallbacks mDefaultRequestCallbacks;
+    private final ConnectionCallbacks mConnectionCallbacks;
+    private EngineStatus mEngineStatus;
+    private String mRequestedEngine;
+    private boolean mFallbackToDefault;
+    private HashMap<String, Pair<UtteranceId, RequestCallbacks>> mCallbacks;
+    // Guarded by mLock
+
+    /** Common voices parameters */
+    public static final class Params {
+        private Params() {}
+
+        /**
+         * Maximum allowed time for a single request attempt, in milliseconds, before synthesis
+         * fails (or fallback request starts, if requested using
+         * {@link #FALLBACK_VOICE_NAME}).
+         */
+        public static final String NETWORK_TIMEOUT_MS = "networkTimeoutMs";
+
+        /**
+         * Number of network request retries that are attempted in case of failure
+         */
+        public static final String NETWORK_RETRIES_COUNT = "networkRetriesCount";
+
+        /**
+         * Should synthesizer report sub-utterance progress on synthesis. Only applicable
+         * for the {@link TextToSpeechClient#queueSpeak} method.
+         */
+        public static final String TRACK_SUBUTTERANCE_PROGRESS = "trackSubutteranceProgress";
+
+        /**
+         * If a voice exposes this parameter then it supports the fallback request feature.
+         *
+         * If it is set to a valid name of some other voice ({@link VoiceInfo#getName()}) then
+         * in case of request failure (due to network problems or missing data), fallback request
+         * will be attempted. Request will be done using the voice referenced by this parameter.
+         * If it is the case, the client will be informed by a callback to the {@link
+         * RequestCallbacks#onSynthesisFallback(UtteranceId)}.
+         */
+        public static final String FALLBACK_VOICE_NAME = "fallbackVoiceName";
+
+        /**
+         * Audio parameter for specifying a linear multiplier to the speaking speed of the voice.
+         * The value is a float. Values below zero decrease speed of the synthesized speech
+         * values above one increase it. If the value of this parameter is equal to zero,
+         * then it will be replaced by a settings-configurable default before it reaches
+         * TTS service.
+         */
+        public static final String SPEECH_SPEED = "speechSpeed";
+
+        /**
+         * Audio parameter for controlling the pitch of the output. The Value is a positive float,
+         * with default of {@code 1.0}. The value is used to scale the primary frequency linearly.
+         * Lower values lower the tone of the synthesized voice, greater values increase it.
+         */
+        public static final String SPEECH_PITCH = "speechPitch";
+
+        /**
+         * Audio parameter for controlling output volume. Value is a float with scale of 0 to 1
+         */
+        public static final String AUDIO_PARAM_VOLUME = TextToSpeech.Engine.KEY_PARAM_VOLUME;
+
+        /**
+         * Audio parameter for controlling output pan.
+         * Value is a float ranging from -1 to +1 where -1 maps to a hard-left pan,
+         * 0 to center (the default behavior), and +1 to hard-right.
+         */
+        public static final String AUDIO_PARAM_PAN = TextToSpeech.Engine.KEY_PARAM_PAN;
+
+        /**
+         * Audio parameter for specifying the audio stream type to be used when speaking text
+         * or playing back a file. The value should be one of the STREAM_ constants
+         * defined in {@link AudioManager}.
+         */
+        public static final String AUDIO_PARAM_STREAM = TextToSpeech.Engine.KEY_PARAM_STREAM;
+    }
+
+    /**
+     * Result codes for TTS operations.
+     */
+    public static final class Status {
+        private Status() {}
+
+        /**
+         * Denotes a successful operation.
+         */
+        public static final int SUCCESS = 0;
+
+        /**
+         * Denotes a stop requested by a client. It's used only on the service side of the API,
+         * client should never expect to see this result code.
+         */
+        public static final int STOPPED = 100;
+
+        /**
+         * Denotes a generic failure.
+         */
+        public static final int ERROR_UNKNOWN = -1;
+
+        /**
+         * Denotes a failure of a TTS engine to synthesize the given input.
+         */
+        public static final int ERROR_SYNTHESIS = 10;
+
+        /**
+         * Denotes a failure of a TTS service.
+         */
+        public static final int ERROR_SERVICE = 11;
+
+        /**
+         * Denotes a failure related to the output (audio device or a file).
+         */
+        public static final int ERROR_OUTPUT = 12;
+
+        /**
+         * Denotes a failure caused by a network connectivity problems.
+         */
+        public static final int ERROR_NETWORK = 13;
+
+        /**
+         * Denotes a failure caused by network timeout.
+         */
+        public static final int ERROR_NETWORK_TIMEOUT = 14;
+
+        /**
+         * Denotes a failure caused by an invalid request.
+         */
+        public static final int ERROR_INVALID_REQUEST = 15;
+
+        /**
+         * Denotes a failure related to passing a non-unique utterance id.
+         */
+        public static final int ERROR_NON_UNIQUE_UTTERANCE_ID = 16;
+
+        /**
+         * Denotes a failure related to missing data. The TTS implementation may download
+         * the missing data, and if so, request will succeed in future. This error can only happen
+         * for voices with {@link VoiceInfo#FEATURE_MAY_AUTOINSTALL} feature.
+         * Note: the recommended way to avoid this error is to create a request with the fallback
+         * voice.
+         */
+        public static final int ERROR_DOWNLOADING_ADDITIONAL_DATA = 17;
+    }
+
+    /**
+     * Set of callbacks for the events related to the progress of a synthesis request
+     * through the synthesis queue. Each synthesis request is associated with a call to
+     * {@link #queueSpeak} or {@link #queueSynthesizeToFile}.
+     *
+     * The callbacks specified in this method will NOT be called on UI thread.
+     */
+    public static abstract class RequestCallbacks  {
+        /**
+         * Called after synthesis of utterance successfully starts.
+         */
+        public void onSynthesisStart(UtteranceId utteranceId) {}
+
+        /**
+         * Called after synthesis successfully finishes.
+         * @param utteranceId
+         *            Unique identifier of synthesized utterance.
+         */
+        public void onSynthesisSuccess(UtteranceId utteranceId) {}
+
+        /**
+         * Called after synthesis was stopped in middle of synthesis process.
+         * @param utteranceId
+         *            Unique identifier of synthesized utterance.
+         */
+        public void onSynthesisStop(UtteranceId utteranceId) {}
+
+        /**
+         * Called when requested synthesis failed and fallback synthesis is about to be attempted.
+         *
+         * Requires voice with available {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME}
+         * parameter, and request with this parameter enabled.
+         *
+         * This callback will be followed by callback to the {@link #onSynthesisStart},
+         * {@link #onSynthesisFailure} or {@link #onSynthesisSuccess} that depends on the
+         * fallback outcome.
+         *
+         * For more fallback feature reference, look at the
+         * {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME}.
+         *
+         * @param utteranceId
+         *            Unique identifier of synthesized utterance.
+         */
+        public void onSynthesisFallback(UtteranceId utteranceId) {}
+
+        /**
+         * Called after synthesis of utterance fails.
+         *
+         * It may be called instead or after a {@link #onSynthesisStart} callback.
+         *
+         * @param utteranceId
+         *            Unique identifier of synthesized utterance.
+         * @param errorCode
+         *            One of the values from {@link Status}.
+         */
+        public void onSynthesisFailure(UtteranceId utteranceId, int errorCode) {}
+
+        /**
+         * Called during synthesis to mark synthesis progress.
+         *
+         * Requires voice with available
+         * {@link TextToSpeechClient.Params#TRACK_SUBUTTERANCE_PROGRESS} parameter, and
+         * request with this parameter enabled.
+         *
+         * @param utteranceId
+         *            Unique identifier of synthesized utterance.
+         * @param charIndex
+         *            String index (java char offset) of recently synthesized character.
+         * @param msFromStart
+         *            Miliseconds from the start of the synthesis.
+         */
+        public void onSynthesisProgress(UtteranceId utteranceId, int charIndex, int msFromStart) {}
+    }
+
+    /**
+     * Interface definition of callbacks that are called when the client is
+     * connected or disconnected from the TTS service.
+     */
+    public static interface ConnectionCallbacks {
+        /**
+         * After calling {@link TextToSpeechClient#connect()}, this method will be invoked
+         * asynchronously when the connect request has successfully completed.
+         *
+         * Clients are strongly encouraged to call {@link TextToSpeechClient#getEngineStatus()}
+         * and create {@link RequestConfig} objects used in subsequent synthesis requests.
+         */
+        public void onConnectionSuccess();
+
+        /**
+         * After calling {@link TextToSpeechClient#connect()}, this method may be invoked
+         * asynchronously when the connect request has failed to complete.
+         *
+         * It may be also invoked synchronously, from the body of
+         * {@link TextToSpeechClient#connect()} method.
+         */
+        public void onConnectionFailure();
+
+        /**
+         * Called when the connection to the service is lost. This can happen if there is a problem
+         * with the speech service (e.g. a crash or resource problem causes it to be killed by the
+         * system). When called, all requests have been canceled and no outstanding listeners will
+         * be executed. Applications should disable UI components that require the service.
+         */
+        public void onServiceDisconnected();
+
+        /**
+         * After receiving {@link #onConnectionSuccess()} callback, this method may be invoked
+         * if engine status obtained from {@link TextToSpeechClient#getEngineStatus()}) changes.
+         * It usually means that some voices were removed, changed or added.
+         *
+         * Clients are required to recreate {@link RequestConfig} objects used in subsequent
+         * synthesis requests.
+         */
+        public void onEngineStatusChange(EngineStatus newEngineStatus);
+    }
+
+    /** State of voices as provided by engine and user. */
+    public static final class EngineStatus {
+        /** All available voices. */
+        private final List<VoiceInfo> mVoices;
+
+        /** Name of the TTS engine package */
+        private final String mPackageName;
+
+        private EngineStatus(String packageName, List<VoiceInfo> voices) {
+            this.mVoices =  Collections.unmodifiableList(voices);
+            this.mPackageName = packageName;
+        }
+
+        /**
+         * Get an immutable list of all Voices exposed by the TTS engine.
+         */
+        public List<VoiceInfo> getVoices() {
+            return mVoices;
+        }
+
+        /**
+         * Get name of the TTS engine package currently in use.
+         */
+        public String getEnginePackage() {
+            return mPackageName;
+        }
+    }
+
+    /** Unique synthesis request identifier. */
+    public static final class UtteranceId {
+        private final String mDescription;
+        /**
+         * Create new, unique UtteranceId instance.
+         */
+        public UtteranceId() {
+            mDescription = null;
+        }
+
+        /**
+         * Create new, unique UtteranceId instance.
+         *
+         * @param description Additional string, that will be appended to
+         * {@link #toUniqueString()} output, allowing easier identification of the utterance in
+         * callbacks.
+         */
+        public UtteranceId(String description) {
+            mDescription = description;
+        }
+
+        /**
+         * Returns a unique string associated with an instance of this object.
+         *
+         * If you subclass {@link UtteranceId} make sure that output of this method is
+         * consistent across multiple calls and unique for the instance.
+         *
+         * This string will be used to identify the synthesis request/utterance inside the
+         * TTS service.
+         */
+        public String toUniqueString() {
+            return mDescription == null ? "UtteranceId" + System.identityHashCode(this) :
+                    "UtteranceId" + System.identityHashCode(this) + ": " + mDescription;
+        }
+    }
+
+    /**
+     * Create TextToSpeech service client.
+     *
+     * Will connect to the default TTS service. In order to be usable, {@link #connect()} need
+     * to be called first and successful connection callback need to be received.
+     *
+     * @param context
+     *            The context this instance is running in.
+     * @param engine
+     *            Package name of requested TTS engine. If it's null, then default engine will
+     *            be selected regardless of {@code fallbackToDefaultEngine} parameter value.
+     * @param fallbackToDefaultEngine
+     *            If requested engine is not available, should we fallback to the default engine?
+     * @param defaultRequestCallbacks
+     *            Default request callbacks, it will be used for all synthesis requests without
+     *            supplied RequestCallbacks instance. Can't be null.
+     * @param connectionCallbacks
+     *            Callbacks for connecting and disconnecting from the service. Can't be null.
+     */
+    public TextToSpeechClient(Context context,
+            String engine, boolean fallbackToDefaultEngine,
+            RequestCallbacks defaultRequestCallbacks,
+            ConnectionCallbacks connectionCallbacks) {
+        if (context == null)
+            throw new IllegalArgumentException("context can't be null");
+        if (defaultRequestCallbacks == null)
+            throw new IllegalArgumentException("defaultRequestCallbacks can't be null");
+        if (connectionCallbacks == null)
+            throw new IllegalArgumentException("connectionCallbacks can't be null");
+        mContext = context;
+        mEnginesHelper = new TtsEngines(mContext);
+        mCallbacks = new HashMap<String, Pair<UtteranceId, RequestCallbacks>>();
+        mDefaultRequestCallbacks = defaultRequestCallbacks;
+        mConnectionCallbacks = connectionCallbacks;
+
+        mRequestedEngine = engine;
+        mFallbackToDefault = fallbackToDefaultEngine;
+    }
+
+    /**
+     * Create TextToSpeech service client. Will connect to the default TTS
+     * service. In order to be usable, {@link #connect()} need to be called
+     * first and successful connection callback need to be received.
+     *
+     * @param context Context this instance is running in.
+     * @param defaultRequestCallbacks Default request callbacks, it
+     *            will be used for all synthesis requests without supplied
+     *            RequestCallbacks instance. Can't be null.
+     * @param connectionCallbacks Callbacks for connecting and disconnecting
+     *            from the service. Can't be null.
+     */
+    public TextToSpeechClient(Context context, RequestCallbacks defaultRequestCallbacks,
+            ConnectionCallbacks connectionCallbacks) {
+        this(context, null, true, defaultRequestCallbacks, connectionCallbacks);
+    }
+
+
+    private boolean initTts(String requestedEngine, boolean fallbackToDefaultEngine) {
+        // Step 1: Try connecting to the engine that was requested.
+        if (requestedEngine != null) {
+            if (mEnginesHelper.isEngineInstalled(requestedEngine)) {
+                if ((mServiceConnection = connectToEngine(requestedEngine)) != null) {
+                    return true;
+                } else if (!fallbackToDefaultEngine) {
+                    Log.w(TAG, "Couldn't connect to requested engine: " + requestedEngine);
+                    return false;
+                }
+            } else if (!fallbackToDefaultEngine) {
+                Log.w(TAG, "Requested engine not installed: " + requestedEngine);
+                return false;
+            }
+        }
+
+        // Step 2: Try connecting to the user's default engine.
+        final String defaultEngine = mEnginesHelper.getDefaultEngine();
+        if (defaultEngine != null && !defaultEngine.equals(requestedEngine)) {
+            if ((mServiceConnection = connectToEngine(defaultEngine)) != null) {
+                return true;
+            }
+        }
+
+        // Step 3: Try connecting to the highest ranked engine in the
+        // system.
+        final String highestRanked = mEnginesHelper.getHighestRankedEngineName();
+        if (highestRanked != null && !highestRanked.equals(requestedEngine) &&
+                !highestRanked.equals(defaultEngine)) {
+            if ((mServiceConnection = connectToEngine(highestRanked)) != null) {
+                return true;
+            }
+        }
+
+        Log.w(TAG, "Couldn't find working TTS engine");
+        return false;
+    }
+
+    private Connection connectToEngine(String engine) {
+        Connection connection = new Connection(engine);
+        Intent intent = new Intent(TextToSpeech.Engine.INTENT_ACTION_TTS_SERVICE);
+        intent.setPackage(engine);
+        boolean bound = mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE);
+        if (!bound) {
+            Log.e(TAG, "Failed to bind to " + engine);
+            return null;
+        } else {
+            Log.i(TAG, "Successfully bound to " + engine);
+            return connection;
+        }
+    }
+
+
+    /**
+     * Connects the client to TTS service. This method returns immediately, and connects to the
+     * service in the background.
+     *
+     * After connection initializes successfully, {@link ConnectionCallbacks#onConnectionSuccess()}
+     * is called. On a failure {@link ConnectionCallbacks#onConnectionFailure} is called.
+     *
+     * Both of those callback may be called asynchronously on the main thread,
+     * {@link ConnectionCallbacks#onConnectionFailure} may be called synchronously, before
+     * this method returns.
+     */
+    public void connect() {
+        synchronized (mLock) {
+            if (mServiceConnection != null) {
+                return;
+            }
+            if(!initTts(mRequestedEngine, mFallbackToDefault)) {
+                mConnectionCallbacks.onConnectionFailure();
+            }
+        }
+    }
+
+    /**
+     * Checks if the client is currently connected to the service, so that
+     * requests to other methods will succeed.
+     */
+    public boolean isConnected() {
+        synchronized (mLock) {
+            return mServiceConnection != null && mServiceConnection.isEstablished();
+        }
+    }
+
+    /**
+     * Closes the connection to TextToSpeech service. No calls can be made on this object after
+     * calling this method.
+     * It is good practice to call this method in the onDestroy() method of an Activity
+     * so the TextToSpeech engine can be cleanly stopped.
+     */
+    public void disconnect() {
+        synchronized (mLock) {
+            if (mServiceConnection != null) {
+                mServiceConnection.disconnect();
+                mServiceConnection = null;
+                mCallbacks.clear();
+            }
+        }
+    }
+
+    /**
+     * Register callback.
+     *
+     * @param utteranceId Non-null UtteranceId instance.
+     * @param callback Non-null callbacks for the request
+     * @return Status.SUCCESS or error code in case of invalid arguments.
+     */
+    private int addCallback(UtteranceId utteranceId, RequestCallbacks callback) {
+        synchronized (mLock) {
+            if (utteranceId == null || callback == null) {
+                return Status.ERROR_INVALID_REQUEST;
+            }
+            if (mCallbacks.put(utteranceId.toUniqueString(),
+                    new Pair<UtteranceId, RequestCallbacks>(utteranceId, callback)) != null) {
+                return Status.ERROR_NON_UNIQUE_UTTERANCE_ID;
+            }
+            return Status.SUCCESS;
+        }
+    }
+
+    /**
+     * Remove and return callback.
+     *
+     * @param utteranceIdStr Unique string obtained from {@link UtteranceId#toUniqueString}.
+     */
+    private Pair<UtteranceId, RequestCallbacks> removeCallback(String utteranceIdStr) {
+        synchronized (mLock) {
+            return mCallbacks.remove(utteranceIdStr);
+        }
+    }
+
+    /**
+     * Get callback and utterance id.
+     *
+     * @param utteranceIdStr Unique string obtained from {@link UtteranceId#toUniqueString}.
+     */
+    private Pair<UtteranceId, RequestCallbacks> getCallback(String utteranceIdStr) {
+        synchronized (mLock) {
+            return mCallbacks.get(utteranceIdStr);
+        }
+    }
+
+    /**
+     * Remove callback and call {@link RequestCallbacks#onSynthesisFailure} with passed
+     * error code.
+     *
+     * @param utteranceIdStr Unique string obtained from {@link UtteranceId#toUniqueString}.
+     * @param errorCode argument to {@link RequestCallbacks#onSynthesisFailure} call.
+     */
+    private void removeCallbackAndErr(String utteranceIdStr, int errorCode) {
+        synchronized (mLock) {
+            Pair<UtteranceId, RequestCallbacks> c = mCallbacks.remove(utteranceIdStr);
+            c.second.onSynthesisFailure(c.first, errorCode);
+        }
+    }
+
+    /**
+     * Retrieve TTS engine status {@link EngineStatus}. Requires connected client.
+     */
+    public EngineStatus getEngineStatus() {
+        synchronized (mLock) {
+            return mEngineStatus;
+        }
+    }
+
+    /**
+     * Query TTS engine about available voices and defaults.
+     *
+     * @return EngineStatus is connected or null if client is disconnected.
+     */
+    private EngineStatus requestEngineStatus(ITextToSpeechService service)
+            throws RemoteException {
+        List<VoiceInfo> voices = service.getVoicesInfo();
+        if (voices == null) {
+            Log.e(TAG, "Requested engine doesn't support TTS V2 API");
+            return null;
+        }
+
+        return new EngineStatus(mServiceConnection.getEngineName(), voices);
+    }
+
+    private class Connection implements ServiceConnection {
+        private final String mEngineName;
+
+        private ITextToSpeechService mService;
+
+        private boolean mEstablished;
+
+        private PrepareConnectionAsyncTask mSetupConnectionAsyncTask;
+
+        public Connection(String engineName) {
+            this.mEngineName = engineName;
+        }
+
+        private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() {
+
+            @Override
+            public void onStart(String utteranceIdStr) {
+                synchronized (mLock) {
+                    Pair<UtteranceId, RequestCallbacks> callbacks = getCallback(utteranceIdStr);
+                    callbacks.second.onSynthesisStart(callbacks.first);
+                }
+            }
+
+            public void onStop(String utteranceIdStr) {
+                synchronized (mLock) {
+                    Pair<UtteranceId, RequestCallbacks> callbacks = removeCallback(utteranceIdStr);
+                    callbacks.second.onSynthesisStop(callbacks.first);
+                }
+            }
+
+            @Override
+            public void onSuccess(String utteranceIdStr) {
+                synchronized (mLock) {
+                    Pair<UtteranceId, RequestCallbacks> callbacks = removeCallback(utteranceIdStr);
+                    callbacks.second.onSynthesisSuccess(callbacks.first);
+                }
+            }
+
+            public void onFallback(String utteranceIdStr) {
+                synchronized (mLock) {
+                    Pair<UtteranceId, RequestCallbacks> callbacks = getCallback(utteranceIdStr);
+                    callbacks.second.onSynthesisFallback(callbacks.first);
+                }
+            };
+
+            @Override
+            public void onError(String utteranceIdStr, int errorCode) {
+                removeCallbackAndErr(utteranceIdStr, errorCode);
+            }
+
+            @Override
+            public void onVoicesInfoChange(List<VoiceInfo> voicesInfo) {
+                synchronized (mLock) {
+                    mEngineStatus = new EngineStatus(mServiceConnection.getEngineName(),
+                            voicesInfo);
+                    mConnectionCallbacks.onEngineStatusChange(mEngineStatus);
+                }
+            }
+        };
+
+        private class PrepareConnectionAsyncTask extends AsyncTask<Void, Void, EngineStatus> {
+
+            private final ComponentName mName;
+
+            public PrepareConnectionAsyncTask(ComponentName name) {
+                mName = name;
+            }
+
+            @Override
+            protected EngineStatus doInBackground(Void... params) {
+                synchronized(mLock) {
+                    if (isCancelled()) {
+                        return null;
+                    }
+                    try {
+                        mService.setCallback(getCallerIdentity(), mCallback);
+                        return requestEngineStatus(mService);
+                    } catch (RemoteException re) {
+                        Log.e(TAG, "Error setting up the TTS service");
+                        return null;
+                    }
+                }
+            }
+
+            @Override
+            protected void onPostExecute(EngineStatus result) {
+                synchronized(mLock) {
+                    if (mSetupConnectionAsyncTask == this) {
+                        mSetupConnectionAsyncTask = null;
+                    }
+                    if (result == null) {
+                        Log.e(TAG, "Setup task failed");
+                        disconnect();
+                        mConnectionCallbacks.onConnectionFailure();
+                        return;
+                    }
+
+                    mEngineStatus = result;
+                    mEstablished = true;
+                }
+                mConnectionCallbacks.onConnectionSuccess();
+            }
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            Log.i(TAG, "Connected to " + name);
+
+            synchronized(mLock) {
+                mEstablished = false;
+                mService = ITextToSpeechService.Stub.asInterface(service);
+                startSetupConnectionTask(name);
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            Log.i(TAG, "Asked to disconnect from " + name);
+
+            synchronized(mLock) {
+                stopSetupConnectionTask();
+            }
+            mConnectionCallbacks.onServiceDisconnected();
+        }
+
+        private void startSetupConnectionTask(ComponentName name) {
+            stopSetupConnectionTask();
+            mSetupConnectionAsyncTask = new PrepareConnectionAsyncTask(name);
+            mSetupConnectionAsyncTask.execute();
+        }
+
+        private boolean stopSetupConnectionTask() {
+            boolean result = false;
+            if (mSetupConnectionAsyncTask != null) {
+                result = mSetupConnectionAsyncTask.cancel(false);
+                mSetupConnectionAsyncTask = null;
+            }
+            return result;
+        }
+
+        IBinder getCallerIdentity() {
+            return mCallback;
+        }
+
+        boolean isEstablished() {
+            return mService != null && mEstablished;
+        }
+
+        boolean runAction(Action action) {
+            synchronized (mLock) {
+                try {
+                    action.run(mService);
+                    return true;
+                } catch (Exception ex) {
+                    Log.e(TAG, action.getName() + " failed", ex);
+                    disconnect();
+                    return false;
+                }
+            }
+        }
+
+        void disconnect() {
+            mContext.unbindService(this);
+            stopSetupConnectionTask();
+            mService = null;
+            mEstablished = false;
+            if (mServiceConnection == this) {
+                mServiceConnection = null;
+            }
+        }
+
+        String getEngineName() {
+            return mEngineName;
+        }
+    }
+
+    private abstract class Action {
+        private final String mName;
+
+        public Action(String name) {
+            mName = name;
+        }
+
+        public String getName() {return mName;}
+        abstract void run(ITextToSpeechService service) throws RemoteException;
+    }
+
+    private IBinder getCallerIdentity() {
+        if (mServiceConnection != null) {
+            return mServiceConnection.getCallerIdentity();
+        }
+        return null;
+    }
+
+    private boolean runAction(Action action) {
+        synchronized (mLock) {
+            if (mServiceConnection == null) {
+                return false;
+            }
+            if (!mServiceConnection.isEstablished()) {
+                return false;
+            }
+            mServiceConnection.runAction(action);
+            return true;
+        }
+    }
+
+    private static final String ACTION_STOP_NAME = "stop";
+
+    /**
+     * Interrupts the current utterance spoken (whether played or rendered to file) and discards
+     * other utterances in the queue.
+     */
+    public void stop() {
+        runAction(new Action(ACTION_STOP_NAME) {
+            @Override
+            public void run(ITextToSpeechService service) throws RemoteException {
+               if (service.stop(getCallerIdentity()) != Status.SUCCESS) {
+                   Log.e(TAG, "Stop failed");
+               }
+               mCallbacks.clear();
+            }
+        });
+    }
+
+    private static final String ACTION_QUEUE_SPEAK_NAME = "queueSpeak";
+
+    /**
+     * Speaks the string using the specified queuing strategy using current
+     * voice. This method is asynchronous, i.e. the method just adds the request
+     * to the queue of TTS requests and then returns. The synthesis might not
+     * have finished (or even started!) at the time when this method returns.
+     *
+     * @param utterance The string of text to be spoken. No longer than
+     *            1000 characters.
+     * @param utteranceId Unique identificator used to track the synthesis progress
+     *            in {@link RequestCallbacks}.
+     * @param config Synthesis request configuration. Can't be null. Has to contain a
+     *            voice.
+     * @param callbacks Synthesis request callbacks. If null, default request
+     *            callbacks object will be used.
+     */
+    public void queueSpeak(final String utterance, final UtteranceId utteranceId,
+            final RequestConfig config,
+            final RequestCallbacks callbacks) {
+        runAction(new Action(ACTION_QUEUE_SPEAK_NAME) {
+            @Override
+            public void run(ITextToSpeechService service) throws RemoteException {
+                RequestCallbacks c = mDefaultRequestCallbacks;
+                if (callbacks != null) {
+                    c = callbacks;
+                }
+                int addCallbackStatus = addCallback(utteranceId, c);
+                if (addCallbackStatus != Status.SUCCESS) {
+                    c.onSynthesisFailure(utteranceId, Status.ERROR_INVALID_REQUEST);
+                    return;
+                }
+
+                int queueResult = service.speakV2(
+                        getCallerIdentity(),
+                        new SynthesisRequestV2(utterance, utteranceId.toUniqueString(), config));
+                if (queueResult != Status.SUCCESS) {
+                    removeCallbackAndErr(utteranceId.toUniqueString(), queueResult);
+                }
+            }
+        });
+    }
+
+    private static final String ACTION_QUEUE_SYNTHESIZE_TO_FILE = "queueSynthesizeToFile";
+
+    /**
+     * Synthesizes the given text to a file using the specified parameters. This
+     * method is asynchronous, i.e. the method just adds the request to the
+     * queue of TTS requests and then returns. The synthesis might not have
+     * finished (or even started!) at the time when this method returns.
+     *
+     * @param utterance The text that should be synthesized. No longer than
+     *            1000 characters.
+     * @param utteranceId Unique identificator used to track the synthesis progress
+     *            in {@link RequestCallbacks}.
+     * @param outputFile File to write the generated audio data to.
+     * @param config Synthesis request configuration. Can't be null. Have to contain a
+     *            voice.
+     * @param callbacks Synthesis request callbacks. If null, default request
+     *            callbacks object will be used.
+     */
+    public void queueSynthesizeToFile(final String utterance, final UtteranceId utteranceId,
+            final File outputFile, final RequestConfig config,
+            final RequestCallbacks callbacks) {
+        runAction(new Action(ACTION_QUEUE_SYNTHESIZE_TO_FILE) {
+            @Override
+            public void run(ITextToSpeechService service) throws RemoteException {
+                RequestCallbacks c = mDefaultRequestCallbacks;
+                if (callbacks != null) {
+                    c = callbacks;
+                }
+                int addCallbackStatus = addCallback(utteranceId, c);
+                if (addCallbackStatus != Status.SUCCESS) {
+                    c.onSynthesisFailure(utteranceId, Status.ERROR_INVALID_REQUEST);
+                    return;
+                }
+
+                ParcelFileDescriptor fileDescriptor = null;
+                try {
+                    if (outputFile.exists() && !outputFile.canWrite()) {
+                        Log.e(TAG, "No permissions to write to " + outputFile);
+                        removeCallbackAndErr(utteranceId.toUniqueString(), Status.ERROR_OUTPUT);
+                        return;
+                    }
+                    fileDescriptor = ParcelFileDescriptor.open(outputFile,
+                            ParcelFileDescriptor.MODE_WRITE_ONLY |
+                            ParcelFileDescriptor.MODE_CREATE |
+                            ParcelFileDescriptor.MODE_TRUNCATE);
+
+                    int queueResult = service.synthesizeToFileDescriptorV2(getCallerIdentity(),
+                            fileDescriptor,
+                            new SynthesisRequestV2(utterance, utteranceId.toUniqueString(),
+                                    config));
+                    fileDescriptor.close();
+                    if (queueResult != Status.SUCCESS) {
+                        removeCallbackAndErr(utteranceId.toUniqueString(), queueResult);
+                    }
+                } catch (FileNotFoundException e) {
+                    Log.e(TAG, "Opening file " + outputFile + " failed", e);
+                    removeCallbackAndErr(utteranceId.toUniqueString(), Status.ERROR_OUTPUT);
+                } catch (IOException e) {
+                    Log.e(TAG, "Closing file " + outputFile + " failed", e);
+                    removeCallbackAndErr(utteranceId.toUniqueString(), Status.ERROR_OUTPUT);
+                }
+            }
+        });
+    }
+
+    private static final String ACTION_QUEUE_SILENCE_NAME = "queueSilence";
+
+    /**
+     * Plays silence for the specified amount of time. This method is asynchronous,
+     * i.e. the method just adds the request to the queue of TTS requests and then
+     * returns. The synthesis might not have finished (or even started!) at the time
+     * when this method returns.
+     *
+     * @param durationInMs The duration of the silence in milliseconds.
+     * @param utteranceId Unique identificator used to track the synthesis progress
+     *            in {@link RequestCallbacks}.
+     * @param callbacks Synthesis request callbacks. If null, default request
+     *            callbacks object will be used.
+     */
+    public void queueSilence(final long durationInMs, final UtteranceId utteranceId,
+            final RequestCallbacks callbacks) {
+        runAction(new Action(ACTION_QUEUE_SILENCE_NAME) {
+            @Override
+            public void run(ITextToSpeechService service) throws RemoteException {
+                RequestCallbacks c = mDefaultRequestCallbacks;
+                if (callbacks != null) {
+                    c = callbacks;
+                }
+                int addCallbackStatus = addCallback(utteranceId, c);
+                if (addCallbackStatus != Status.SUCCESS) {
+                    c.onSynthesisFailure(utteranceId, Status.ERROR_INVALID_REQUEST);
+                }
+
+                int queueResult = service.playSilence(getCallerIdentity(), durationInMs,
+                        TextToSpeech.QUEUE_ADD, utteranceId.toUniqueString());
+
+                if (queueResult != Status.SUCCESS) {
+                    removeCallbackAndErr(utteranceId.toUniqueString(), queueResult);
+                }
+            }
+        });
+    }
+
+
+    private static final String ACTION_QUEUE_AUDIO_NAME = "queueAudio";
+
+    /**
+     * Plays the audio resource using the specified parameters.
+     * This method is asynchronous, i.e. the method just adds the request to the queue of TTS
+     * requests and then returns. The synthesis might not have finished (or even started!) at the
+     * time when this method returns.
+     *
+     * @param audioUrl The audio resource that should be played
+     * @param utteranceId Unique identificator used to track synthesis progress
+     *            in {@link RequestCallbacks}.
+     * @param config Synthesis request configuration. Can't be null. Doesn't have to contain a
+     *            voice (only system parameters are used).
+     * @param callbacks Synthesis request callbacks. If null, default request
+     *            callbacks object will be used.
+     */
+    public void queueAudio(final Uri audioUrl, final UtteranceId utteranceId,
+            final RequestConfig config, final RequestCallbacks callbacks) {
+        runAction(new Action(ACTION_QUEUE_AUDIO_NAME) {
+            @Override
+            public void run(ITextToSpeechService service) throws RemoteException {
+                RequestCallbacks c = mDefaultRequestCallbacks;
+                if (callbacks != null) {
+                    c = callbacks;
+                }
+                int addCallbackStatus = addCallback(utteranceId, c);
+                if (addCallbackStatus != Status.SUCCESS) {
+                    c.onSynthesisFailure(utteranceId, Status.ERROR_INVALID_REQUEST);
+                }
+
+                int queueResult = service.playAudioV2(getCallerIdentity(), audioUrl,
+                        utteranceId.toUniqueString(), config.getVoiceParams());
+
+                if (queueResult != Status.SUCCESS) {
+                    removeCallbackAndErr(utteranceId.toUniqueString(), queueResult);
+                }
+            }
+        });
+    }
+}
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 575855c..d7c51fc 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -34,26 +34,27 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
 import java.util.Set;
 
 
 /**
  * Abstract base class for TTS engine implementations. The following methods
- * need to be implemented.
- *
+ * need to be implemented for V1 API ({@link TextToSpeech}) implementation.
  * <ul>
- *   <li>{@link #onIsLanguageAvailable}</li>
- *   <li>{@link #onLoadLanguage}</li>
- *   <li>{@link #onGetLanguage}</li>
- *   <li>{@link #onSynthesizeText}</li>
- *   <li>{@link #onStop}</li>
+ * <li>{@link #onIsLanguageAvailable}</li>
+ * <li>{@link #onLoadLanguage}</li>
+ * <li>{@link #onGetLanguage}</li>
+ * <li>{@link #onSynthesizeText}</li>
+ * <li>{@link #onStop}</li>
  * </ul>
- *
  * The first three deal primarily with language management, and are used to
  * query the engine for it's support for a given language and indicate to it
  * that requests in a given language are imminent.
@@ -61,22 +62,44 @@
  * {@link #onSynthesizeText} is central to the engine implementation. The
  * implementation should synthesize text as per the request parameters and
  * return synthesized data via the supplied callback. This class and its helpers
- * will then consume that data, which might mean queueing it for playback or writing
- * it to a file or similar. All calls to this method will be on a single
- * thread, which will be different from the main thread of the service. Synthesis
- * must be synchronous which means the engine must NOT hold on the callback or call
- * any methods on it after the method returns
+ * will then consume that data, which might mean queuing it for playback or writing
+ * it to a file or similar. All calls to this method will be on a single thread,
+ * which will be different from the main thread of the service. Synthesis must be
+ * synchronous which means the engine must NOT hold on to the callback or call any
+ * methods on it after the method returns.
  *
- * {@link #onStop} tells the engine that it should stop all ongoing synthesis, if
- * any. Any pending data from the current synthesis will be discarded.
+ * {@link #onStop} tells the engine that it should stop
+ * all ongoing synthesis, if any. Any pending data from the current synthesis
+ * will be discarded.
  *
+ * {@link #onGetLanguage} is not required as of JELLYBEAN_MR2 (API 18) and later, it is only
+ * called on earlier versions of Android.
+ * <p>
+ * In order to fully support the V2 API ({@link TextToSpeechClient}),
+ * these methods must be implemented:
+ * <ul>
+ * <li>{@link #onSynthesizeTextV2}</li>
+ * <li>{@link #checkVoicesInfo}</li>
+ * <li>{@link #onVoicesInfoChange}</li>
+ * <li>{@link #implementsV2API}</li>
+ * </ul>
+ * In addition {@link #implementsV2API} has to return true.
+ * <p>
+ * If the service does not implement these methods and {@link #implementsV2API} returns false,
+ * then the V2 API will be provided by converting V2 requests ({@link #onSynthesizeTextV2})
+ * to V1 requests ({@link #onSynthesizeText}). On service setup, all of the available device
+ * locales will be fed to {@link #onIsLanguageAvailable} to check if they are supported.
+ * If they are, embedded and/or network voices will be created depending on the result of
+ * {@link #onGetFeaturesForLanguage}.
+ * <p>
+ * Note that a V2 service will still receive requests from V1 clients and has to implement all
+ * of the V1 API methods.
  */
 public abstract class TextToSpeechService extends Service {
 
     private static final boolean DBG = false;
     private static final String TAG = "TextToSpeechService";
 
-
     private static final String SYNTH_THREAD_NAME = "SynthThread";
 
     private SynthHandler mSynthHandler;
@@ -89,6 +112,11 @@
     private CallbackMap mCallbacks;
     private String mPackageName;
 
+    private final Object mVoicesInfoLock = new Object();
+
+    private List<VoiceInfo> mVoicesInfoList;
+    private Map<String, VoiceInfo> mVoicesInfoLookup;
+
     @Override
     public void onCreate() {
         if (DBG) Log.d(TAG, "onCreate()");
@@ -108,6 +136,7 @@
         mPackageName = getApplicationInfo().packageName;
 
         String[] defaultLocale = getSettingsLocale();
+
         // Load default language
         onLoadLanguage(defaultLocale[0], defaultLocale[1], defaultLocale[2]);
     }
@@ -148,6 +177,9 @@
     /**
      * Returns the language, country and variant currently being used by the TTS engine.
      *
+     * This method will be called only on Android 4.2 and before (API <= 17). In later versions
+     * this method is not called by the Android TTS framework.
+     *
      * Can be called on multiple threads.
      *
      * @return A 3-element array, containing language (ISO 3-letter code),
@@ -191,21 +223,159 @@
     protected abstract void onStop();
 
     /**
-     * Tells the service to synthesize speech from the given text. This method should
-     * block until the synthesis is finished.
-     *
-     * Called on the synthesis thread.
+     * Tells the service to synthesize speech from the given text. This method
+     * should block until the synthesis is finished. Used for requests from V1
+     * clients ({@link android.speech.tts.TextToSpeech}). Called on the synthesis
+     * thread.
      *
      * @param request The synthesis request.
-     * @param callback The callback the the engine must use to make data available for
-     *         playback or for writing to a file.
+     * @param callback The callback that the engine must use to make data
+     *            available for playback or for writing to a file.
      */
     protected abstract void onSynthesizeText(SynthesisRequest request,
             SynthesisCallback callback);
 
     /**
+     * Check the available voices data and return an immutable list of the available voices.
+     * The output of this method will be passed to clients to allow them to configure synthesis
+     * requests.
+     *
+     * Can be called on multiple threads.
+     *
+     * The result of this method will be saved and served to all TTS clients. If a TTS service wants
+     * to update the set of available voices, it should call the {@link #forceVoicesInfoCheck()}
+     * method.
+     */
+    protected List<VoiceInfo> checkVoicesInfo() {
+        if (implementsV2API()) {
+            throw new IllegalStateException("For proper V2 API implementation this method has to" +
+                    "  be implemented");
+        }
+
+        // V2 to V1 interface adapter. This allows using V2 client interface on V1-only services.
+        Bundle defaultParams = new Bundle();
+        defaultParams.putFloat(TextToSpeechClient.Params.SPEECH_PITCH, 1.0f);
+        defaultParams.putFloat(TextToSpeechClient.Params.SPEECH_SPEED, -1.0f);
+
+        // Enumerate all locales and check if they are available
+        ArrayList<VoiceInfo> voicesInfo = new ArrayList<VoiceInfo>();
+        int id = 0;
+        for (Locale locale : Locale.getAvailableLocales()) {
+            int expectedStatus = TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE;
+            if (locale.getVariant().isEmpty()) {
+                if (locale.getCountry().isEmpty()) {
+                    expectedStatus = TextToSpeech.LANG_AVAILABLE;
+                } else {
+                    expectedStatus = TextToSpeech.LANG_COUNTRY_AVAILABLE;
+                }
+            }
+            try {
+                int localeStatus = onIsLanguageAvailable(locale.getISO3Language(),
+                        locale.getISO3Country(), locale.getVariant());
+                if (localeStatus != expectedStatus) {
+                    continue;
+                }
+            } catch (MissingResourceException e) {
+                // Ignore locale without iso 3 codes
+                continue;
+            }
+
+            Set<String> features = onGetFeaturesForLanguage(locale.getISO3Language(),
+                        locale.getISO3Country(), locale.getVariant());
+
+            VoiceInfo.Builder builder = new VoiceInfo.Builder();
+            builder.setLatency(VoiceInfo.LATENCY_NORMAL);
+            builder.setQuality(VoiceInfo.QUALITY_NORMAL);
+            builder.setLocale(locale);
+            builder.setParamsWithDefaults(defaultParams);
+
+            if (features == null || features.contains(
+                    TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS)) {
+                builder.setName(locale.toString() + "-embedded");
+                builder.setRequiresNetworkConnection(false);
+                voicesInfo.add(builder.build());
+            }
+
+            if (features != null && features.contains(
+                    TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS)) {
+                builder.setName(locale.toString() + "-network");
+                builder.setRequiresNetworkConnection(true);
+                voicesInfo.add(builder.build());
+            }
+        }
+
+        return voicesInfo;
+    }
+
+    /**
+     * Tells the synthesis thread that it should reload voice data.
+     * There's a high probability that the underlying set of available voice data has changed.
+     * Called only on the synthesis thread.
+     */
+    protected void onVoicesInfoChange() {
+
+    }
+
+    /**
+     * Tells the service to synthesize speech from the given text. This method
+     * should block until the synthesis is finished. Used for requests from V2
+     * client {@link android.speech.tts.TextToSpeechClient}. Called on the
+     * synthesis thread.
+     *
+     * @param request The synthesis request.
+     * @param callback The callback the the engine must use to make data
+     *            available for playback or for writing to a file.
+     */
+    protected void onSynthesizeTextV2(SynthesisRequestV2 request,
+            VoiceInfo selectedVoice,
+            SynthesisCallback callback) {
+        if (implementsV2API()) {
+            throw new IllegalStateException("For proper V2 API implementation this method has to" +
+                    "  be implemented");
+        }
+
+        // Convert to V1 params
+        int speechRate = (int) (request.getVoiceParams().getFloat(
+                TextToSpeechClient.Params.SPEECH_SPEED, 1.0f) * 100);
+        int speechPitch = (int) (request.getVoiceParams().getFloat(
+                TextToSpeechClient.Params.SPEECH_PITCH, 1.0f) * 100);
+
+        // Provide adapter to V1 API
+        Bundle params = new Bundle();
+        params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, request.getUtteranceId());
+        params.putInt(TextToSpeech.Engine.KEY_PARAM_PITCH, speechPitch);
+        params.putInt(TextToSpeech.Engine.KEY_PARAM_RATE, speechRate);
+        if (selectedVoice.getRequiresNetworkConnection()) {
+            params.putString(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS, "true");
+        } else {
+            params.putString(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS, "true");
+        }
+
+        // Build V1 request
+        SynthesisRequest requestV1 = new SynthesisRequest(request.getText(), params);
+        Locale locale = selectedVoice.getLocale();
+        requestV1.setLanguage(locale.getISO3Language(), locale.getISO3Country(),
+                locale.getVariant());
+        requestV1.setSpeechRate(speechRate);
+        requestV1.setPitch(speechPitch);
+
+        // Synthesize using V1 interface
+        onSynthesizeText(requestV1, callback);
+    }
+
+    /**
+     * If true, this service implements proper V2 TTS API service. If it's false,
+     * V2 API will be provided through adapter.
+     */
+    protected boolean implementsV2API() {
+        return false;
+    }
+
+    /**
      * Queries the service for a set of features supported for a given language.
      *
+     * Can be called on multiple threads.
+     *
      * @param lang ISO-3 language code.
      * @param country ISO-3 country code. May be empty or null.
      * @param variant Language variant. May be empty or null.
@@ -215,6 +385,69 @@
         return null;
     }
 
+    private List<VoiceInfo> getVoicesInfo() {
+        synchronized (mVoicesInfoLock) {
+            if (mVoicesInfoList == null) {
+                // Get voices. Defensive copy to make sure TTS engine won't alter the list.
+                mVoicesInfoList = new ArrayList<VoiceInfo>(checkVoicesInfo());
+                // Build lookup map
+                mVoicesInfoLookup = new HashMap<String, VoiceInfo>((int) (
+                        mVoicesInfoList.size()*1.5f));
+                for (VoiceInfo voiceInfo : mVoicesInfoList) {
+                    VoiceInfo prev = mVoicesInfoLookup.put(voiceInfo.getName(), voiceInfo);
+                    if (prev != null) {
+                        Log.e(TAG, "Duplicate name (" + voiceInfo.getName() + ") of the voice ");
+                    }
+                }
+            }
+            return mVoicesInfoList;
+        }
+    }
+
+    public VoiceInfo getVoicesInfoWithName(String name) {
+        synchronized (mVoicesInfoLock) {
+            if (mVoicesInfoLookup != null) {
+                return mVoicesInfoLookup.get(name);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Force TTS service to reevaluate the set of available languages. Will result in
+     * a call to {@link #checkVoicesInfo()} on the same thread, {@link #onVoicesInfoChange}
+     * on the synthesizer thread and callback to
+     * {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange} of all connected
+     * TTS clients.
+     *
+     * Use this method only if you know that set of available languages changed.
+     *
+     * Can be called on multiple threads.
+     */
+    public void forceVoicesInfoCheck() {
+        synchronized (mVoicesInfoLock) {
+            List<VoiceInfo> old = mVoicesInfoList;
+
+            mVoicesInfoList = null; // Force recreation of voices info list
+            getVoicesInfo();
+
+            if (mVoicesInfoList == null) {
+                throw new IllegalStateException("This method applies only to services " +
+                        "supporting V2 TTS API. This services doesn't support V2 TTS API.");
+            }
+
+            if (old != null) {
+                // Flush all existing items, and inform synthesis thread about the change.
+                mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_FLUSH,
+                        new VoicesInfoChangeItem());
+                // TODO: Handle items that may be added to queue after SynthesizerRestartItem
+                // but before client reconnection
+                // Disconnect all of them
+                mCallbacks.dispatchVoicesInfoChange(mVoicesInfoList);
+            }
+        }
+    }
+
     private int getDefaultSpeechRate() {
         return getSecureSettingInt(Settings.Secure.TTS_DEFAULT_RATE, Engine.DEFAULT_RATE);
     }
@@ -317,7 +550,8 @@
 
             if (!speechItem.isValid()) {
                 if (utterenceProgress != null) {
-                    utterenceProgress.dispatchOnError();
+                    utterenceProgress.dispatchOnError(
+                            TextToSpeechClient.Status.ERROR_INVALID_REQUEST);
                 }
                 return TextToSpeech.ERROR;
             }
@@ -342,12 +576,13 @@
             //
             // Note that this string is interned, so the == comparison works.
             msg.obj = speechItem.getCallerIdentity();
+
             if (sendMessage(msg)) {
                 return TextToSpeech.SUCCESS;
             } else {
                 Log.w(TAG, "SynthThread has quit");
                 if (utterenceProgress != null) {
-                    utterenceProgress.dispatchOnError();
+                    utterenceProgress.dispatchOnError(TextToSpeechClient.Status.ERROR_SERVICE);
                 }
                 return TextToSpeech.ERROR;
             }
@@ -399,9 +634,11 @@
     }
 
     interface UtteranceProgressDispatcher {
-        public void dispatchOnDone();
+        public void dispatchOnFallback();
+        public void dispatchOnStop();
+        public void dispatchOnSuccess();
         public void dispatchOnStart();
-        public void dispatchOnError();
+        public void dispatchOnError(int errorCode);
     }
 
     /**
@@ -409,15 +646,13 @@
      */
     private abstract class SpeechItem {
         private final Object mCallerIdentity;
-        protected final Bundle mParams;
         private final int mCallerUid;
         private final int mCallerPid;
         private boolean mStarted = false;
         private boolean mStopped = false;
 
-        public SpeechItem(Object caller, int callerUid, int callerPid, Bundle params) {
+        public SpeechItem(Object caller, int callerUid, int callerPid) {
             mCallerIdentity = caller;
-            mParams = params;
             mCallerUid = callerUid;
             mCallerPid = callerPid;
         }
@@ -446,20 +681,18 @@
          * Must not be called more than once.
          *
          * Only called on the synthesis thread.
-         *
-         * @return {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
          */
-        public int play() {
+        public void play() {
             synchronized (this) {
                 if (mStarted) {
                     throw new IllegalStateException("play() called twice");
                 }
                 mStarted = true;
             }
-            return playImpl();
+            playImpl();
         }
 
-        protected abstract int playImpl();
+        protected abstract void playImpl();
 
         /**
          * Stops the speech item.
@@ -485,20 +718,37 @@
     }
 
     /**
-     * An item in the synth thread queue that process utterance.
+     * An item in the synth thread queue that process utterance (and call back to client about
+     * progress).
      */
     private abstract class UtteranceSpeechItem extends SpeechItem
         implements UtteranceProgressDispatcher  {
 
-        public UtteranceSpeechItem(Object caller, int callerUid, int callerPid, Bundle params) {
-            super(caller, callerUid, callerPid, params);
+        public UtteranceSpeechItem(Object caller, int callerUid, int callerPid) {
+            super(caller, callerUid, callerPid);
         }
 
         @Override
-        public void dispatchOnDone() {
+        public void dispatchOnSuccess() {
             final String utteranceId = getUtteranceId();
             if (utteranceId != null) {
-                mCallbacks.dispatchOnDone(getCallerIdentity(), utteranceId);
+                mCallbacks.dispatchOnSuccess(getCallerIdentity(), utteranceId);
+            }
+        }
+
+        @Override
+        public void dispatchOnStop() {
+            final String utteranceId = getUtteranceId();
+            if (utteranceId != null) {
+                mCallbacks.dispatchOnStop(getCallerIdentity(), utteranceId);
+            }
+        }
+
+        @Override
+        public void dispatchOnFallback() {
+            final String utteranceId = getUtteranceId();
+            if (utteranceId != null) {
+                mCallbacks.dispatchOnFallback(getCallerIdentity(), utteranceId);
             }
         }
 
@@ -511,44 +761,260 @@
         }
 
         @Override
-        public void dispatchOnError() {
+        public void dispatchOnError(int errorCode) {
             final String utteranceId = getUtteranceId();
             if (utteranceId != null) {
-                mCallbacks.dispatchOnError(getCallerIdentity(), utteranceId);
+                mCallbacks.dispatchOnError(getCallerIdentity(), utteranceId, errorCode);
             }
         }
 
-        public int getStreamType() {
-            return getIntParam(Engine.KEY_PARAM_STREAM, Engine.DEFAULT_STREAM);
+        abstract public String getUtteranceId();
+
+        String getStringParam(Bundle params, String key, String defaultValue) {
+            return params == null ? defaultValue : params.getString(key, defaultValue);
         }
 
-        public float getVolume() {
-            return getFloatParam(Engine.KEY_PARAM_VOLUME, Engine.DEFAULT_VOLUME);
+        int getIntParam(Bundle params, String key, int defaultValue) {
+            return params == null ? defaultValue : params.getInt(key, defaultValue);
         }
 
-        public float getPan() {
-            return getFloatParam(Engine.KEY_PARAM_PAN, Engine.DEFAULT_PAN);
+        float getFloatParam(Bundle params, String key, float defaultValue) {
+            return params == null ? defaultValue : params.getFloat(key, defaultValue);
+        }
+    }
+
+    /**
+     * UtteranceSpeechItem for V1 API speech items. V1 API speech items keep
+     * synthesis parameters in a single Bundle passed as parameter. This class
+     * allow subclasses to access them conveniently.
+     */
+    private abstract class SpeechItemV1 extends UtteranceSpeechItem {
+        protected final Bundle mParams;
+
+        SpeechItemV1(Object callerIdentity, int callerUid, int callerPid,
+                Bundle params) {
+            super(callerIdentity, callerUid, callerPid);
+            mParams = params;
+        }
+
+        boolean hasLanguage() {
+            return !TextUtils.isEmpty(getStringParam(mParams, Engine.KEY_PARAM_LANGUAGE, null));
+        }
+
+        int getSpeechRate() {
+            return getIntParam(mParams, Engine.KEY_PARAM_RATE, getDefaultSpeechRate());
+        }
+
+        int getPitch() {
+            return getIntParam(mParams, Engine.KEY_PARAM_PITCH, Engine.DEFAULT_PITCH);
+        }
+
+        @Override
+        public String getUtteranceId() {
+            return getStringParam(mParams, Engine.KEY_PARAM_UTTERANCE_ID, null);
+        }
+
+        int getStreamType() {
+            return getIntParam(mParams, Engine.KEY_PARAM_STREAM, Engine.DEFAULT_STREAM);
+        }
+
+        float getVolume() {
+            return getFloatParam(mParams, Engine.KEY_PARAM_VOLUME, Engine.DEFAULT_VOLUME);
+        }
+
+        float getPan() {
+            return getFloatParam(mParams, Engine.KEY_PARAM_PAN, Engine.DEFAULT_PAN);
+        }
+    }
+
+    class SynthesisSpeechItemV2 extends UtteranceSpeechItem {
+        private final SynthesisRequestV2 mSynthesisRequest;
+        private AbstractSynthesisCallback mSynthesisCallback;
+        private final EventLoggerV2 mEventLogger;
+
+        public SynthesisSpeechItemV2(Object callerIdentity, int callerUid, int callerPid,
+                SynthesisRequestV2 synthesisRequest) {
+            super(callerIdentity, callerUid, callerPid);
+
+            mSynthesisRequest = synthesisRequest;
+            mEventLogger = new EventLoggerV2(synthesisRequest, callerUid, callerPid,
+                    mPackageName);
+
+            updateSpeechSpeedParam(synthesisRequest);
+        }
+
+        private void updateSpeechSpeedParam(SynthesisRequestV2 synthesisRequest) {
+            Bundle voiceParams = mSynthesisRequest.getVoiceParams();
+
+            // Inject default speech speed if needed
+            if (voiceParams.containsKey(TextToSpeechClient.Params.SPEECH_SPEED)) {
+                if (voiceParams.getFloat(TextToSpeechClient.Params.SPEECH_SPEED) <= 0) {
+                    voiceParams.putFloat(TextToSpeechClient.Params.SPEECH_SPEED,
+                            getDefaultSpeechRate() / 100.0f);
+                }
+            }
+        }
+
+        @Override
+        public boolean isValid() {
+            if (mSynthesisRequest.getText() == null) {
+                Log.e(TAG, "null synthesis text");
+                return false;
+            }
+            if (mSynthesisRequest.getText().length() >= TextToSpeech.getMaxSpeechInputLength()) {
+                Log.w(TAG, "Text too long: " + mSynthesisRequest.getText().length() + " chars");
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        protected void playImpl() {
+            AbstractSynthesisCallback synthesisCallback;
+            if (mEventLogger != null) {
+                mEventLogger.onRequestProcessingStart();
+            }
+            synchronized (this) {
+                // stop() might have been called before we enter this
+                // synchronized block.
+                if (isStopped()) {
+                    return;
+                }
+                mSynthesisCallback = createSynthesisCallback();
+                synthesisCallback = mSynthesisCallback;
+            }
+
+            // Get voice info
+            VoiceInfo voiceInfo = getVoicesInfoWithName(mSynthesisRequest.getVoiceName());
+            if (voiceInfo != null) {
+                // Primary voice
+                TextToSpeechService.this.onSynthesizeTextV2(mSynthesisRequest, voiceInfo,
+                        synthesisCallback);
+            } else {
+                Log.e(TAG, "Unknown voice name:" + mSynthesisRequest.getVoiceName());
+                synthesisCallback.error(TextToSpeechClient.Status.ERROR_INVALID_REQUEST);
+            }
+
+            // Fix for case where client called .start() & .error(), but did not called .done()
+            if (!synthesisCallback.hasFinished()) {
+                synthesisCallback.done();
+            }
+        }
+
+        @Override
+        protected void stopImpl() {
+            AbstractSynthesisCallback synthesisCallback;
+            synchronized (this) {
+                synthesisCallback = mSynthesisCallback;
+            }
+            if (synthesisCallback != null) {
+                // If the synthesis callback is null, it implies that we haven't
+                // entered the synchronized(this) block in playImpl which in
+                // turn implies that synthesis would not have started.
+                synthesisCallback.stop();
+                TextToSpeechService.this.onStop();
+            }
+        }
+
+        protected AbstractSynthesisCallback createSynthesisCallback() {
+            return new PlaybackSynthesisCallback(getStreamType(), getVolume(), getPan(),
+                    mAudioPlaybackHandler, this, getCallerIdentity(), mEventLogger,
+                    implementsV2API());
+        }
+
+        private int getStreamType() {
+            return getIntParam(mSynthesisRequest.getAudioParams(),
+                    TextToSpeechClient.Params.AUDIO_PARAM_STREAM,
+                    Engine.DEFAULT_STREAM);
+        }
+
+        private float getVolume() {
+            return getFloatParam(mSynthesisRequest.getAudioParams(),
+                    TextToSpeechClient.Params.AUDIO_PARAM_VOLUME,
+                    Engine.DEFAULT_VOLUME);
+        }
+
+        private float getPan() {
+            return getFloatParam(mSynthesisRequest.getAudioParams(),
+                    TextToSpeechClient.Params.AUDIO_PARAM_PAN,
+                    Engine.DEFAULT_PAN);
+        }
+
+        @Override
+        public String getUtteranceId() {
+            return mSynthesisRequest.getUtteranceId();
+        }
+    }
+
+    private class SynthesisToFileOutputStreamSpeechItemV2 extends SynthesisSpeechItemV2 {
+        private final FileOutputStream mFileOutputStream;
+
+        public SynthesisToFileOutputStreamSpeechItemV2(Object callerIdentity, int callerUid,
+                int callerPid,
+                SynthesisRequestV2 synthesisRequest,
+                FileOutputStream fileOutputStream) {
+            super(callerIdentity, callerUid, callerPid, synthesisRequest);
+            mFileOutputStream = fileOutputStream;
+        }
+
+        @Override
+        protected AbstractSynthesisCallback createSynthesisCallback() {
+            return new FileSynthesisCallback(mFileOutputStream.getChannel(),
+                    this, getCallerIdentity(), implementsV2API());
+        }
+
+        @Override
+        protected void playImpl() {
+            super.playImpl();
+            try {
+              mFileOutputStream.close();
+            } catch(IOException e) {
+              Log.w(TAG, "Failed to close output file", e);
+            }
+        }
+    }
+
+    private class AudioSpeechItemV2 extends UtteranceSpeechItem {
+        private final AudioPlaybackQueueItem mItem;
+        private final Bundle mAudioParams;
+        private final String mUtteranceId;
+
+        public AudioSpeechItemV2(Object callerIdentity, int callerUid, int callerPid,
+                String utteranceId, Bundle audioParams, Uri uri) {
+            super(callerIdentity, callerUid, callerPid);
+            mUtteranceId = utteranceId;
+            mAudioParams = audioParams;
+            mItem = new AudioPlaybackQueueItem(this, getCallerIdentity(),
+                    TextToSpeechService.this, uri, getStreamType());
+        }
+
+        @Override
+        public boolean isValid() {
+            return true;
+        }
+
+        @Override
+        protected void playImpl() {
+            mAudioPlaybackHandler.enqueue(mItem);
+        }
+
+        @Override
+        protected void stopImpl() {
+            // Do nothing.
+        }
+
+        protected int getStreamType() {
+            return mAudioParams.getInt(TextToSpeechClient.Params.AUDIO_PARAM_STREAM);
         }
 
         public String getUtteranceId() {
-            return getStringParam(Engine.KEY_PARAM_UTTERANCE_ID, null);
+            return mUtteranceId;
         }
-
-        protected String getStringParam(String key, String defaultValue) {
-            return mParams == null ? defaultValue : mParams.getString(key, defaultValue);
-        }
-
-        protected int getIntParam(String key, int defaultValue) {
-            return mParams == null ? defaultValue : mParams.getInt(key, defaultValue);
-        }
-
-        protected float getFloatParam(String key, float defaultValue) {
-            return mParams == null ? defaultValue : mParams.getFloat(key, defaultValue);
-        }
-
     }
 
-    class SynthesisSpeechItem extends UtteranceSpeechItem {
+
+    class SynthesisSpeechItemV1 extends SpeechItemV1 {
         // Never null.
         private final String mText;
         private final SynthesisRequest mSynthesisRequest;
@@ -556,10 +1022,10 @@
         // Non null after synthesis has started, and all accesses
         // guarded by 'this'.
         private AbstractSynthesisCallback mSynthesisCallback;
-        private final EventLogger mEventLogger;
+        private final EventLoggerV1 mEventLogger;
         private final int mCallerUid;
 
-        public SynthesisSpeechItem(Object callerIdentity, int callerUid, int callerPid,
+        public SynthesisSpeechItemV1(Object callerIdentity, int callerUid, int callerPid,
                 Bundle params, String text) {
             super(callerIdentity, callerUid, callerPid, params);
             mText = text;
@@ -567,7 +1033,7 @@
             mSynthesisRequest = new SynthesisRequest(mText, mParams);
             mDefaultLocale = getSettingsLocale();
             setRequestParams(mSynthesisRequest);
-            mEventLogger = new EventLogger(mSynthesisRequest, callerUid, callerPid,
+            mEventLogger = new EventLoggerV1(mSynthesisRequest, callerUid, callerPid,
                     mPackageName);
         }
 
@@ -589,25 +1055,30 @@
         }
 
         @Override
-        protected int playImpl() {
+        protected void playImpl() {
             AbstractSynthesisCallback synthesisCallback;
             mEventLogger.onRequestProcessingStart();
             synchronized (this) {
                 // stop() might have been called before we enter this
                 // synchronized block.
                 if (isStopped()) {
-                    return TextToSpeech.ERROR;
+                    return;
                 }
                 mSynthesisCallback = createSynthesisCallback();
                 synthesisCallback = mSynthesisCallback;
             }
+
             TextToSpeechService.this.onSynthesizeText(mSynthesisRequest, synthesisCallback);
-            return synthesisCallback.isDone() ? TextToSpeech.SUCCESS : TextToSpeech.ERROR;
+
+            // Fix for case where client called .start() & .error(), but did not called .done()
+            if (synthesisCallback.hasStarted() && !synthesisCallback.hasFinished()) {
+                synthesisCallback.done();
+            }
         }
 
         protected AbstractSynthesisCallback createSynthesisCallback() {
             return new PlaybackSynthesisCallback(getStreamType(), getVolume(), getPan(),
-                    mAudioPlaybackHandler, this, getCallerIdentity(), mEventLogger);
+                    mAudioPlaybackHandler, this, getCallerIdentity(), mEventLogger, false);
         }
 
         private void setRequestParams(SynthesisRequest request) {
@@ -632,37 +1103,25 @@
             }
         }
 
-        public String getLanguage() {
-            return getStringParam(Engine.KEY_PARAM_LANGUAGE, mDefaultLocale[0]);
-        }
-
-        private boolean hasLanguage() {
-            return !TextUtils.isEmpty(getStringParam(Engine.KEY_PARAM_LANGUAGE, null));
-        }
-
         private String getCountry() {
             if (!hasLanguage()) return mDefaultLocale[1];
-            return getStringParam(Engine.KEY_PARAM_COUNTRY, "");
+            return getStringParam(mParams, Engine.KEY_PARAM_COUNTRY, "");
         }
 
         private String getVariant() {
             if (!hasLanguage()) return mDefaultLocale[2];
-            return getStringParam(Engine.KEY_PARAM_VARIANT, "");
+            return getStringParam(mParams, Engine.KEY_PARAM_VARIANT, "");
         }
 
-        private int getSpeechRate() {
-            return getIntParam(Engine.KEY_PARAM_RATE, getDefaultSpeechRate());
-        }
-
-        private int getPitch() {
-            return getIntParam(Engine.KEY_PARAM_PITCH, Engine.DEFAULT_PITCH);
+        public String getLanguage() {
+            return getStringParam(mParams, Engine.KEY_PARAM_LANGUAGE, mDefaultLocale[0]);
         }
     }
 
-    private class SynthesisToFileOutputStreamSpeechItem extends SynthesisSpeechItem {
+    private class SynthesisToFileOutputStreamSpeechItemV1 extends SynthesisSpeechItemV1 {
         private final FileOutputStream mFileOutputStream;
 
-        public SynthesisToFileOutputStreamSpeechItem(Object callerIdentity, int callerUid,
+        public SynthesisToFileOutputStreamSpeechItemV1(Object callerIdentity, int callerUid,
                 int callerPid, Bundle params, String text, FileOutputStream fileOutputStream) {
             super(callerIdentity, callerUid, callerPid, params, text);
             mFileOutputStream = fileOutputStream;
@@ -670,30 +1129,26 @@
 
         @Override
         protected AbstractSynthesisCallback createSynthesisCallback() {
-            return new FileSynthesisCallback(mFileOutputStream.getChannel());
+            return new FileSynthesisCallback(mFileOutputStream.getChannel(),
+                    this, getCallerIdentity(), false);
         }
 
         @Override
-        protected int playImpl() {
+        protected void playImpl() {
             dispatchOnStart();
-            int status = super.playImpl();
-            if (status == TextToSpeech.SUCCESS) {
-                dispatchOnDone();
-            } else {
-                dispatchOnError();
-            }
+            super.playImpl();
             try {
               mFileOutputStream.close();
             } catch(IOException e) {
               Log.w(TAG, "Failed to close output file", e);
             }
-            return status;
         }
     }
 
-    private class AudioSpeechItem extends UtteranceSpeechItem {
+    private class AudioSpeechItemV1 extends SpeechItemV1 {
         private final AudioPlaybackQueueItem mItem;
-        public AudioSpeechItem(Object callerIdentity, int callerUid, int callerPid,
+
+        public AudioSpeechItemV1(Object callerIdentity, int callerUid, int callerPid,
                 Bundle params, Uri uri) {
             super(callerIdentity, callerUid, callerPid, params);
             mItem = new AudioPlaybackQueueItem(this, getCallerIdentity(),
@@ -706,23 +1161,29 @@
         }
 
         @Override
-        protected int playImpl() {
+        protected void playImpl() {
             mAudioPlaybackHandler.enqueue(mItem);
-            return TextToSpeech.SUCCESS;
         }
 
         @Override
         protected void stopImpl() {
             // Do nothing.
         }
+
+        @Override
+        public String getUtteranceId() {
+            return getStringParam(mParams, Engine.KEY_PARAM_UTTERANCE_ID, null);
+        }
     }
 
     private class SilenceSpeechItem extends UtteranceSpeechItem {
         private final long mDuration;
+        private final String mUtteranceId;
 
         public SilenceSpeechItem(Object callerIdentity, int callerUid, int callerPid,
-                Bundle params, long duration) {
-            super(callerIdentity, callerUid, callerPid, params);
+                String utteranceId, long duration) {
+            super(callerIdentity, callerUid, callerPid);
+            mUtteranceId = utteranceId;
             mDuration = duration;
         }
 
@@ -732,26 +1193,57 @@
         }
 
         @Override
-        protected int playImpl() {
+        protected void playImpl() {
             mAudioPlaybackHandler.enqueue(new SilencePlaybackQueueItem(
                     this, getCallerIdentity(), mDuration));
-            return TextToSpeech.SUCCESS;
         }
 
         @Override
         protected void stopImpl() {
-            // Do nothing, handled by AudioPlaybackHandler#stopForApp
+
+        }
+
+        @Override
+        public String getUtteranceId() {
+            return mUtteranceId;
         }
     }
 
+    /**
+     * Call {@link TextToSpeechService#onVoicesInfoChange} on synthesis thread.
+     */
+    private class VoicesInfoChangeItem extends SpeechItem {
+        public VoicesInfoChangeItem() {
+            super(null, 0, 0); // It's never initiated by an user
+        }
+
+        @Override
+        public boolean isValid() {
+            return true;
+        }
+
+        @Override
+        protected void playImpl() {
+            TextToSpeechService.this.onVoicesInfoChange();
+        }
+
+        @Override
+        protected void stopImpl() {
+            // No-op
+        }
+    }
+
+    /**
+     * Call {@link TextToSpeechService#onLoadLanguage} on synth thread.
+     */
     private class LoadLanguageItem extends SpeechItem {
         private final String mLanguage;
         private final String mCountry;
         private final String mVariant;
 
         public LoadLanguageItem(Object callerIdentity, int callerUid, int callerPid,
-                Bundle params, String language, String country, String variant) {
-            super(callerIdentity, callerUid, callerPid, params);
+                String language, String country, String variant) {
+            super(callerIdentity, callerUid, callerPid);
             mLanguage = language;
             mCountry = country;
             mVariant = variant;
@@ -763,14 +1255,8 @@
         }
 
         @Override
-        protected int playImpl() {
-            int result = TextToSpeechService.this.onLoadLanguage(mLanguage, mCountry, mVariant);
-            if (result == TextToSpeech.LANG_AVAILABLE ||
-                    result == TextToSpeech.LANG_COUNTRY_AVAILABLE ||
-                    result == TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE) {
-                return TextToSpeech.SUCCESS;
-            }
-            return TextToSpeech.ERROR;
+        protected void playImpl() {
+            TextToSpeechService.this.onLoadLanguage(mLanguage, mCountry, mVariant);
         }
 
         @Override
@@ -800,7 +1286,7 @@
                 return TextToSpeech.ERROR;
             }
 
-            SpeechItem item = new SynthesisSpeechItem(caller,
+            SpeechItem item = new SynthesisSpeechItemV1(caller,
                     Binder.getCallingUid(), Binder.getCallingPid(), params, text);
             return mSynthHandler.enqueueSpeechItem(queueMode, item);
         }
@@ -818,7 +1304,7 @@
             final ParcelFileDescriptor sameFileDescriptor = ParcelFileDescriptor.adoptFd(
                     fileDescriptor.detachFd());
 
-            SpeechItem item = new SynthesisToFileOutputStreamSpeechItem(caller,
+            SpeechItem item = new SynthesisToFileOutputStreamSpeechItemV1(caller,
                     Binder.getCallingUid(), Binder.getCallingPid(), params, text,
                     new ParcelFileDescriptor.AutoCloseOutputStream(sameFileDescriptor));
             return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
@@ -830,19 +1316,19 @@
                 return TextToSpeech.ERROR;
             }
 
-            SpeechItem item = new AudioSpeechItem(caller,
+            SpeechItem item = new AudioSpeechItemV1(caller,
                     Binder.getCallingUid(), Binder.getCallingPid(), params, audioUri);
             return mSynthHandler.enqueueSpeechItem(queueMode, item);
         }
 
         @Override
-        public int playSilence(IBinder caller, long duration, int queueMode, Bundle params) {
-            if (!checkNonNull(caller, params)) {
+        public int playSilence(IBinder caller, long duration, int queueMode, String utteranceId) {
+            if (!checkNonNull(caller)) {
                 return TextToSpeech.ERROR;
             }
 
             SpeechItem item = new SilenceSpeechItem(caller,
-                    Binder.getCallingUid(), Binder.getCallingPid(), params, duration);
+                    Binder.getCallingUid(), Binder.getCallingPid(), utteranceId, duration);
             return mSynthHandler.enqueueSpeechItem(queueMode, item);
         }
 
@@ -912,7 +1398,7 @@
                     retVal == TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE) {
 
                 SpeechItem item = new LoadLanguageItem(caller, Binder.getCallingUid(),
-                    Binder.getCallingPid(), null, lang, country, variant);
+                        Binder.getCallingPid(), lang, country, variant);
 
                 if (mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item) !=
                         TextToSpeech.SUCCESS) {
@@ -943,6 +1429,58 @@
             }
             return true;
         }
+
+        @Override
+        public List<VoiceInfo> getVoicesInfo() {
+            return TextToSpeechService.this.getVoicesInfo();
+        }
+
+        @Override
+        public int speakV2(IBinder callingInstance,
+                SynthesisRequestV2 request) {
+            if (!checkNonNull(callingInstance, request)) {
+                return TextToSpeech.ERROR;
+            }
+
+            SpeechItem item = new SynthesisSpeechItemV2(callingInstance,
+                    Binder.getCallingUid(), Binder.getCallingPid(), request);
+            return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
+        }
+
+        @Override
+        public int synthesizeToFileDescriptorV2(IBinder callingInstance,
+                ParcelFileDescriptor fileDescriptor,
+                SynthesisRequestV2 request) {
+            if (!checkNonNull(callingInstance, request, fileDescriptor)) {
+                return TextToSpeech.ERROR;
+            }
+
+            // In test env, ParcelFileDescriptor instance may be EXACTLY the same
+            // one that is used by client. And it will be closed by a client, thus
+            // preventing us from writing anything to it.
+            final ParcelFileDescriptor sameFileDescriptor = ParcelFileDescriptor.adoptFd(
+                    fileDescriptor.detachFd());
+
+            SpeechItem item = new SynthesisToFileOutputStreamSpeechItemV2(callingInstance,
+                    Binder.getCallingUid(), Binder.getCallingPid(), request,
+                    new ParcelFileDescriptor.AutoCloseOutputStream(sameFileDescriptor));
+            return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
+
+        }
+
+        @Override
+        public int playAudioV2(
+                IBinder callingInstance, Uri audioUri, String utteranceId,
+                Bundle systemParameters) {
+            if (!checkNonNull(callingInstance, audioUri, systemParameters)) {
+                return TextToSpeech.ERROR;
+            }
+
+            SpeechItem item = new AudioSpeechItemV2(callingInstance,
+                    Binder.getCallingUid(), Binder.getCallingPid(), utteranceId, systemParameters,
+                    audioUri);
+            return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
+        }
     };
 
     private class CallbackMap extends RemoteCallbackList<ITextToSpeechCallback> {
@@ -964,11 +1502,31 @@
             }
         }
 
-        public void dispatchOnDone(Object callerIdentity, String utteranceId) {
+        public void dispatchOnFallback(Object callerIdentity, String utteranceId) {
             ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
             if (cb == null) return;
             try {
-                cb.onDone(utteranceId);
+                cb.onFallback(utteranceId);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Callback onFallback failed: " + e);
+            }
+        }
+
+        public void dispatchOnStop(Object callerIdentity, String utteranceId) {
+            ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
+            if (cb == null) return;
+            try {
+                cb.onStop(utteranceId);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Callback onStop failed: " + e);
+            }
+        }
+
+        public void dispatchOnSuccess(Object callerIdentity, String utteranceId) {
+            ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
+            if (cb == null) return;
+            try {
+                cb.onSuccess(utteranceId);
             } catch (RemoteException e) {
                 Log.e(TAG, "Callback onDone failed: " + e);
             }
@@ -985,11 +1543,12 @@
 
         }
 
-        public void dispatchOnError(Object callerIdentity, String utteranceId) {
+        public void dispatchOnError(Object callerIdentity, String utteranceId,
+                int errorCode) {
             ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
             if (cb == null) return;
             try {
-                cb.onError(utteranceId);
+                cb.onError(utteranceId, errorCode);
             } catch (RemoteException e) {
                 Log.e(TAG, "Callback onError failed: " + e);
             }
@@ -1001,7 +1560,7 @@
             synchronized (mCallerToCallback) {
                 mCallerToCallback.remove(caller);
             }
-            mSynthHandler.stopForApp(caller);
+            //mSynthHandler.stopForApp(caller);
         }
 
         @Override
@@ -1012,6 +1571,18 @@
             }
         }
 
+        public void dispatchVoicesInfoChange(List<VoiceInfo> voicesInfo) {
+            synchronized (mCallerToCallback) {
+                for (ITextToSpeechCallback callback : mCallerToCallback.values()) {
+                    try {
+                        callback.onVoicesInfoChange(voicesInfo);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Failed to request reconnect", e);
+                    }
+                }
+            }
+        }
+
         private ITextToSpeechCallback getCallbackFor(Object caller) {
             ITextToSpeechCallback cb;
             IBinder asBinder = (IBinder) caller;
@@ -1021,7 +1592,5 @@
 
             return cb;
         }
-
     }
-
 }
diff --git a/core/java/android/speech/tts/VoiceInfo.aidl b/core/java/android/speech/tts/VoiceInfo.aidl
new file mode 100644
index 0000000..4005f8b
--- /dev/null
+++ b/core/java/android/speech/tts/VoiceInfo.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** 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.speech.tts;
+
+parcelable VoiceInfo;
\ No newline at end of file
diff --git a/core/java/android/speech/tts/VoiceInfo.java b/core/java/android/speech/tts/VoiceInfo.java
new file mode 100644
index 0000000..16b9a97
--- /dev/null
+++ b/core/java/android/speech/tts/VoiceInfo.java
@@ -0,0 +1,325 @@
+package android.speech.tts;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Locale;
+
+/**
+ * Characteristics and features of a Text-To-Speech Voice. Each TTS Engine can expose
+ * multiple voices for multiple locales, with different set of features.
+ *
+ * Each VoiceInfo has an unique name. This name can be obtained using the {@link #getName()} method
+ * and will persist until the client is asked to re-evaluate the list of available voices in the
+ * {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange(android.speech.tts.TextToSpeechClient.EngineStatus)}
+ * callback. The name can be used to reference a VoiceInfo in an instance of {@link RequestConfig};
+ * the {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter is an example of this.
+ * It is recommended that the voice name never change during the TTS service lifetime.
+ */
+public final class VoiceInfo implements Parcelable {
+    /** Very low, but still intelligible quality of speech synthesis */
+    public static final int QUALITY_VERY_LOW = 100;
+
+    /** Low, not human-like quality of speech synthesis */
+    public static final int QUALITY_LOW = 200;
+
+    /** Normal quality of speech synthesis */
+    public static final int QUALITY_NORMAL = 300;
+
+    /** High, human-like quality of speech synthesis */
+    public static final int QUALITY_HIGH = 400;
+
+    /** Very high, almost human-indistinguishable quality of speech synthesis */
+    public static final int QUALITY_VERY_HIGH = 500;
+
+    /** Very low expected synthesizer latency (< 20ms) */
+    public static final int LATENCY_VERY_LOW = 100;
+
+    /** Low expected synthesizer latency (~20ms) */
+    public static final int LATENCY_LOW = 200;
+
+    /** Normal expected synthesizer latency (~50ms) */
+    public static final int LATENCY_NORMAL = 300;
+
+    /** Network based expected synthesizer latency (~200ms) */
+    public static final int LATENCY_HIGH = 400;
+
+    /** Very slow network based expected synthesizer latency (> 200ms) */
+    public static final int LATENCY_VERY_HIGH = 500;
+
+    /** Additional feature key, with string value, gender of the speaker */
+    public static final String FEATURE_SPEAKER_GENDER = "speakerGender";
+
+    /** Additional feature key, with integer value, speaking speed in words per minute
+     * when {@link TextToSpeechClient.Params#SPEECH_SPEED} parameter is set to {@code 1.0} */
+    public static final String FEATURE_WORDS_PER_MINUTE = "wordsPerMinute";
+
+    /**
+     * Additional feature key, with boolean value, that indicates that voice may need to
+     * download additional data if used for synthesis.
+     *
+     * Making a request with a voice that has this feature may result in a
+     * {@link TextToSpeechClient.Status#ERROR_DOWNLOADING_ADDITIONAL_DATA} error. It's recommended
+     * to set the {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter to reference
+     * a fully installed voice (or network voice) that can serve as replacement.
+     *
+     * Note: It's a good practice for a TTS engine to provide a sensible fallback voice as the
+     * default value for {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} parameter if this
+     * feature is present.
+     */
+    public static final String FEATURE_MAY_AUTOINSTALL = "mayAutoInstall";
+
+    private final String mName;
+    private final Locale mLocale;
+    private final int mQuality;
+    private final int mLatency;
+    private final boolean mRequiresNetworkConnection;
+    private final Bundle mParams;
+    private final Bundle mAdditionalFeatures;
+
+    private VoiceInfo(Parcel in) {
+        this.mName = in.readString();
+        String[] localesData = new String[3];
+        in.readStringArray(localesData);
+        this.mLocale = new Locale(localesData[0], localesData[1], localesData[2]);
+
+        this.mQuality = in.readInt();
+        this.mLatency = in.readInt();
+        this.mRequiresNetworkConnection = (in.readByte() == 1);
+
+        this.mParams = in.readBundle();
+        this.mAdditionalFeatures = in.readBundle();
+    }
+
+    private VoiceInfo(String name,
+            Locale locale,
+            int quality,
+            int latency,
+            boolean requiresNetworkConnection,
+            Bundle params,
+            Bundle additionalFeatures) {
+        this.mName = name;
+        this.mLocale = locale;
+        this.mQuality = quality;
+        this.mLatency = latency;
+        this.mRequiresNetworkConnection = requiresNetworkConnection;
+        this.mParams = params;
+        this.mAdditionalFeatures = additionalFeatures;
+    }
+
+    /** Builder, allows TTS engines to create VoiceInfo instances. */
+    public static final class Builder {
+        private String name;
+        private Locale locale;
+        private int quality = VoiceInfo.QUALITY_NORMAL;
+        private int latency = VoiceInfo.LATENCY_NORMAL;
+        private boolean requiresNetworkConnection;
+        private Bundle params;
+        private Bundle additionalFeatures;
+
+        public Builder() {
+
+        }
+
+        /**
+         * Copy fields from given VoiceInfo instance.
+         */
+        public Builder(VoiceInfo voiceInfo) {
+            this.name = voiceInfo.mName;
+            this.locale = voiceInfo.mLocale;
+            this.quality = voiceInfo.mQuality;
+            this.latency = voiceInfo.mLatency;
+            this.requiresNetworkConnection = voiceInfo.mRequiresNetworkConnection;
+            this.params = (Bundle)voiceInfo.mParams.clone();
+            this.additionalFeatures = (Bundle) voiceInfo.mAdditionalFeatures.clone();
+        }
+
+        /**
+         * Sets the voice's unique name. It will be used by clients to reference the voice used by a
+         * request.
+         *
+         * It's recommended that each voice use the same consistent name during the TTS service
+         * lifetime.
+         */
+        public Builder setName(String name) {
+            this.name = name;
+            return this;
+        }
+
+        /**
+         * Sets voice locale. This has to be a valid locale, built from ISO 639-1 and ISO 3166-1
+         * two letter codes.
+         */
+        public Builder setLocale(Locale locale) {
+            this.locale = locale;
+            return this;
+        }
+
+        /**
+         * Sets map of all available request parameters with their default values.
+         * Some common parameter names can be found in {@link TextToSpeechClient.Params} static
+         * members.
+         */
+        public Builder setParamsWithDefaults(Bundle params) {
+            this.params = params;
+            return this;
+        }
+
+        /**
+         * Sets map of additional voice features. Some common feature names can be found in
+         * {@link VoiceInfo} static members.
+         */
+        public Builder setAdditionalFeatures(Bundle additionalFeatures) {
+            this.additionalFeatures = additionalFeatures;
+            return this;
+        }
+
+        /**
+         * Sets the voice quality (higher is better).
+         */
+        public Builder setQuality(int quality) {
+            this.quality = quality;
+            return this;
+        }
+
+        /**
+         * Sets the voice latency (lower is better).
+         */
+        public Builder setLatency(int latency) {
+            this.latency = latency;
+            return this;
+        }
+
+        /**
+         * Sets whether the voice requires network connection to work properly.
+         */
+        public Builder setRequiresNetworkConnection(boolean requiresNetworkConnection) {
+            this.requiresNetworkConnection = requiresNetworkConnection;
+            return this;
+        }
+
+        /**
+         * @return The built VoiceInfo instance.
+         */
+        public VoiceInfo build() {
+            if (name == null || name.isEmpty()) {
+                throw new IllegalStateException("Name can't be null or empty");
+            }
+            if (locale == null) {
+                throw new IllegalStateException("Locale can't be null");
+            }
+
+            return new VoiceInfo(name, locale, quality, latency,
+                        requiresNetworkConnection,
+                        ((params == null) ? new Bundle() :
+                            (Bundle)params.clone()),
+                        ((additionalFeatures == null) ? new Bundle() :
+                            (Bundle)additionalFeatures.clone()));
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mName);
+        String[] localesData = new String[]{mLocale.getLanguage(), mLocale.getCountry(), mLocale.getVariant()};
+        dest.writeStringArray(localesData);
+        dest.writeInt(mQuality);
+        dest.writeInt(mLatency);
+        dest.writeByte((byte) (mRequiresNetworkConnection ? 1 : 0));
+        dest.writeBundle(mParams);
+        dest.writeBundle(mAdditionalFeatures);
+    }
+
+    /**
+     * @hide
+     */
+    public static final Parcelable.Creator<VoiceInfo> CREATOR = new Parcelable.Creator<VoiceInfo>() {
+        @Override
+        public VoiceInfo createFromParcel(Parcel in) {
+            return new VoiceInfo(in);
+        }
+
+        @Override
+        public VoiceInfo[] newArray(int size) {
+            return new VoiceInfo[size];
+        }
+    };
+
+    /**
+     * @return The voice's locale
+     */
+    public Locale getLocale() {
+        return mLocale;
+    }
+
+    /**
+     * @return The voice's quality (higher is better)
+     */
+    public int getQuality() {
+        return mQuality;
+    }
+
+    /**
+     * @return The voice's latency (lower is better)
+     */
+    public int getLatency() {
+        return mLatency;
+    }
+
+    /**
+     * @return Does the Voice require a network connection to work.
+     */
+    public boolean getRequiresNetworkConnection() {
+        return mRequiresNetworkConnection;
+    }
+
+    /**
+     * @return Bundle of all available parameters with their default values.
+     */
+    public Bundle getParamsWithDefaults() {
+        return mParams;
+    }
+
+    /**
+     * @return Unique voice name.
+     *
+     * Each VoiceInfo has an unique name, that persists until client is asked to re-evaluate the
+     * set of the available languages in the {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange(android.speech.tts.TextToSpeechClient.EngineStatus)}
+     * callback (Voice may disappear from the set if voice was removed by the user).
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * @return Additional features of the voice.
+     */
+    public Bundle getAdditionalFeatures() {
+        return mAdditionalFeatures;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder(64);
+        return builder.append("VoiceInfo[Name: ").append(mName)
+                .append(" ,locale: ").append(mLocale)
+                .append(" ,quality: ").append(mQuality)
+                .append(" ,latency: ").append(mLatency)
+                .append(" ,requiresNetwork: ").append(mRequiresNetworkConnection)
+                .append(" ,paramsWithDefaults: ").append(mParams.toString())
+                .append(" ,additionalFeatures: ").append(mAdditionalFeatures.toString())
+                .append("]").toString();
+    }
+}
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index f839d52..c80321c 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -48,11 +48,8 @@
 import android.text.style.URLSpan;
 import android.text.style.UnderlineSpan;
 
-import com.android.internal.util.XmlUtils;
-
 import java.io.IOException;
 import java.io.StringReader;
-import java.util.HashMap;
 
 /**
  * This class processes HTML strings into displayable styled text.
diff --git a/core/java/android/text/MeasuredText.java b/core/java/android/text/MeasuredText.java
index bd9310c1..101d6a2 100644
--- a/core/java/android/text/MeasuredText.java
+++ b/core/java/android/text/MeasuredText.java
@@ -46,7 +46,7 @@
     }
 
     private static final Object[] sLock = new Object[0];
-    private static MeasuredText[] sCached = new MeasuredText[3];
+    private static final MeasuredText[] sCached = new MeasuredText[3];
 
     static MeasuredText obtain() {
         MeasuredText mt;
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index 22675b4..d0ed871 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -28,7 +28,6 @@
 import java.util.Formatter;
 import java.util.GregorianCalendar;
 import java.util.Locale;
-import java.util.TimeZone;
 
 import libcore.icu.DateIntervalFormat;
 import libcore.icu.LocaleData;
diff --git a/core/java/android/text/method/HideReturnsTransformationMethod.java b/core/java/android/text/method/HideReturnsTransformationMethod.java
index ce18692..c6a90ca 100644
--- a/core/java/android/text/method/HideReturnsTransformationMethod.java
+++ b/core/java/android/text/method/HideReturnsTransformationMethod.java
@@ -16,13 +16,6 @@
 
 package android.text.method;
 
-import android.graphics.Rect;
-import android.text.GetChars;
-import android.text.Spanned;
-import android.text.SpannedString;
-import android.text.TextUtils;
-import android.view.View; 
-
 /**
  * This transformation method causes any carriage return characters (\r)
  * to be hidden by displaying them as zero-width non-breaking space
diff --git a/core/java/android/text/method/PasswordTransformationMethod.java b/core/java/android/text/method/PasswordTransformationMethod.java
index b769b76..88a69b9 100644
--- a/core/java/android/text/method/PasswordTransformationMethod.java
+++ b/core/java/android/text/method/PasswordTransformationMethod.java
@@ -25,7 +25,6 @@
 import android.text.NoCopySpan;
 import android.text.TextUtils;
 import android.text.TextWatcher;
-import android.text.Selection;
 import android.text.Spanned;
 import android.text.Spannable;
 import android.text.style.UpdateLayout;
diff --git a/core/java/android/text/method/SingleLineTransformationMethod.java b/core/java/android/text/method/SingleLineTransformationMethod.java
index 6a05fe4..818526a 100644
--- a/core/java/android/text/method/SingleLineTransformationMethod.java
+++ b/core/java/android/text/method/SingleLineTransformationMethod.java
@@ -16,15 +16,6 @@
 
 package android.text.method;
 
-import android.graphics.Rect;
-import android.text.Editable;
-import android.text.GetChars;
-import android.text.Spannable;
-import android.text.Spanned;
-import android.text.SpannedString;
-import android.text.TextUtils;
-import android.view.View;
-
 /**
  * This transformation method causes any newline characters (\n) to be
  * displayed as spaces instead of causing line breaks, and causes
diff --git a/core/java/android/text/style/DrawableMarginSpan.java b/core/java/android/text/style/DrawableMarginSpan.java
index c2564d5..20b6886 100644
--- a/core/java/android/text/style/DrawableMarginSpan.java
+++ b/core/java/android/text/style/DrawableMarginSpan.java
@@ -19,7 +19,6 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.Paint;
 import android.graphics.Canvas;
-import android.graphics.RectF;
 import android.text.Spanned;
 import android.text.Layout;
 
diff --git a/core/java/android/text/style/DynamicDrawableSpan.java b/core/java/android/text/style/DynamicDrawableSpan.java
index 89dc45b..5b8a6dd 100644
--- a/core/java/android/text/style/DynamicDrawableSpan.java
+++ b/core/java/android/text/style/DynamicDrawableSpan.java
@@ -17,12 +17,9 @@
 package android.text.style;
 
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
-import android.graphics.Paint.Style;
 import android.graphics.drawable.Drawable;
-import android.util.Log;
 
 import java.lang.ref.WeakReference;
 
diff --git a/core/java/android/text/style/IconMarginSpan.java b/core/java/android/text/style/IconMarginSpan.java
index c786a17..cf9a705 100644
--- a/core/java/android/text/style/IconMarginSpan.java
+++ b/core/java/android/text/style/IconMarginSpan.java
@@ -19,7 +19,6 @@
 import android.graphics.Paint;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
-import android.graphics.RectF;
 import android.text.Spanned;
 import android.text.Layout;
 
diff --git a/core/java/android/text/style/LineHeightSpan.java b/core/java/android/text/style/LineHeightSpan.java
index 44a1706..1ebee82 100644
--- a/core/java/android/text/style/LineHeightSpan.java
+++ b/core/java/android/text/style/LineHeightSpan.java
@@ -17,8 +17,6 @@
 package android.text.style;
 
 import android.graphics.Paint;
-import android.graphics.Canvas;
-import android.text.Layout;
 import android.text.TextPaint;
 
 public interface LineHeightSpan
diff --git a/core/java/android/text/style/MetricAffectingSpan.java b/core/java/android/text/style/MetricAffectingSpan.java
index 92558eb..a02b276 100644
--- a/core/java/android/text/style/MetricAffectingSpan.java
+++ b/core/java/android/text/style/MetricAffectingSpan.java
@@ -16,7 +16,6 @@
 
 package android.text.style;
 
-import android.graphics.Paint;
 import android.text.TextPaint;
 
 /**
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index 0ec7e84..8b40953 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -166,25 +166,25 @@
             return;
         }
 
-        int defStyle = com.android.internal.R.attr.textAppearanceMisspelledSuggestion;
+        int defStyleAttr = com.android.internal.R.attr.textAppearanceMisspelledSuggestion;
         TypedArray typedArray = context.obtainStyledAttributes(
-                null, com.android.internal.R.styleable.SuggestionSpan, defStyle, 0);
+                null, com.android.internal.R.styleable.SuggestionSpan, defStyleAttr, 0);
         mMisspelledUnderlineThickness = typedArray.getDimension(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
         mMisspelledUnderlineColor = typedArray.getColor(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
 
-        defStyle = com.android.internal.R.attr.textAppearanceEasyCorrectSuggestion;
+        defStyleAttr = com.android.internal.R.attr.textAppearanceEasyCorrectSuggestion;
         typedArray = context.obtainStyledAttributes(
-                null, com.android.internal.R.styleable.SuggestionSpan, defStyle, 0);
+                null, com.android.internal.R.styleable.SuggestionSpan, defStyleAttr, 0);
         mEasyCorrectUnderlineThickness = typedArray.getDimension(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
         mEasyCorrectUnderlineColor = typedArray.getColor(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
 
-        defStyle = com.android.internal.R.attr.textAppearanceAutoCorrectionSuggestion;
+        defStyleAttr = com.android.internal.R.attr.textAppearanceAutoCorrectionSuggestion;
         typedArray = context.obtainStyledAttributes(
-                null, com.android.internal.R.styleable.SuggestionSpan, defStyle, 0);
+                null, com.android.internal.R.styleable.SuggestionSpan, defStyleAttr, 0);
         mAutoCorrectionUnderlineThickness = typedArray.getDimension(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
         mAutoCorrectionUnderlineColor = typedArray.getColor(
diff --git a/core/java/android/transition/Recolor.java b/core/java/android/transition/Recolor.java
index 70111d1..1638f67 100644
--- a/core/java/android/transition/Recolor.java
+++ b/core/java/android/transition/Recolor.java
@@ -17,7 +17,6 @@
 package android.transition;
 
 import android.animation.Animator;
-import android.animation.ArgbEvaluator;
 import android.animation.ObjectAnimator;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
@@ -75,8 +74,8 @@
             if (startColor.getColor() != endColor.getColor()) {
                 endColor.setColor(startColor.getColor());
                 changed = true;
-                return ObjectAnimator.ofObject(endBackground, "color",
-                        new ArgbEvaluator(), startColor.getColor(), endColor.getColor());
+                return ObjectAnimator.ofArgb(endBackground, "color", startColor.getColor(),
+                        endColor.getColor());
             }
         }
         if (view instanceof TextView) {
@@ -86,8 +85,7 @@
             if (start != end) {
                 textView.setTextColor(end);
                 changed = true;
-                return ObjectAnimator.ofObject(textView, "textColor",
-                        new ArgbEvaluator(), start, end);
+                return ObjectAnimator.ofArgb(textView, "textColor", start, end);
             }
         }
         return null;
diff --git a/core/java/android/transition/Scene.java b/core/java/android/transition/Scene.java
index e1f1896..4267a65 100644
--- a/core/java/android/transition/Scene.java
+++ b/core/java/android/transition/Scene.java
@@ -34,7 +34,7 @@
     private Context mContext;
     private int mLayoutId = -1;
     private ViewGroup mSceneRoot;
-    private ViewGroup mLayout; // alternative to layoutId
+    private View mLayout; // alternative to layoutId
     Runnable mEnterAction, mExitAction;
 
     /**
@@ -114,6 +114,15 @@
      * @param layout The view hierarchy of this scene, added as a child
      * of sceneRoot when this scene is entered.
      */
+    public Scene(ViewGroup sceneRoot, View layout) {
+        mSceneRoot = sceneRoot;
+        mLayout = layout;
+    }
+
+    /**
+     * @deprecated use {@link #Scene(ViewGroup, View)}.
+     */
+    @Deprecated
     public Scene(ViewGroup sceneRoot, ViewGroup layout) {
         mSceneRoot = sceneRoot;
         mLayout = layout;
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index 9f77d5e..9fa554c 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -20,6 +20,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
+import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Xml;
 import android.view.InflateException;
@@ -291,19 +292,40 @@
         int toId = a.getResourceId(
                 com.android.internal.R.styleable.TransitionManager_toScene, -1);
         if (toId >= 0) toScene = Scene.getSceneForLayout(sceneRoot, toId, mContext);
+        String fromName = a.getString(
+                com.android.internal.R.styleable.TransitionManager_fromSceneName);
+        String toName = a.getString(
+                com.android.internal.R.styleable.TransitionManager_toSceneName);
         if (transitionId >= 0) {
             Transition transition = inflateTransition(transitionId);
             if (transition != null) {
                 if (fromScene != null) {
-                    if (toScene == null){
-                        throw new RuntimeException("No matching toScene for given fromScene " +
-                                "for transition ID " + transitionId);
-                    } else {
+                    boolean hasDest = false;
+                    if (toScene != null) {
                         transitionManager.setTransition(fromScene, toScene, transition);
+                        hasDest = true;
+                    }
+
+                    if (!TextUtils.isEmpty(toName)) {
+                        transitionManager.setTransition(fromScene, toName, transition);
+                        hasDest = true;
+                    }
+
+                    if (!hasDest) {
+                        throw new RuntimeException("No matching toScene or toSceneName for given " +
+                                "fromScene for transition ID " + transitionId);
                     }
                 } else if (toId >= 0) {
                     transitionManager.setTransition(toScene, transition);
                 }
+                if (fromName != null) {
+                    if (toScene != null) {
+                        transitionManager.setTransition(fromName, toScene, transition);
+                    } else {
+                        throw new RuntimeException("No matching toScene for given fromSceneName " +
+                                "for transition ID " + transitionId);
+                    }
+                }
             }
         }
         a.recycle();
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 3bf6790..0106f7fb 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -67,9 +67,15 @@
 
     private static Transition sDefaultTransition = new AutoTransition();
 
+    private static final String[] EMPTY_STRINGS = new String[0];
+
     ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
     ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
             new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
+    ArrayMap<Scene, ArrayMap<String, Transition>> mSceneNameTransitions =
+            new ArrayMap<Scene, ArrayMap<String, Transition>>();
+    ArrayMap<String, ArrayMap<Scene, Transition>> mNameSceneTransitions =
+            new ArrayMap<String, ArrayMap<Scene, Transition>>();
     private static ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>
             sRunningTransitions =
             new ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>();
@@ -218,6 +224,141 @@
     }
 
     /**
+     * Retrieve the transition from a named scene to a target defined scene if one has been
+     * associated with this TransitionManager.
+     *
+     * <p>A named scene is an indirect link for a transition. Fundamentally a named
+     * scene represents a potentially arbitrary intersection point of two otherwise independent
+     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
+     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
+     * In this way applications may define an API for more sophisticated transitions between
+     * caller and called activities very similar to the way that <code>Intent</code> extras
+     * define APIs for arguments and data propagation between activities.</p>
+     *
+     * @param fromName Named scene that this transition corresponds to
+     * @param toScene Target scene that this transition will move to
+     * @return Transition corresponding to the given fromName and toScene or null
+     *         if no association exists in this TransitionManager
+     *
+     * @see #setTransition(String, Scene, Transition)
+     */
+    public Transition getNamedTransition(String fromName, Scene toScene) {
+        ArrayMap<Scene, Transition> m = mNameSceneTransitions.get(fromName);
+        if (m != null) {
+            return m.get(toScene);
+        }
+        return null;
+    }
+
+    /**
+     * Retrieve the transition from a defined scene to a target named scene if one has been
+     * associated with this TransitionManager.
+     *
+     * <p>A named scene is an indirect link for a transition. Fundamentally a named
+     * scene represents a potentially arbitrary intersection point of two otherwise independent
+     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
+     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
+     * In this way applications may define an API for more sophisticated transitions between
+     * caller and called activities very similar to the way that <code>Intent</code> extras
+     * define APIs for arguments and data propagation between activities.</p>
+     *
+     * @param fromScene Scene that this transition starts from
+     * @param toName Name of the target scene
+     * @return Transition corresponding to the given fromScene and toName or null
+     *         if no association exists in this TransitionManager
+     */
+    public Transition getNamedTransition(Scene fromScene, String toName) {
+        ArrayMap<String, Transition> m = mSceneNameTransitions.get(fromScene);
+        if (m != null) {
+            return m.get(toName);
+        }
+        return null;
+    }
+
+    /**
+     * Retrieve the supported target named scenes when transitioning away from the given scene.
+     *
+     * <p>A named scene is an indirect link for a transition. Fundamentally a named
+     * scene represents a potentially arbitrary intersection point of two otherwise independent
+     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
+     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
+     * In this way applications may define an API for more sophisticated transitions between
+     * caller and called activities very similar to the way that <code>Intent</code> extras
+     * define APIs for arguments and data propagation between activities.</p>
+     *
+     * @param fromScene Scene to transition from
+     * @return An array of Strings naming each supported transition starting from
+     *         <code>fromScene</code>. If no transitions to a named scene from the given
+     *         scene are supported this function will return a String[] of length 0.
+     *
+     * @see #setTransition(Scene, String, Transition)
+     */
+    public String[] getTargetSceneNames(Scene fromScene) {
+        final ArrayMap<String, Transition> m = mSceneNameTransitions.get(fromScene);
+        if (m == null) {
+            return EMPTY_STRINGS;
+        }
+        final int count = m.size();
+        final String[] result = new String[count];
+        for (int i = 0; i < count; i++) {
+            result[i] = m.keyAt(i);
+        }
+        return result;
+    }
+
+    /**
+     * Set a transition from a specific scene to a named scene.
+     *
+     * <p>A named scene is an indirect link for a transition. Fundamentally a named
+     * scene represents a potentially arbitrary intersection point of two otherwise independent
+     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
+     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
+     * In this way applications may define an API for more sophisticated transitions between
+     * caller and called activities very similar to the way that <code>Intent</code> extras
+     * define APIs for arguments and data propagation between activities.</p>
+     *
+     * @param fromScene Scene to transition from
+     * @param toName Named scene to transition to
+     * @param transition Transition to use
+     *
+     * @see #getTargetSceneNames(Scene)
+     */
+    public void setTransition(Scene fromScene, String toName, Transition transition) {
+        ArrayMap<String, Transition> m = mSceneNameTransitions.get(fromScene);
+        if (m == null) {
+            m = new ArrayMap<String, Transition>();
+            mSceneNameTransitions.put(fromScene, m);
+        }
+        m.put(toName, transition);
+    }
+
+    /**
+     * Set a transition from a named scene to a concrete scene.
+     *
+     * <p>A named scene is an indirect link for a transition. Fundamentally a named
+     * scene represents a potentially arbitrary intersection point of two otherwise independent
+     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
+     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
+     * In this way applications may define an API for more sophisticated transitions between
+     * caller and called activities very similar to the way that <code>Intent</code> extras
+     * define APIs for arguments and data propagation between activities.</p>
+     *
+     * @param fromName Named scene to transition from
+     * @param toScene Scene to transition to
+     * @param transition Transition to use
+     *
+     * @see #getNamedTransition(String, Scene)
+     */
+    public void setTransition(String fromName, Scene toScene, Transition transition) {
+        ArrayMap<Scene, Transition> m = mNameSceneTransitions.get(fromName);
+        if (m == null) {
+            m = new ArrayMap<Scene, Transition>();
+            mNameSceneTransitions.put(fromName, m);
+        }
+        m.put(toScene, transition);
+    }
+
+    /**
      * This private utility class is used to listen for both OnPreDraw and
      * OnAttachStateChange events. OnPreDraw events are the main ones we care
      * about since that's what triggers the transition to take place.
@@ -329,7 +470,6 @@
         // Auto transition if there is no transition declared for the Scene, but there is
         // a root or parent view
         changeScene(scene, getTransition(scene));
-
     }
 
     /**
diff --git a/core/java/android/util/CharsetUtils.java b/core/java/android/util/CharsetUtils.java
deleted file mode 100644
index a763a69..0000000
--- a/core/java/android/util/CharsetUtils.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import android.os.Build;
-import android.text.TextUtils;
-
-import java.nio.charset.Charset;
-import java.nio.charset.IllegalCharsetNameException;
-import java.nio.charset.UnsupportedCharsetException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * <p>
- * A class containing utility methods related to character sets. This
- * class is primarily useful for code that wishes to be vendor-aware
- * in its interpretation of Japanese charset names (used in DoCoMo,
- * KDDI, and SoftBank).
- * </p>
- *
- * <p>
- * <b>Note:</b> Developers will need to add an appropriate mapping for
- * each vendor-specific charset. You may need to modify the C libraries
- * like icu4c in order to let Android support an additional charset.
- * </p>
- *
- * @hide
- */
-public final class CharsetUtils {
-    /**
-     * name of the vendor "DoCoMo". <b>Note:</b> This isn't a public
-     * constant, in order to keep this class from becoming a de facto
-     * reference list of vendor names.
-     */
-    private static final String VENDOR_DOCOMO = "docomo";
-    /**
-     * Name of the vendor "KDDI".
-     */
-    private static final String VENDOR_KDDI = "kddi";
-    /**
-     * Name of the vendor "SoftBank".
-     */
-    private static final String VENDOR_SOFTBANK = "softbank";
-
-    /**
-     * Represents one-to-one mapping from a vendor name to a charset specific to the vendor.
-     */
-    private static final Map<String, String> sVendorShiftJisMap = new HashMap<String, String>();
-
-    static {
-        // These variants of Shift_JIS come from icu's mapping data (convrtrs.txt)
-        sVendorShiftJisMap.put(VENDOR_DOCOMO, "docomo-shift_jis-2007");
-        sVendorShiftJisMap.put(VENDOR_KDDI, "kddi-shift_jis-2007");
-        sVendorShiftJisMap.put(VENDOR_SOFTBANK, "softbank-shift_jis-2007");
-    }
-
-    /**
-     * This class is uninstantiable.
-     */
-    private CharsetUtils() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Returns the name of the vendor-specific character set
-     * corresponding to the given original character set name and
-     * vendor. If there is no vendor-specific character set for the
-     * given name/vendor pair, this returns the original character set name.
-     *
-     * @param charsetName the base character set name
-     * @param vendor the vendor to specialize for. All characters should be lower-cased.
-     * @return the specialized character set name, or {@code charsetName} if
-     * there is no specialized name
-     */
-    public static String nameForVendor(String charsetName, String vendor) {
-        if (!TextUtils.isEmpty(charsetName) && !TextUtils.isEmpty(vendor)) {
-            // You can add your own mapping here.
-            if (isShiftJis(charsetName)) {
-                final String vendorShiftJis = sVendorShiftJisMap.get(vendor);
-                if (vendorShiftJis != null) {
-                    return vendorShiftJis;
-                }
-            }
-        }
-
-        return charsetName;
-    }
-
-    /**
-     * Returns the name of the vendor-specific character set
-     * corresponding to the given original character set name and the
-     * default vendor (that is, the targeted vendor of the device this
-     * code is running on). This method merely calls through to
-     * {@link #nameForVendor(String,String)}, passing the default vendor
-     * as the second argument.
-     * 
-     * @param charsetName the base character set name
-     * @return the specialized character set name, or {@code charsetName} if
-     * there is no specialized name
-     */
-    public static String nameForDefaultVendor(String charsetName) {
-        return nameForVendor(charsetName, getDefaultVendor());
-    }
-
-    /**
-     * Returns the vendor-specific character set corresponding to the
-     * given original character set name and vendor. If there is no
-     * vendor-specific character set for the given name/vendor pair,
-     * this returns the character set corresponding to the original
-     * name. The vendor name is matched case-insensitively. This
-     * method merely calls {@code Charset.forName()} on a name
-     * transformed by a call to {@link #nameForVendor(String,String)}.
-     * 
-     * @param charsetName the base character set name
-     * @param vendor the vendor to specialize for
-     * @return the specialized character set, or the one corresponding
-     * directly to {@code charsetName} if there is no specialized
-     * variant
-     * @throws UnsupportedCharsetException thrown if the named character
-     * set is not supported by the system
-     * @throws IllegalCharsetNameException thrown if {@code charsetName}
-     * has invalid syntax
-     */
-    public static Charset charsetForVendor(String charsetName, String vendor)
-            throws UnsupportedCharsetException, IllegalCharsetNameException {
-        charsetName = nameForVendor(charsetName, vendor);
-        return Charset.forName(charsetName);
-    }
-    
-    /**
-     * Returns the vendor-specific character set corresponding to the
-     * given original character set name and default vendor (that is,
-     * the targeted vendor of the device this code is running on). 
-     * This method merely calls through to {@link
-     * #charsetForVendor(String,String)}, passing the default vendor
-     * as the second argument.
-     * 
-     * @param charsetName the base character set name
-     * @return the specialized character set, or the one corresponding
-     * directly to {@code charsetName} if there is no specialized
-     * variant
-     * @throws UnsupportedCharsetException thrown if the named character
-     * set is not supported by the system
-     * @throws IllegalCharsetNameException thrown if {@code charsetName}
-     * has invalid syntax
-     */
-    public static Charset charsetForVendor(String charsetName)
-            throws UnsupportedCharsetException, IllegalCharsetNameException {
-        return charsetForVendor(charsetName, getDefaultVendor());
-    }
-
-    /**
-     * Returns whether the given character set name indicates the Shift-JIS
-     * encoding. Returns false if the name is null.
-     * 
-     * @param charsetName the character set name
-     * @return {@code true} if the name corresponds to Shift-JIS or
-     * {@code false} if not
-     */
-    private static boolean isShiftJis(String charsetName) {
-        // Bail quickly if the length doesn't match.
-        if (charsetName == null) {
-            return false;
-        }
-        int length = charsetName.length();
-        if (length != 4 && length != 9) {
-            return false;
-        }
-
-        return charsetName.equalsIgnoreCase("shift_jis")
-            || charsetName.equalsIgnoreCase("shift-jis")
-            || charsetName.equalsIgnoreCase("sjis");
-    }
-
-    /**
-     * Gets the default vendor for this build.
-     * 
-     * @return the default vendor name
-     */
-    private static String getDefaultVendor() {
-        return Build.BRAND;
-    }
-}
diff --git a/core/java/android/util/EventLogTags.java b/core/java/android/util/EventLogTags.java
index 8c18417..f4ce4fd 100644
--- a/core/java/android/util/EventLogTags.java
+++ b/core/java/android/util/EventLogTags.java
@@ -16,14 +16,8 @@
 
 package android.util;
 
-import android.util.Log;
-
 import java.io.BufferedReader;
-import java.io.FileReader;
 import java.io.IOException;
-import java.util.HashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * @deprecated This class is no longer functional.
diff --git a/core/java/android/util/LocalLog.java b/core/java/android/util/LocalLog.java
index 641d1b4..eeb6d58 100644
--- a/core/java/android/util/LocalLog.java
+++ b/core/java/android/util/LocalLog.java
@@ -20,7 +20,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.Iterator;
 import java.util.LinkedList;
 
diff --git a/core/java/android/util/LongArray.java b/core/java/android/util/LongArray.java
new file mode 100644
index 0000000..290a89b
--- /dev/null
+++ b/core/java/android/util/LongArray.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import com.android.internal.util.ArrayUtils;
+
+/**
+ * Implements a growing array of long primitives.
+ *
+ * @hide
+ */
+public class LongArray implements Cloneable {
+    private static final int MIN_CAPACITY_INCREMENT = 12;
+
+    private long[] mValues;
+    private int mSize;
+
+    /**
+     * Creates an empty LongArray with the default initial capacity.
+     */
+    public LongArray() {
+        this(10);
+    }
+
+    /**
+     * Creates an empty LongArray with the specified initial capacity.
+     */
+    public LongArray(int initialCapacity) {
+        if (initialCapacity == 0) {
+            mValues = ContainerHelpers.EMPTY_LONGS;
+        } else {
+            initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
+            mValues = new long[initialCapacity];
+        }
+        mSize = 0;
+    }
+
+    /**
+     * Appends the specified value to the end of this array.
+     */
+    public void add(long value) {
+        add(mSize, value);
+    }
+
+    /**
+     * Inserts a value at the specified position in this array.
+     *
+     * @throws IndexOutOfBoundsException when index &lt; 0 || index &gt; size()
+     */
+    public void add(int index, long value) {
+        if (index < 0 || index > mSize) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        ensureCapacity(1);
+
+        if (mSize - index != 0) {
+            System.arraycopy(mValues, index, mValues, index + 1, mSize - index);
+        }
+
+        mValues[index] = value;
+        mSize++;
+    }
+
+    /**
+     * Adds the values in the specified array to this array.
+     */
+    public void addAll(LongArray values) {
+        final int count = values.mSize;
+        ensureCapacity(count);
+
+        System.arraycopy(values.mValues, 0, mValues, mSize, count);
+        mSize += count;
+    }
+
+    /**
+     * Ensures capacity to append at least <code>count</code> values.
+     */
+    private void ensureCapacity(int count) {
+        final int currentSize = mSize;
+        final int minCapacity = currentSize + count;
+        if (minCapacity >= mValues.length) {
+            final int targetCap = currentSize + (currentSize < (MIN_CAPACITY_INCREMENT / 2) ?
+                    MIN_CAPACITY_INCREMENT : currentSize >> 1);
+            final int newCapacity = targetCap > minCapacity ? targetCap : minCapacity;
+            final long[] newValues = new long[ArrayUtils.idealLongArraySize(newCapacity)];
+            System.arraycopy(mValues, 0, newValues, 0, currentSize);
+            mValues = newValues;
+        }
+    }
+
+    /**
+     * Removes all values from this array.
+     */
+    public void clear() {
+        mSize = 0;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public LongArray clone() {
+        LongArray clone = null;
+        try {
+            clone = (LongArray) super.clone();
+            clone.mValues = mValues.clone();
+        } catch (CloneNotSupportedException cnse) {
+            /* ignore */
+        }
+        return clone;
+    }
+
+    /**
+     * Returns the value at the specified position in this array.
+     */
+    public long get(int index) {
+        if (index >= mSize) {
+            throw new ArrayIndexOutOfBoundsException(mSize, index);
+        }
+        return mValues[index];
+    }
+
+    /**
+     * Returns the index of the first occurrence of the specified value in this
+     * array, or -1 if this array does not contain the value.
+     */
+    public int indexOf(long value) {
+        final int n = mSize;
+        for (int i = 0; i < n; i++) {
+            if (mValues[i] == value) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Removes the value at the specified index from this array.
+     */
+    public void remove(int index) {
+        if (index >= mSize) {
+            throw new ArrayIndexOutOfBoundsException(mSize, index);
+        }
+        System.arraycopy(mValues, index, mValues, index + 1, mSize - index);
+    }
+
+    /**
+     * Returns the number of values in this array.
+     */
+    public int size() {
+        return mSize;
+    }
+}
diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java
index d6e116f..dab853a 100644
--- a/core/java/android/util/LongSparseArray.java
+++ b/core/java/android/util/LongSparseArray.java
@@ -44,7 +44,7 @@
  * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
  * <code>keyAt(int)</code> with ascending values of the index will return the
  * keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)<code>.</p>
+ * order in the case of <code>valueAt(int)</code>.</p>
  */
 public class LongSparseArray<E> implements Cloneable {
     private static final Object DELETED = new Object();
diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
index 87d868b..b8073dd 100644
--- a/core/java/android/util/LongSparseLongArray.java
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -18,8 +18,6 @@
 
 import com.android.internal.util.ArrayUtils;
 
-import java.util.Arrays;
-
 /**
  * Map of {@code long} to {@code long}. Unlike a normal array of longs, there
  * can be gaps in the indices. It is intended to be more memory efficient than using a
@@ -39,7 +37,7 @@
  * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
  * <code>keyAt(int)</code> with ascending values of the index will return the
  * keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)<code>.</p>
+ * order in the case of <code>valueAt(int)</code>.</p>
  *
  * @hide
  */
diff --git a/core/java/android/util/Slog.java b/core/java/android/util/Slog.java
index 70795bb..b25d80f 100644
--- a/core/java/android/util/Slog.java
+++ b/core/java/android/util/Slog.java
@@ -16,11 +16,6 @@
 
 package android.util;
 
-import com.android.internal.os.RuntimeInit;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
 /**
  * @hide
  */
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index 6e168a8..46d9d45 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -44,7 +44,7 @@
  * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
  * <code>keyAt(int)</code> with ascending values of the index will return the
  * keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)<code>.</p>
+ * order in the case of <code>valueAt(int)</code>.</p>
  */
 public class SparseArray<E> implements Cloneable {
     private static final Object DELETED = new Object();
diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java
index 68487e3..905dcb0 100644
--- a/core/java/android/util/SparseBooleanArray.java
+++ b/core/java/android/util/SparseBooleanArray.java
@@ -38,7 +38,7 @@
  * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
  * <code>keyAt(int)</code> with ascending values of the index will return the
  * keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)<code>.</p>
+ * order in the case of <code>valueAt(int)</code>.</p>
  */
 public class SparseBooleanArray implements Cloneable {
     /**
diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java
index 0835cb0..4f5ca07 100644
--- a/core/java/android/util/SparseIntArray.java
+++ b/core/java/android/util/SparseIntArray.java
@@ -37,7 +37,7 @@
  * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
  * <code>keyAt(int)</code> with ascending values of the index will return the
  * keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)<code>.</p>
+ * order in the case of <code>valueAt(int)</code>.</p>
  */
 public class SparseIntArray implements Cloneable {
     private int[] mKeys;
diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java
index 62c1c0d..39fc8a3 100644
--- a/core/java/android/util/SparseLongArray.java
+++ b/core/java/android/util/SparseLongArray.java
@@ -37,7 +37,7 @@
  * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
  * <code>keyAt(int)</code> with ascending values of the index will return the
  * keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)<code>.</p>
+ * order in the case of <code>valueAt(int)</code>.</p>
  */
 public class SparseLongArray implements Cloneable {
     private int[] mKeys;
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 41d3700..3859ad4 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -24,7 +24,6 @@
 import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
-import android.util.SparseLongArray;
 import android.view.View.AttachInfo;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -881,13 +880,12 @@
                 AccessibilityNodeInfo parent =
                     provider.createAccessibilityNodeInfo(parentVirtualDescendantId);
                 if (parent != null) {
-                    SparseLongArray childNodeIds = parent.getChildNodeIds();
-                    final int childCount = childNodeIds.size();
+                    final int childCount = parent.getChildCount();
                     for (int i = 0; i < childCount; i++) {
                         if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                             return;
                         }
-                        final long childNodeId = childNodeIds.get(i);
+                        final long childNodeId = parent.getChildId(i);
                         if (childNodeId != current.getSourceNodeId()) {
                             final int childVirtualDescendantId =
                                 AccessibilityNodeInfo.getVirtualDescendantId(childNodeId);
@@ -906,14 +904,13 @@
 
         private void prefetchDescendantsOfVirtualNode(AccessibilityNodeInfo root,
                 AccessibilityNodeProvider provider, List<AccessibilityNodeInfo> outInfos) {
-            SparseLongArray childNodeIds = root.getChildNodeIds();
             final int initialOutInfosSize = outInfos.size();
-            final int childCount = childNodeIds.size();
+            final int childCount = root.getChildCount();
             for (int i = 0; i < childCount; i++) {
                 if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                     return;
                 }
-                final long childNodeId = childNodeIds.get(i);
+                final long childNodeId = root.getChildId(i);
                 AccessibilityNodeInfo child = provider.createAccessibilityNodeInfo(
                         AccessibilityNodeInfo.getVirtualDescendantId(childNodeId));
                 if (child != null) {
diff --git a/core/java/android/view/AccessibilityIterators.java b/core/java/android/view/AccessibilityIterators.java
index 17ce4f6..e59937d 100644
--- a/core/java/android/view/AccessibilityIterators.java
+++ b/core/java/android/view/AccessibilityIterators.java
@@ -17,8 +17,6 @@
 package android.view;
 
 import android.content.ComponentCallbacks;
-import android.content.Context;
-import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 
 import java.text.BreakIterator;
diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java
index 6c733f9..1de9c35 100644
--- a/core/java/android/view/ContextThemeWrapper.java
+++ b/core/java/android/view/ContextThemeWrapper.java
@@ -20,7 +20,6 @@
 import android.content.ContextWrapper;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.os.Build;
 
 /**
  * A ContextWrapper that allows you to modify the theme from what is in the 
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 7d310a2..d3f63b4 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -528,6 +528,7 @@
      * 90 degrees clockwise and thus the returned value here will be
      * {@link Surface#ROTATION_90 Surface.ROTATION_90}.
      */
+    @Surface.Rotation
     public int getRotation() {
         synchronized (this) {
             updateDisplayInfoLocked();
@@ -540,6 +541,7 @@
      * @return orientation of this display.
      */
     @Deprecated
+    @Surface.Rotation
     public int getOrientation() {
         return getRotation();
     }
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 8944207..7fd7b83 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -20,7 +20,6 @@
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Process;
 import android.util.DisplayMetrics;
 
 import libcore.util.Objects;
@@ -144,6 +143,7 @@
      * more than one physical display.
      * </p>
      */
+    @Surface.Rotation
     public int rotation;
 
     /**
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index 43fd628..623472a3 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -86,18 +86,15 @@
  *
  * <pre class="prettyprint">
  *     private void createDisplayList() {
- *         HardwareRenderer renderer = getHardwareRenderer();
- *         if (renderer != null) {
- *             mDisplayList = renderer.createDisplayList();
- *             HardwareCanvas canvas = mDisplayList.start(width, height);
- *             try {
- *                 for (Bitmap b : mBitmaps) {
- *                     canvas.drawBitmap(b, 0.0f, 0.0f, null);
- *                     canvas.translate(0.0f, b.getHeight());
- *                 }
- *             } finally {
- *                 displayList.end();
+ *         mDisplayList = DisplayList.create("MyDisplayList");
+ *         HardwareCanvas canvas = mDisplayList.start(width, height);
+ *         try {
+ *             for (Bitmap b : mBitmaps) {
+ *                 canvas.drawBitmap(b, 0.0f, 0.0f, null);
+ *                 canvas.translate(0.0f, b.getHeight());
  *             }
+ *         } finally {
+ *             displayList.end();
  *         }
  *     }
  *
@@ -177,6 +174,20 @@
     public static final int STATUS_DREW = 0x4;
 
     /**
+     * Creates a new display list that can be used to record batches of
+     * drawing operations.
+     *
+     * @param name The name of the display list, used for debugging purpose. May be null.
+     *
+     * @return A new display list.
+     *
+     * @hide
+     */
+    public static DisplayList create(String name) {
+        return new GLES20DisplayList(name);
+    }
+
+    /**
      * Starts recording the display list. All operations performed on the
      * returned canvas are recorded and stored in this display list.
      *
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
new file mode 100644
index 0000000..a195231
--- /dev/null
+++ b/core/java/android/view/GLRenderer.java
@@ -0,0 +1,1610 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static javax.microedition.khronos.egl.EGL10.EGL_ALPHA_SIZE;
+import static javax.microedition.khronos.egl.EGL10.EGL_BAD_NATIVE_WINDOW;
+import static javax.microedition.khronos.egl.EGL10.EGL_BLUE_SIZE;
+import static javax.microedition.khronos.egl.EGL10.EGL_CONFIG_CAVEAT;
+import static javax.microedition.khronos.egl.EGL10.EGL_DEFAULT_DISPLAY;
+import static javax.microedition.khronos.egl.EGL10.EGL_DEPTH_SIZE;
+import static javax.microedition.khronos.egl.EGL10.EGL_DRAW;
+import static javax.microedition.khronos.egl.EGL10.EGL_GREEN_SIZE;
+import static javax.microedition.khronos.egl.EGL10.EGL_HEIGHT;
+import static javax.microedition.khronos.egl.EGL10.EGL_NONE;
+import static javax.microedition.khronos.egl.EGL10.EGL_NO_CONTEXT;
+import static javax.microedition.khronos.egl.EGL10.EGL_NO_DISPLAY;
+import static javax.microedition.khronos.egl.EGL10.EGL_NO_SURFACE;
+import static javax.microedition.khronos.egl.EGL10.EGL_RED_SIZE;
+import static javax.microedition.khronos.egl.EGL10.EGL_RENDERABLE_TYPE;
+import static javax.microedition.khronos.egl.EGL10.EGL_SAMPLES;
+import static javax.microedition.khronos.egl.EGL10.EGL_SAMPLE_BUFFERS;
+import static javax.microedition.khronos.egl.EGL10.EGL_STENCIL_SIZE;
+import static javax.microedition.khronos.egl.EGL10.EGL_SUCCESS;
+import static javax.microedition.khronos.egl.EGL10.EGL_SURFACE_TYPE;
+import static javax.microedition.khronos.egl.EGL10.EGL_WIDTH;
+import static javax.microedition.khronos.egl.EGL10.EGL_WINDOW_BIT;
+
+import android.content.ComponentCallbacks2;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.SurfaceTexture;
+import android.opengl.EGL14;
+import android.opengl.GLUtils;
+import android.opengl.ManagedEGLContext;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.Trace;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Surface.OutOfResourcesException;
+
+import com.google.android.gles_jni.EGLImpl;
+
+import java.io.PrintWriter;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGL11;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
+import javax.microedition.khronos.opengles.GL;
+
+/**
+ * Hardware renderer using OpenGL
+ *
+ * @hide
+ */
+public class GLRenderer extends HardwareRenderer {
+    static final int SURFACE_STATE_ERROR = 0;
+    static final int SURFACE_STATE_SUCCESS = 1;
+    static final int SURFACE_STATE_UPDATED = 2;
+
+    static final int FUNCTOR_PROCESS_DELAY = 4;
+
+    /**
+     * Number of frames to profile.
+     */
+    private static final int PROFILE_MAX_FRAMES = 128;
+
+    /**
+     * Number of floats per profiled frame.
+     */
+    private static final int PROFILE_FRAME_DATA_COUNT = 3;
+
+    private static final int PROFILE_DRAW_MARGIN = 0;
+    private static final int PROFILE_DRAW_WIDTH = 3;
+    private static final int[] PROFILE_DRAW_COLORS = { 0xcf3e66cc, 0xcfdc3912, 0xcfe69800 };
+    private static final int PROFILE_DRAW_CURRENT_FRAME_COLOR = 0xcf5faa4d;
+    private static final int PROFILE_DRAW_THRESHOLD_COLOR = 0xff5faa4d;
+    private static final int PROFILE_DRAW_THRESHOLD_STROKE_WIDTH = 2;
+    private static final int PROFILE_DRAW_DP_PER_MS = 7;
+
+    private static final String[] VISUALIZERS = {
+            PROFILE_PROPERTY_VISUALIZE_BARS,
+            PROFILE_PROPERTY_VISUALIZE_LINES
+    };
+
+    private static final String[] OVERDRAW = {
+            OVERDRAW_PROPERTY_SHOW,
+            OVERDRAW_PROPERTY_COUNT
+    };
+    private static final int OVERDRAW_TYPE_COUNT = 1;
+    private static final int GL_VERSION = 2;
+
+    static EGL10 sEgl;
+    static EGLDisplay sEglDisplay;
+    static EGLConfig sEglConfig;
+    static final Object[] sEglLock = new Object[0];
+    int mWidth = -1, mHeight = -1;
+
+    static final ThreadLocal<ManagedEGLContext> sEglContextStorage
+            = new ThreadLocal<ManagedEGLContext>();
+
+    EGLContext mEglContext;
+    Thread mEglThread;
+
+    EGLSurface mEglSurface;
+
+    GL mGl;
+    HardwareCanvas mCanvas;
+
+    String mName;
+
+    long mFrameCount;
+    Paint mDebugPaint;
+
+    static boolean sDirtyRegions;
+    static final boolean sDirtyRegionsRequested;
+    static {
+        String dirtyProperty = SystemProperties.get(RENDER_DIRTY_REGIONS_PROPERTY, "true");
+        //noinspection PointlessBooleanExpression,ConstantConditions
+        sDirtyRegions = "true".equalsIgnoreCase(dirtyProperty);
+        sDirtyRegionsRequested = sDirtyRegions;
+    }
+
+    boolean mDirtyRegionsEnabled;
+    boolean mUpdateDirtyRegions;
+
+    boolean mProfileEnabled;
+    int mProfileVisualizerType = -1;
+    float[] mProfileData;
+    ReentrantLock mProfileLock;
+    int mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
+
+    GraphDataProvider mDebugDataProvider;
+    float[][] mProfileShapes;
+    Paint mProfilePaint;
+
+    boolean mDebugDirtyRegions;
+    int mDebugOverdraw = -1;
+    HardwareLayer mDebugOverdrawLayer;
+    Paint mDebugOverdrawPaint;
+
+    final boolean mTranslucent;
+
+    private boolean mDestroyed;
+
+    private final Rect mRedrawClip = new Rect();
+
+    private final int[] mSurfaceSize = new int[2];
+    private final FunctorsRunnable mFunctorsRunnable = new FunctorsRunnable();
+
+    private long mDrawDelta = Long.MAX_VALUE;
+
+    private GLES20Canvas mGlCanvas;
+
+    private DisplayMetrics mDisplayMetrics;
+
+    private static EGLSurface sPbuffer;
+    private static final Object[] sPbufferLock = new Object[0];
+
+    private static class GLRendererEglContext extends ManagedEGLContext {
+        final Handler mHandler = new Handler();
+
+        public GLRendererEglContext(EGLContext context) {
+            super(context);
+        }
+
+        @Override
+        public void onTerminate(final EGLContext eglContext) {
+            // Make sure we do this on the correct thread.
+            if (mHandler.getLooper() != Looper.myLooper()) {
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        onTerminate(eglContext);
+                    }
+                });
+                return;
+            }
+
+            synchronized (sEglLock) {
+                if (sEgl == null) return;
+
+                if (EGLImpl.getInitCount(sEglDisplay) == 1) {
+                    usePbufferSurface(eglContext);
+                    GLES20Canvas.terminateCaches();
+
+                    sEgl.eglDestroyContext(sEglDisplay, eglContext);
+                    sEglContextStorage.set(null);
+                    sEglContextStorage.remove();
+
+                    sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
+                    sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
+                            EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+                    sEgl.eglReleaseThread();
+                    sEgl.eglTerminate(sEglDisplay);
+
+                    sEgl = null;
+                    sEglDisplay = null;
+                    sEglConfig = null;
+                    sPbuffer = null;
+                }
+            }
+        }
+    }
+
+    HardwareCanvas createCanvas() {
+        return mGlCanvas = new GLES20Canvas(mTranslucent);
+    }
+
+    ManagedEGLContext createManagedContext(EGLContext eglContext) {
+        return new GLRendererEglContext(mEglContext);
+    }
+
+    int[] getConfig(boolean dirtyRegions) {
+        //noinspection PointlessBooleanExpression,ConstantConditions
+        final int stencilSize = GLES20Canvas.getStencilSize();
+        final int swapBehavior = dirtyRegions ? EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
+
+        return new int[] {
+                EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
+                EGL_RED_SIZE, 8,
+                EGL_GREEN_SIZE, 8,
+                EGL_BLUE_SIZE, 8,
+                EGL_ALPHA_SIZE, 8,
+                EGL_DEPTH_SIZE, 0,
+                EGL_CONFIG_CAVEAT, EGL_NONE,
+                EGL_STENCIL_SIZE, stencilSize,
+                EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior,
+                EGL_NONE
+        };
+    }
+
+    void initCaches() {
+        if (GLES20Canvas.initCaches()) {
+            // Caches were (re)initialized, rebind atlas
+            initAtlas();
+        }
+    }
+
+    void initAtlas() {
+        IBinder binder = ServiceManager.getService("assetatlas");
+        if (binder == null) return;
+
+        IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
+        try {
+            if (atlas.isCompatible(android.os.Process.myPpid())) {
+                GraphicBuffer buffer = atlas.getBuffer();
+                if (buffer != null) {
+                    int[] map = atlas.getMap();
+                    if (map != null) {
+                        GLES20Canvas.initAtlas(buffer, map);
+                    }
+                    // If IAssetAtlas is not the same class as the IBinder
+                    // we are using a remote service and we can safely
+                    // destroy the graphic buffer
+                    if (atlas.getClass() != binder.getClass()) {
+                        buffer.destroy();
+                    }
+                }
+            }
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Could not acquire atlas", e);
+        }
+    }
+
+    boolean canDraw() {
+        return mGl != null && mCanvas != null && mGlCanvas != null;
+    }
+
+    int onPreDraw(Rect dirty) {
+        return mGlCanvas.onPreDraw(dirty);
+    }
+
+    void onPostDraw() {
+        mGlCanvas.onPostDraw();
+    }
+
+    void drawProfileData(View.AttachInfo attachInfo) {
+        if (mDebugDataProvider != null) {
+            final GraphDataProvider provider = mDebugDataProvider;
+            initProfileDrawData(attachInfo, provider);
+
+            final int height = provider.getVerticalUnitSize();
+            final int margin = provider.getHorizontaUnitMargin();
+            final int width = provider.getHorizontalUnitSize();
+
+            int x = 0;
+            int count = 0;
+            int current = 0;
+
+            final float[] data = provider.getData();
+            final int elementCount = provider.getElementCount();
+            final int graphType = provider.getGraphType();
+
+            int totalCount = provider.getFrameCount() * elementCount;
+            if (graphType == GraphDataProvider.GRAPH_TYPE_LINES) {
+                totalCount -= elementCount;
+            }
+
+            for (int i = 0; i < totalCount; i += elementCount) {
+                if (data[i] < 0.0f) break;
+
+                int index = count * 4;
+                if (i == provider.getCurrentFrame() * elementCount) current = index;
+
+                x += margin;
+                int x2 = x + width;
+
+                int y2 = mHeight;
+                int y1 = (int) (y2 - data[i] * height);
+
+                switch (graphType) {
+                    case GraphDataProvider.GRAPH_TYPE_BARS: {
+                        for (int j = 0; j < elementCount; j++) {
+                            //noinspection MismatchedReadAndWriteOfArray
+                            final float[] r = mProfileShapes[j];
+                            r[index] = x;
+                            r[index + 1] = y1;
+                            r[index + 2] = x2;
+                            r[index + 3] = y2;
+
+                            y2 = y1;
+                            if (j < elementCount - 1) {
+                                y1 = (int) (y2 - data[i + j + 1] * height);
+                            }
+                        }
+                    } break;
+                    case GraphDataProvider.GRAPH_TYPE_LINES: {
+                        for (int j = 0; j < elementCount; j++) {
+                            //noinspection MismatchedReadAndWriteOfArray
+                            final float[] r = mProfileShapes[j];
+                            r[index] = (x + x2) * 0.5f;
+                            r[index + 1] = index == 0 ? y1 : r[index - 1];
+                            r[index + 2] = r[index] + width;
+                            r[index + 3] = y1;
+
+                            y2 = y1;
+                            if (j < elementCount - 1) {
+                                y1 = (int) (y2 - data[i + j + 1] * height);
+                            }
+                        }
+                    } break;
+                }
+
+
+                x += width;
+                count++;
+            }
+
+            x += margin;
+
+            drawGraph(graphType, count);
+            drawCurrentFrame(graphType, current);
+            drawThreshold(x, height);
+        }
+    }
+
+    private void drawGraph(int graphType, int count) {
+        for (int i = 0; i < mProfileShapes.length; i++) {
+            mDebugDataProvider.setupGraphPaint(mProfilePaint, i);
+            switch (graphType) {
+                case GraphDataProvider.GRAPH_TYPE_BARS:
+                    mGlCanvas.drawRects(mProfileShapes[i], count * 4, mProfilePaint);
+                    break;
+                case GraphDataProvider.GRAPH_TYPE_LINES:
+                    mGlCanvas.drawLines(mProfileShapes[i], 0, count * 4, mProfilePaint);
+                    break;
+            }
+        }
+    }
+
+    private void drawCurrentFrame(int graphType, int index) {
+        if (index >= 0) {
+            mDebugDataProvider.setupCurrentFramePaint(mProfilePaint);
+            switch (graphType) {
+                case GraphDataProvider.GRAPH_TYPE_BARS:
+                    mGlCanvas.drawRect(mProfileShapes[2][index], mProfileShapes[2][index + 1],
+                            mProfileShapes[2][index + 2], mProfileShapes[0][index + 3],
+                            mProfilePaint);
+                    break;
+                case GraphDataProvider.GRAPH_TYPE_LINES:
+                    mGlCanvas.drawLine(mProfileShapes[2][index], mProfileShapes[2][index + 1],
+                            mProfileShapes[2][index], mHeight, mProfilePaint);
+                    break;
+            }
+        }
+    }
+
+    private void drawThreshold(int x, int height) {
+        float threshold = mDebugDataProvider.getThreshold();
+        if (threshold > 0.0f) {
+            mDebugDataProvider.setupThresholdPaint(mProfilePaint);
+            int y = (int) (mHeight - threshold * height);
+            mGlCanvas.drawLine(0.0f, y, x, y, mProfilePaint);
+        }
+    }
+
+    private void initProfileDrawData(View.AttachInfo attachInfo, GraphDataProvider provider) {
+        if (mProfileShapes == null) {
+            final int elementCount = provider.getElementCount();
+            final int frameCount = provider.getFrameCount();
+
+            mProfileShapes = new float[elementCount][];
+            for (int i = 0; i < elementCount; i++) {
+                mProfileShapes[i] = new float[frameCount * 4];
+            }
+
+            mProfilePaint = new Paint();
+        }
+
+        mProfilePaint.reset();
+        if (provider.getGraphType() == GraphDataProvider.GRAPH_TYPE_LINES) {
+            mProfilePaint.setAntiAlias(true);
+        }
+
+        if (mDisplayMetrics == null) {
+            mDisplayMetrics = new DisplayMetrics();
+        }
+
+        attachInfo.mDisplay.getMetrics(mDisplayMetrics);
+        provider.prepare(mDisplayMetrics);
+    }
+
+    @Override
+    void destroy(boolean full) {
+        try {
+            if (full && mCanvas != null) {
+                mCanvas = null;
+            }
+
+            if (!isEnabled() || mDestroyed) {
+                setEnabled(false);
+                return;
+            }
+
+            destroySurface();
+            setEnabled(false);
+
+            mDestroyed = true;
+            mGl = null;
+        } finally {
+            if (full && mGlCanvas != null) {
+                mGlCanvas = null;
+            }
+        }
+    }
+
+    @Override
+    void pushLayerUpdate(HardwareLayer layer) {
+        mGlCanvas.pushLayerUpdate(layer);
+    }
+
+    @Override
+    void cancelLayerUpdate(HardwareLayer layer) {
+        mGlCanvas.cancelLayerUpdate(layer);
+    }
+
+    @Override
+    void flushLayerUpdates() {
+        mGlCanvas.flushLayerUpdates();
+    }
+
+    @Override
+    HardwareLayer createHardwareLayer(boolean isOpaque) {
+        return new GLES20TextureLayer(isOpaque);
+    }
+
+    @Override
+    public HardwareLayer createHardwareLayer(int width, int height, boolean isOpaque) {
+        return new GLES20RenderLayer(width, height, isOpaque);
+    }
+
+    void countOverdraw(HardwareCanvas canvas) {
+        ((GLES20Canvas) canvas).setCountOverdrawEnabled(true);
+    }
+
+    float getOverdraw(HardwareCanvas canvas) {
+        return ((GLES20Canvas) canvas).getOverdraw();
+    }
+
+    @Override
+    public SurfaceTexture createSurfaceTexture(HardwareLayer layer) {
+        return ((GLES20TextureLayer) layer).getSurfaceTexture();
+    }
+
+    @Override
+    void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture) {
+        ((GLES20TextureLayer) layer).setSurfaceTexture(surfaceTexture);
+    }
+
+    @Override
+    boolean safelyRun(Runnable action) {
+        boolean needsContext = !isEnabled() || checkRenderContext() == SURFACE_STATE_ERROR;
+
+        if (needsContext) {
+            GLRendererEglContext managedContext =
+                    (GLRendererEglContext) sEglContextStorage.get();
+            if (managedContext == null) return false;
+            usePbufferSurface(managedContext.getContext());
+        }
+
+        try {
+            action.run();
+        } finally {
+            if (needsContext) {
+                sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
+                        EGL_NO_SURFACE, EGL_NO_CONTEXT);
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    void destroyLayers(final View view) {
+        if (view != null) {
+            safelyRun(new Runnable() {
+                @Override
+                public void run() {
+                    if (mCanvas != null) {
+                        mCanvas.clearLayerUpdates();
+                    }
+                    destroyHardwareLayer(view);
+                    GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
+                }
+            });
+        }
+    }
+
+    private static void destroyHardwareLayer(View view) {
+        view.destroyLayer(true);
+
+        if (view instanceof ViewGroup) {
+            ViewGroup group = (ViewGroup) view;
+
+            int count = group.getChildCount();
+            for (int i = 0; i < count; i++) {
+                destroyHardwareLayer(group.getChildAt(i));
+            }
+        }
+    }
+
+    @Override
+    void destroyHardwareResources(final View view) {
+        if (view != null) {
+            safelyRun(new Runnable() {
+                @Override
+                public void run() {
+                    if (mCanvas != null) {
+                        mCanvas.clearLayerUpdates();
+                    }
+                    destroyResources(view);
+                    GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
+                }
+            });
+        }
+    }
+
+    private static void destroyResources(View view) {
+        view.destroyHardwareResources();
+
+        if (view instanceof ViewGroup) {
+            ViewGroup group = (ViewGroup) view;
+
+            int count = group.getChildCount();
+            for (int i = 0; i < count; i++) {
+                destroyResources(group.getChildAt(i));
+            }
+        }
+    }
+
+    static void startTrimMemory(int level) {
+        if (sEgl == null || sEglConfig == null) return;
+
+        GLRendererEglContext managedContext =
+                (GLRendererEglContext) sEglContextStorage.get();
+        // We do not have OpenGL objects
+        if (managedContext == null) {
+            return;
+        } else {
+            usePbufferSurface(managedContext.getContext());
+        }
+
+        if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
+            GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
+        } else if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
+            GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
+        }
+    }
+
+    static void endTrimMemory() {
+        if (sEgl != null && sEglDisplay != null) {
+            sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        }
+    }
+
+    private static void usePbufferSurface(EGLContext eglContext) {
+        synchronized (sPbufferLock) {
+            // Create a temporary 1x1 pbuffer so we have a context
+            // to clear our OpenGL objects
+            if (sPbuffer == null) {
+                sPbuffer = sEgl.eglCreatePbufferSurface(sEglDisplay, sEglConfig, new int[] {
+                        EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE
+                });
+            }
+        }
+        sEgl.eglMakeCurrent(sEglDisplay, sPbuffer, sPbuffer, eglContext);
+    }
+
+    GLRenderer(boolean translucent) {
+        mTranslucent = translucent;
+
+        loadSystemProperties(null);
+    }
+
+    @Override
+    boolean loadSystemProperties(Surface surface) {
+        boolean value;
+        boolean changed = false;
+
+        String profiling = SystemProperties.get(PROFILE_PROPERTY);
+        int graphType = search(VISUALIZERS, profiling);
+        value = graphType >= 0;
+
+        if (graphType != mProfileVisualizerType) {
+            changed = true;
+            mProfileVisualizerType = graphType;
+
+            mProfileShapes = null;
+            mProfilePaint = null;
+
+            if (value) {
+                mDebugDataProvider = new DrawPerformanceDataProvider(graphType);
+            } else {
+                mDebugDataProvider = null;
+            }
+        }
+
+        // If on-screen profiling is not enabled, we need to check whether
+        // console profiling only is enabled
+        if (!value) {
+            value = Boolean.parseBoolean(profiling);
+        }
+
+        if (value != mProfileEnabled) {
+            changed = true;
+            mProfileEnabled = value;
+
+            if (mProfileEnabled) {
+                Log.d(LOG_TAG, "Profiling hardware renderer");
+
+                int maxProfileFrames = SystemProperties.getInt(PROFILE_MAXFRAMES_PROPERTY,
+                        PROFILE_MAX_FRAMES);
+                mProfileData = new float[maxProfileFrames * PROFILE_FRAME_DATA_COUNT];
+                for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
+                    mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
+                }
+
+                mProfileLock = new ReentrantLock();
+            } else {
+                mProfileData = null;
+                mProfileLock = null;
+                mProfileVisualizerType = -1;
+            }
+
+            mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
+        }
+
+        value = SystemProperties.getBoolean(DEBUG_DIRTY_REGIONS_PROPERTY, false);
+        if (value != mDebugDirtyRegions) {
+            changed = true;
+            mDebugDirtyRegions = value;
+
+            if (mDebugDirtyRegions) {
+                Log.d(LOG_TAG, "Debugging dirty regions");
+            }
+        }
+
+        String overdraw = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
+        int debugOverdraw = search(OVERDRAW, overdraw);
+        if (debugOverdraw != mDebugOverdraw) {
+            changed = true;
+            mDebugOverdraw = debugOverdraw;
+
+            if (mDebugOverdraw != OVERDRAW_TYPE_COUNT) {
+                if (mDebugOverdrawLayer != null) {
+                    mDebugOverdrawLayer.destroy();
+                    mDebugOverdrawLayer = null;
+                    mDebugOverdrawPaint = null;
+                }
+            }
+        }
+
+        if (loadProperties()) {
+            changed = true;
+        }
+
+        return changed;
+    }
+
+    private static int search(String[] values, String value) {
+        for (int i = 0; i < values.length; i++) {
+            if (values[i].equals(value)) return i;
+        }
+        return -1;
+    }
+
+    @Override
+    void dumpGfxInfo(PrintWriter pw) {
+        if (mProfileEnabled) {
+            pw.printf("\n\tDraw\tProcess\tExecute\n");
+
+            mProfileLock.lock();
+            try {
+                for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
+                    if (mProfileData[i] < 0) {
+                        break;
+                    }
+                    pw.printf("\t%3.2f\t%3.2f\t%3.2f\n", mProfileData[i], mProfileData[i + 1],
+                            mProfileData[i + 2]);
+                    mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
+                }
+                mProfileCurrentFrame = mProfileData.length;
+            } finally {
+                mProfileLock.unlock();
+            }
+        }
+    }
+
+    @Override
+    long getFrameCount() {
+        return mFrameCount;
+    }
+
+    /**
+     * Indicates whether this renderer instance can track and update dirty regions.
+     */
+    boolean hasDirtyRegions() {
+        return mDirtyRegionsEnabled;
+    }
+
+    /**
+     * Checks for OpenGL errors. If an error has occured, {@link #destroy(boolean)}
+     * is invoked and the requested flag is turned off. The error code is
+     * also logged as a warning.
+     */
+    void checkEglErrors() {
+        if (isEnabled()) {
+            checkEglErrorsForced();
+        }
+    }
+
+    private void checkEglErrorsForced() {
+        int error = sEgl.eglGetError();
+        if (error != EGL_SUCCESS) {
+            // something bad has happened revert to
+            // normal rendering.
+            Log.w(LOG_TAG, "EGL error: " + GLUtils.getEGLErrorString(error));
+            fallback(error != EGL11.EGL_CONTEXT_LOST);
+        }
+    }
+
+    private void fallback(boolean fallback) {
+        destroy(true);
+        if (fallback) {
+            // we'll try again if it was context lost
+            setRequested(false);
+            Log.w(LOG_TAG, "Mountain View, we've had a problem here. "
+                    + "Switching back to software rendering.");
+        }
+    }
+
+    @Override
+    boolean initialize(Surface surface) throws OutOfResourcesException {
+        if (isRequested() && !isEnabled()) {
+            boolean contextCreated = initializeEgl();
+            mGl = createEglSurface(surface);
+            mDestroyed = false;
+
+            if (mGl != null) {
+                int err = sEgl.eglGetError();
+                if (err != EGL_SUCCESS) {
+                    destroy(true);
+                    setRequested(false);
+                } else {
+                    if (mCanvas == null) {
+                        mCanvas = createCanvas();
+                        mCanvas.setName(mName);
+                    }
+                    setEnabled(true);
+
+                    if (contextCreated) {
+                        initAtlas();
+                    }
+                }
+
+                return mCanvas != null;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    void updateSurface(Surface surface) throws OutOfResourcesException {
+        if (isRequested() && isEnabled()) {
+            createEglSurface(surface);
+        }
+    }
+
+    boolean initializeEgl() {
+        synchronized (sEglLock) {
+            if (sEgl == null && sEglConfig == null) {
+                sEgl = (EGL10) EGLContext.getEGL();
+
+                // Get to the default display.
+                sEglDisplay = sEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+                if (sEglDisplay == EGL_NO_DISPLAY) {
+                    throw new RuntimeException("eglGetDisplay failed "
+                            + GLUtils.getEGLErrorString(sEgl.eglGetError()));
+                }
+
+                // We can now initialize EGL for that display
+                int[] version = new int[2];
+                if (!sEgl.eglInitialize(sEglDisplay, version)) {
+                    throw new RuntimeException("eglInitialize failed " +
+                            GLUtils.getEGLErrorString(sEgl.eglGetError()));
+                }
+
+                checkEglErrorsForced();
+
+                sEglConfig = loadEglConfig();
+            }
+        }
+
+        ManagedEGLContext managedContext = sEglContextStorage.get();
+        mEglContext = managedContext != null ? managedContext.getContext() : null;
+        mEglThread = Thread.currentThread();
+
+        if (mEglContext == null) {
+            mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
+            sEglContextStorage.set(createManagedContext(mEglContext));
+            return true;
+        }
+
+        return false;
+    }
+
+    private EGLConfig loadEglConfig() {
+        EGLConfig eglConfig = chooseEglConfig();
+        if (eglConfig == null) {
+            // We tried to use EGL_SWAP_BEHAVIOR_PRESERVED_BIT, try again without
+            if (sDirtyRegions) {
+                sDirtyRegions = false;
+                eglConfig = chooseEglConfig();
+                if (eglConfig == null) {
+                    throw new RuntimeException("eglConfig not initialized");
+                }
+            } else {
+                throw new RuntimeException("eglConfig not initialized");
+            }
+        }
+        return eglConfig;
+    }
+
+    private EGLConfig chooseEglConfig() {
+        EGLConfig[] configs = new EGLConfig[1];
+        int[] configsCount = new int[1];
+        int[] configSpec = getConfig(sDirtyRegions);
+
+        // Debug
+        final String debug = SystemProperties.get(PRINT_CONFIG_PROPERTY, "");
+        if ("all".equalsIgnoreCase(debug)) {
+            sEgl.eglChooseConfig(sEglDisplay, configSpec, null, 0, configsCount);
+
+            EGLConfig[] debugConfigs = new EGLConfig[configsCount[0]];
+            sEgl.eglChooseConfig(sEglDisplay, configSpec, debugConfigs,
+                    configsCount[0], configsCount);
+
+            for (EGLConfig config : debugConfigs) {
+                printConfig(config);
+            }
+        }
+
+        if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) {
+            throw new IllegalArgumentException("eglChooseConfig failed " +
+                    GLUtils.getEGLErrorString(sEgl.eglGetError()));
+        } else if (configsCount[0] > 0) {
+            if ("choice".equalsIgnoreCase(debug)) {
+                printConfig(configs[0]);
+            }
+            return configs[0];
+        }
+
+        return null;
+    }
+
+    private static void printConfig(EGLConfig config) {
+        int[] value = new int[1];
+
+        Log.d(LOG_TAG, "EGL configuration " + config + ":");
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_RED_SIZE, value);
+        Log.d(LOG_TAG, "  RED_SIZE = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_GREEN_SIZE, value);
+        Log.d(LOG_TAG, "  GREEN_SIZE = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_BLUE_SIZE, value);
+        Log.d(LOG_TAG, "  BLUE_SIZE = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_ALPHA_SIZE, value);
+        Log.d(LOG_TAG, "  ALPHA_SIZE = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_DEPTH_SIZE, value);
+        Log.d(LOG_TAG, "  DEPTH_SIZE = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_STENCIL_SIZE, value);
+        Log.d(LOG_TAG, "  STENCIL_SIZE = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLE_BUFFERS, value);
+        Log.d(LOG_TAG, "  SAMPLE_BUFFERS = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLES, value);
+        Log.d(LOG_TAG, "  SAMPLES = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SURFACE_TYPE, value);
+        Log.d(LOG_TAG, "  SURFACE_TYPE = 0x" + Integer.toHexString(value[0]));
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_CONFIG_CAVEAT, value);
+        Log.d(LOG_TAG, "  CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0]));
+    }
+
+    GL createEglSurface(Surface surface) throws OutOfResourcesException {
+        // Check preconditions.
+        if (sEgl == null) {
+            throw new RuntimeException("egl not initialized");
+        }
+        if (sEglDisplay == null) {
+            throw new RuntimeException("eglDisplay not initialized");
+        }
+        if (sEglConfig == null) {
+            throw new RuntimeException("eglConfig not initialized");
+        }
+        if (Thread.currentThread() != mEglThread) {
+            throw new IllegalStateException("HardwareRenderer cannot be used "
+                    + "from multiple threads");
+        }
+
+        // In case we need to destroy an existing surface
+        destroySurface();
+
+        // Create an EGL surface we can render into.
+        if (!createSurface(surface)) {
+            return null;
+        }
+
+        initCaches();
+
+        return mEglContext.getGL();
+    }
+
+    private void enableDirtyRegions() {
+        // If mDirtyRegions is set, this means we have an EGL configuration
+        // with EGL_SWAP_BEHAVIOR_PRESERVED_BIT set
+        if (sDirtyRegions) {
+            if (!(mDirtyRegionsEnabled = preserveBackBuffer())) {
+                Log.w(LOG_TAG, "Backbuffer cannot be preserved");
+            }
+        } else if (sDirtyRegionsRequested) {
+            // If mDirtyRegions is not set, our EGL configuration does not
+            // have EGL_SWAP_BEHAVIOR_PRESERVED_BIT; however, the default
+            // swap behavior might be EGL_BUFFER_PRESERVED, which means we
+            // want to set mDirtyRegions. We try to do this only if dirty
+            // regions were initially requested as part of the device
+            // configuration (see RENDER_DIRTY_REGIONS)
+            mDirtyRegionsEnabled = isBackBufferPreserved();
+        }
+    }
+
+    EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
+        final int[] attribs = { EGL14.EGL_CONTEXT_CLIENT_VERSION, GL_VERSION, EGL_NONE };
+
+        EGLContext context = egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT,
+                attribs);
+        if (context == null || context == EGL_NO_CONTEXT) {
+            //noinspection ConstantConditions
+            throw new IllegalStateException(
+                    "Could not create an EGL context. eglCreateContext failed with error: " +
+                    GLUtils.getEGLErrorString(sEgl.eglGetError()));
+        }
+
+        return context;
+    }
+
+    void destroySurface() {
+        if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
+            if (mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW))) {
+                sEgl.eglMakeCurrent(sEglDisplay,
+                        EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+            }
+            sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
+            mEglSurface = null;
+        }
+    }
+
+    @Override
+    void invalidate(Surface surface) {
+        // Cancels any existing buffer to ensure we'll get a buffer
+        // of the right size before we call eglSwapBuffers
+        sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+        if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
+            sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
+            mEglSurface = null;
+            setEnabled(false);
+        }
+
+        if (surface.isValid()) {
+            if (!createSurface(surface)) {
+                return;
+            }
+
+            mUpdateDirtyRegions = true;
+
+            if (mCanvas != null) {
+                setEnabled(true);
+            }
+        }
+    }
+
+    private boolean createSurface(Surface surface) {
+        mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, surface, null);
+
+        if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
+            int error = sEgl.eglGetError();
+            if (error == EGL_BAD_NATIVE_WINDOW) {
+                Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
+                return false;
+            }
+            throw new RuntimeException("createWindowSurface failed "
+                    + GLUtils.getEGLErrorString(error));
+        }
+
+        if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+            throw new IllegalStateException("eglMakeCurrent failed " +
+                    GLUtils.getEGLErrorString(sEgl.eglGetError()));
+        }
+
+        enableDirtyRegions();
+
+        return true;
+    }
+
+    @Override
+    boolean validate() {
+        return checkRenderContext() != SURFACE_STATE_ERROR;
+    }
+
+    @Override
+    void setup(int width, int height) {
+        if (validate()) {
+            mCanvas.setViewport(width, height);
+            mWidth = width;
+            mHeight = height;
+        }
+    }
+
+    @Override
+    int getWidth() {
+        return mWidth;
+    }
+
+    @Override
+    int getHeight() {
+        return mHeight;
+    }
+
+    @Override
+    HardwareCanvas getCanvas() {
+        return mCanvas;
+    }
+
+    @Override
+    void setName(String name) {
+        mName = name;
+    }
+
+    class FunctorsRunnable implements Runnable {
+        View.AttachInfo attachInfo;
+
+        @Override
+        public void run() {
+            final HardwareRenderer renderer = attachInfo.mHardwareRenderer;
+            if (renderer == null || !renderer.isEnabled() || renderer != GLRenderer.this) {
+                return;
+            }
+
+            if (checkRenderContext() != SURFACE_STATE_ERROR) {
+                int status = mCanvas.invokeFunctors(mRedrawClip);
+                handleFunctorStatus(attachInfo, status);
+            }
+        }
+    }
+
+    @Override
+    void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
+            Rect dirty) {
+        if (canDraw()) {
+            if (!hasDirtyRegions()) {
+                dirty = null;
+            }
+            attachInfo.mIgnoreDirtyState = true;
+            attachInfo.mDrawingTime = SystemClock.uptimeMillis();
+
+            view.mPrivateFlags |= View.PFLAG_DRAWN;
+
+            // We are already on the correct thread
+            final int surfaceState = checkRenderContextUnsafe();
+            if (surfaceState != SURFACE_STATE_ERROR) {
+                HardwareCanvas canvas = mCanvas;
+                attachInfo.mHardwareCanvas = canvas;
+
+                if (mProfileEnabled) {
+                    mProfileLock.lock();
+                }
+
+                dirty = beginFrame(canvas, dirty, surfaceState);
+
+                DisplayList displayList = buildDisplayList(view, canvas);
+
+                // buildDisplayList() calls into user code which can cause
+                // an eglMakeCurrent to happen with a different surface/context.
+                // We must therefore check again here.
+                if (checkRenderContextUnsafe() == SURFACE_STATE_ERROR) {
+                    return;
+                }
+
+                int saveCount = 0;
+                int status = DisplayList.STATUS_DONE;
+
+                long start = getSystemTime();
+                try {
+                    status = prepareFrame(dirty);
+
+                    saveCount = canvas.save();
+                    callbacks.onHardwarePreDraw(canvas);
+
+                    if (displayList != null) {
+                        status |= drawDisplayList(attachInfo, canvas, displayList, status);
+                    } else {
+                        // Shouldn't reach here
+                        view.draw(canvas);
+                    }
+                } catch (Exception e) {
+                    Log.e(LOG_TAG, "An error has occurred while drawing:", e);
+                } finally {
+                    callbacks.onHardwarePostDraw(canvas);
+                    canvas.restoreToCount(saveCount);
+                    view.mRecreateDisplayList = false;
+
+                    mDrawDelta = getSystemTime() - start;
+
+                    if (mDrawDelta > 0) {
+                        mFrameCount++;
+
+                        debugOverdraw(attachInfo, dirty, canvas, displayList);
+                        debugDirtyRegions(dirty, canvas);
+                        drawProfileData(attachInfo);
+                    }
+                }
+
+                onPostDraw();
+
+                swapBuffers(status);
+
+                if (mProfileEnabled) {
+                    mProfileLock.unlock();
+                }
+
+                attachInfo.mIgnoreDirtyState = false;
+            }
+        }
+    }
+
+    private void debugOverdraw(View.AttachInfo attachInfo, Rect dirty,
+            HardwareCanvas canvas, DisplayList displayList) {
+
+        if (mDebugOverdraw == OVERDRAW_TYPE_COUNT) {
+            if (mDebugOverdrawLayer == null) {
+                mDebugOverdrawLayer = createHardwareLayer(mWidth, mHeight, true);
+            } else if (mDebugOverdrawLayer.getWidth() != mWidth ||
+                    mDebugOverdrawLayer.getHeight() != mHeight) {
+                mDebugOverdrawLayer.resize(mWidth, mHeight);
+            }
+
+            if (!mDebugOverdrawLayer.isValid()) {
+                mDebugOverdraw = -1;
+                return;
+            }
+
+            HardwareCanvas layerCanvas = mDebugOverdrawLayer.start(canvas, dirty);
+            countOverdraw(layerCanvas);
+            final int restoreCount = layerCanvas.save();
+            layerCanvas.drawDisplayList(displayList, null, DisplayList.FLAG_CLIP_CHILDREN);
+            layerCanvas.restoreToCount(restoreCount);
+            mDebugOverdrawLayer.end(canvas);
+
+            float overdraw = getOverdraw(layerCanvas);
+            DisplayMetrics metrics = attachInfo.mRootView.getResources().getDisplayMetrics();
+
+            drawOverdrawCounter(canvas, overdraw, metrics.density);
+        }
+    }
+
+    private void drawOverdrawCounter(HardwareCanvas canvas, float overdraw, float density) {
+        final String text = String.format("%.2fx", overdraw);
+        final Paint paint = setupPaint(density);
+        // HSBtoColor will clamp the values in the 0..1 range
+        paint.setColor(Color.HSBtoColor(0.28f - 0.28f * overdraw / 3.5f, 0.8f, 1.0f));
+
+        canvas.drawText(text, density * 4.0f, mHeight - paint.getFontMetrics().bottom, paint);
+    }
+
+    private Paint setupPaint(float density) {
+        if (mDebugOverdrawPaint == null) {
+            mDebugOverdrawPaint = new Paint();
+            mDebugOverdrawPaint.setAntiAlias(true);
+            mDebugOverdrawPaint.setShadowLayer(density * 3.0f, 0.0f, 0.0f, 0xff000000);
+            mDebugOverdrawPaint.setTextSize(density * 20.0f);
+        }
+        return mDebugOverdrawPaint;
+    }
+
+    private DisplayList buildDisplayList(View view, HardwareCanvas canvas) {
+        if (mDrawDelta <= 0) {
+            return view.mDisplayList;
+        }
+
+        view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
+                == View.PFLAG_INVALIDATED;
+        view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
+
+        long buildDisplayListStartTime = startBuildDisplayListProfiling();
+        canvas.clearLayerUpdates();
+
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
+        DisplayList displayList = view.getDisplayList();
+        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+
+        endBuildDisplayListProfiling(buildDisplayListStartTime);
+
+        return displayList;
+    }
+
+    private Rect beginFrame(HardwareCanvas canvas, Rect dirty, int surfaceState) {
+        // We had to change the current surface and/or context, redraw everything
+        if (surfaceState == SURFACE_STATE_UPDATED) {
+            dirty = null;
+            beginFrame(null);
+        } else {
+            int[] size = mSurfaceSize;
+            beginFrame(size);
+
+            if (size[1] != mHeight || size[0] != mWidth) {
+                mWidth = size[0];
+                mHeight = size[1];
+
+                canvas.setViewport(mWidth, mHeight);
+
+                dirty = null;
+            }
+        }
+
+        if (mDebugDataProvider != null) dirty = null;
+
+        return dirty;
+    }
+
+    private long startBuildDisplayListProfiling() {
+        if (mProfileEnabled) {
+            mProfileCurrentFrame += PROFILE_FRAME_DATA_COUNT;
+            if (mProfileCurrentFrame >= mProfileData.length) {
+                mProfileCurrentFrame = 0;
+            }
+
+            return System.nanoTime();
+        }
+        return 0;
+    }
+
+    private void endBuildDisplayListProfiling(long getDisplayListStartTime) {
+        if (mProfileEnabled) {
+            long now = System.nanoTime();
+            float total = (now - getDisplayListStartTime) * 0.000001f;
+            //noinspection PointlessArithmeticExpression
+            mProfileData[mProfileCurrentFrame] = total;
+        }
+    }
+
+    private int prepareFrame(Rect dirty) {
+        int status;
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "prepareFrame");
+        try {
+            status = onPreDraw(dirty);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+        }
+        return status;
+    }
+
+    private int drawDisplayList(View.AttachInfo attachInfo, HardwareCanvas canvas,
+            DisplayList displayList, int status) {
+
+        long drawDisplayListStartTime = 0;
+        if (mProfileEnabled) {
+            drawDisplayListStartTime = System.nanoTime();
+        }
+
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList");
+        try {
+            status |= canvas.drawDisplayList(displayList, mRedrawClip,
+                    DisplayList.FLAG_CLIP_CHILDREN);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+        }
+
+        if (mProfileEnabled) {
+            long now = System.nanoTime();
+            float total = (now - drawDisplayListStartTime) * 0.000001f;
+            mProfileData[mProfileCurrentFrame + 1] = total;
+        }
+
+        handleFunctorStatus(attachInfo, status);
+        return status;
+    }
+
+    private void swapBuffers(int status) {
+        if ((status & DisplayList.STATUS_DREW) == DisplayList.STATUS_DREW) {
+            long eglSwapBuffersStartTime = 0;
+            if (mProfileEnabled) {
+                eglSwapBuffersStartTime = System.nanoTime();
+            }
+
+            sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
+
+            if (mProfileEnabled) {
+                long now = System.nanoTime();
+                float total = (now - eglSwapBuffersStartTime) * 0.000001f;
+                mProfileData[mProfileCurrentFrame + 2] = total;
+            }
+
+            checkEglErrors();
+        }
+    }
+
+    private void debugDirtyRegions(Rect dirty, HardwareCanvas canvas) {
+        if (mDebugDirtyRegions) {
+            if (mDebugPaint == null) {
+                mDebugPaint = new Paint();
+                mDebugPaint.setColor(0x7fff0000);
+            }
+
+            if (dirty != null && (mFrameCount & 1) == 0) {
+                canvas.drawRect(dirty, mDebugPaint);
+            }
+        }
+    }
+
+    private void handleFunctorStatus(View.AttachInfo attachInfo, int status) {
+        // If the draw flag is set, functors will be invoked while executing
+        // the tree of display lists
+        if ((status & DisplayList.STATUS_DRAW) != 0) {
+            if (mRedrawClip.isEmpty()) {
+                attachInfo.mViewRootImpl.invalidate();
+            } else {
+                attachInfo.mViewRootImpl.invalidateChildInParent(null, mRedrawClip);
+                mRedrawClip.setEmpty();
+            }
+        }
+
+        if ((status & DisplayList.STATUS_INVOKE) != 0 ||
+                attachInfo.mHandler.hasCallbacks(mFunctorsRunnable)) {
+            attachInfo.mHandler.removeCallbacks(mFunctorsRunnable);
+            mFunctorsRunnable.attachInfo = attachInfo;
+            attachInfo.mHandler.postDelayed(mFunctorsRunnable, FUNCTOR_PROCESS_DELAY);
+        }
+    }
+
+    @Override
+    void detachFunctor(int functor) {
+        if (mCanvas != null) {
+            mCanvas.detachFunctor(functor);
+        }
+    }
+
+    @Override
+    boolean attachFunctor(View.AttachInfo attachInfo, int functor) {
+        if (mCanvas != null) {
+            mCanvas.attachFunctor(functor);
+            mFunctorsRunnable.attachInfo = attachInfo;
+            attachInfo.mHandler.removeCallbacks(mFunctorsRunnable);
+            attachInfo.mHandler.postDelayed(mFunctorsRunnable,  0);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Ensures the current EGL context and surface are the ones we expect.
+     * This method throws an IllegalStateException if invoked from a thread
+     * that did not initialize EGL.
+     *
+     * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
+     *         {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
+     *         {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
+     *
+     * @see #checkRenderContextUnsafe()
+     */
+    int checkRenderContext() {
+        if (mEglThread != Thread.currentThread()) {
+            throw new IllegalStateException("Hardware acceleration can only be used with a " +
+                    "single UI thread.\nOriginal thread: " + mEglThread + "\n" +
+                    "Current thread: " + Thread.currentThread());
+        }
+
+        return checkRenderContextUnsafe();
+    }
+
+    /**
+     * Ensures the current EGL context and surface are the ones we expect.
+     * This method does not check the current thread.
+     *
+     * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
+     *         {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
+     *         {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
+     *
+     * @see #checkRenderContext()
+     */
+    private int checkRenderContextUnsafe() {
+        if (!mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW)) ||
+                !mEglContext.equals(sEgl.eglGetCurrentContext())) {
+            if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+                Log.e(LOG_TAG, "eglMakeCurrent failed " +
+                        GLUtils.getEGLErrorString(sEgl.eglGetError()));
+                fallback(true);
+                return SURFACE_STATE_ERROR;
+            } else {
+                if (mUpdateDirtyRegions) {
+                    enableDirtyRegions();
+                    mUpdateDirtyRegions = false;
+                }
+                return SURFACE_STATE_UPDATED;
+            }
+        }
+        return SURFACE_STATE_SUCCESS;
+    }
+
+    private static int dpToPx(int dp, float density) {
+        return (int) (dp * density + 0.5f);
+    }
+
+    private static native boolean loadProperties();
+
+    static native void setupShadersDiskCache(String cacheFile);
+
+    /**
+     * Notifies EGL that the frame is about to be rendered.
+     * @param size
+     */
+    private static native void beginFrame(int[] size);
+
+    /**
+     * Returns the current system time according to the renderer.
+     * This method is used for debugging only and should not be used
+     * as a clock.
+     */
+    private static native long getSystemTime();
+
+    /**
+     * Preserves the back buffer of the current surface after a buffer swap.
+     * Calling this method sets the EGL_SWAP_BEHAVIOR attribute of the current
+     * surface to EGL_BUFFER_PRESERVED. Calling this method requires an EGL
+     * config that supports EGL_SWAP_BEHAVIOR_PRESERVED_BIT.
+     *
+     * @return True if the swap behavior was successfully changed,
+     *         false otherwise.
+     */
+    private static native boolean preserveBackBuffer();
+
+    /**
+     * Indicates whether the current surface preserves its back buffer
+     * after a buffer swap.
+     *
+     * @return True, if the surface's EGL_SWAP_BEHAVIOR is EGL_BUFFER_PRESERVED,
+     *         false otherwise
+     */
+    private static native boolean isBackBufferPreserved();
+
+    class DrawPerformanceDataProvider extends GraphDataProvider {
+        private final int mGraphType;
+
+        private int mVerticalUnit;
+        private int mHorizontalUnit;
+        private int mHorizontalMargin;
+        private int mThresholdStroke;
+
+        DrawPerformanceDataProvider(int graphType) {
+            mGraphType = graphType;
+        }
+
+        @Override
+        void prepare(DisplayMetrics metrics) {
+            final float density = metrics.density;
+
+            mVerticalUnit = dpToPx(PROFILE_DRAW_DP_PER_MS, density);
+            mHorizontalUnit = dpToPx(PROFILE_DRAW_WIDTH, density);
+            mHorizontalMargin = dpToPx(PROFILE_DRAW_MARGIN, density);
+            mThresholdStroke = dpToPx(PROFILE_DRAW_THRESHOLD_STROKE_WIDTH, density);
+        }
+
+        @Override
+        int getGraphType() {
+            return mGraphType;
+        }
+
+        @Override
+        int getVerticalUnitSize() {
+            return mVerticalUnit;
+        }
+
+        @Override
+        int getHorizontalUnitSize() {
+            return mHorizontalUnit;
+        }
+
+        @Override
+        int getHorizontaUnitMargin() {
+            return mHorizontalMargin;
+        }
+
+        @Override
+        float[] getData() {
+            return mProfileData;
+        }
+
+        @Override
+        float getThreshold() {
+            return 16;
+        }
+
+        @Override
+        int getFrameCount() {
+            return mProfileData.length / PROFILE_FRAME_DATA_COUNT;
+        }
+
+        @Override
+        int getElementCount() {
+            return PROFILE_FRAME_DATA_COUNT;
+        }
+
+        @Override
+        int getCurrentFrame() {
+            return mProfileCurrentFrame / PROFILE_FRAME_DATA_COUNT;
+        }
+
+        @Override
+        void setupGraphPaint(Paint paint, int elementIndex) {
+            paint.setColor(PROFILE_DRAW_COLORS[elementIndex]);
+            if (mGraphType == GRAPH_TYPE_LINES) paint.setStrokeWidth(mThresholdStroke);
+        }
+
+        @Override
+        void setupThresholdPaint(Paint paint) {
+            paint.setColor(PROFILE_DRAW_THRESHOLD_COLOR);
+            paint.setStrokeWidth(mThresholdStroke);
+        }
+
+        @Override
+        void setupCurrentFramePaint(Paint paint) {
+            paint.setColor(PROFILE_DRAW_CURRENT_FRAME_COLOR);
+            if (mGraphType == GRAPH_TYPE_LINES) paint.setStrokeWidth(mThresholdStroke);
+        }
+    }
+}
diff --git a/core/java/android/view/Gravity.java b/core/java/android/view/Gravity.java
index 9a89fa5..324a1ae 100644
--- a/core/java/android/view/Gravity.java
+++ b/core/java/android/view/Gravity.java
@@ -123,7 +123,7 @@
     public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = START | END;
 
     /**
-     * Apply a gravity constant to an object. This suppose that the layout direction is LTR.
+     * Apply a gravity constant to an object. This supposes that the layout direction is LTR.
      * 
      * @param gravity The desired placement of the object, as defined by the
      *                constants in this class.
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java
index 8f40260..26f47f9 100644
--- a/core/java/android/view/HapticFeedbackConstants.java
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -41,6 +41,11 @@
     public static final int KEYBOARD_TAP = 3;
 
     /**
+     * The user has pressed either an hour or minute tick of a Clock.
+     */
+    public static final int CLOCK_TICK = 4;
+
+    /**
      * This is a private constant.  Feel free to renumber as desired.
      * @hide
      */
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index f215189..5c0be4a 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -16,41 +16,14 @@
 
 package android.view;
 
-import android.content.ComponentCallbacks2;
-import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
-import android.opengl.EGL14;
-import android.opengl.GLUtils;
-import android.opengl.ManagedEGLContext;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.Trace;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.view.Surface.OutOfResourcesException;
 
-import com.google.android.gles_jni.EGLImpl;
-
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGL11;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-import javax.microedition.khronos.egl.EGLSurface;
-import javax.microedition.khronos.opengles.GL;
-
 import java.io.File;
 import java.io.PrintWriter;
-import java.util.concurrent.locks.ReentrantLock;
-
-import static javax.microedition.khronos.egl.EGL10.*;
 
 /**
  * Interface for rendering a view hierarchy using hardware acceleration.
@@ -66,13 +39,6 @@
     private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
 
     /**
-     * Turn on to only refresh the parts of the screen that need updating.
-     * When turned on the property defined by {@link #RENDER_DIRTY_REGIONS_PROPERTY}
-     * must also have the value "true".
-     */
-    static final boolean RENDER_DIRTY_REGIONS = true;
-
-    /**
      * System property used to enable or disable dirty regions invalidation.
      * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true.
      * The default value of this property is assumed to be true.
@@ -222,16 +188,6 @@
      */
     public static boolean sSystemRendererDisabled = false;
 
-    /**
-     * Number of frames to profile.
-     */
-    private static final int PROFILE_MAX_FRAMES = 128;
-
-    /**
-     * Number of floats per profiled frame.
-     */
-    private static final int PROFILE_FRAME_DATA_COUNT = 3;
-
     private boolean mEnabled;
     private boolean mRequested = true;
 
@@ -381,8 +337,6 @@
      */
     abstract boolean loadSystemProperties(Surface surface);
 
-    private static native boolean nLoadProperties();
-
     /**
      * Sets the directory to use as a persistent storage for hardware rendering
      * resources.
@@ -392,60 +346,9 @@
      * @hide
      */
     public static void setupDiskCache(File cacheDir) {
-        nSetupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
+        GLRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
     }
 
-    private static native void nSetupShadersDiskCache(String cacheFile);
-
-    /**
-     * Notifies EGL that the frame is about to be rendered.
-     * @param size
-     */
-    static void beginFrame(int[] size) {
-        nBeginFrame(size);
-    }
-
-    private static native void nBeginFrame(int[] size);
-
-    /**
-     * Returns the current system time according to the renderer.
-     * This method is used for debugging only and should not be used
-     * as a clock.
-     */
-    static long getSystemTime() {
-        return nGetSystemTime();
-    }
-
-    private static native long nGetSystemTime();
-
-    /**
-     * Preserves the back buffer of the current surface after a buffer swap.
-     * Calling this method sets the EGL_SWAP_BEHAVIOR attribute of the current
-     * surface to EGL_BUFFER_PRESERVED. Calling this method requires an EGL
-     * config that supports EGL_SWAP_BEHAVIOR_PRESERVED_BIT.
-     *
-     * @return True if the swap behavior was successfully changed,
-     *         false otherwise.
-     */
-    static boolean preserveBackBuffer() {
-        return nPreserveBackBuffer();
-    }
-
-    private static native boolean nPreserveBackBuffer();
-
-    /**
-     * Indicates whether the current surface preserves its back buffer
-     * after a buffer swap.
-     *
-     * @return True, if the surface's EGL_SWAP_BEHAVIOR is EGL_BUFFER_PRESERVED,
-     *         false otherwise
-     */
-    static boolean isBackBufferPreserved() {
-        return nIsBackBufferPreserved();
-    }
-
-    private static native boolean nIsBackBufferPreserved();
-
     /**
      * Indicates that the specified hardware layer needs to be updated
      * as soon as possible.
@@ -509,18 +412,6 @@
             Rect dirty);
 
     /**
-     * Creates a new display list that can be used to record batches of
-     * drawing operations.
-     *
-     * @param name The name of the display list, used for debugging purpose. May be null.
-     *
-     * @return A new display list.
-     *
-     * @hide
-     */
-    public abstract DisplayList createDisplayList(String name);
-
-    /**
      * Creates a new hardware layer. A hardware layer built by calling this
      * method will be treated as a texture layer, instead of as a render target.
      *
@@ -621,17 +512,15 @@
     /**
      * Creates a hardware renderer using OpenGL.
      *
-     * @param glVersion The version of OpenGL to use (1 for OpenGL 1, 11 for OpenGL 1.1, etc.)
      * @param translucent True if the surface is translucent, false otherwise
      *
      * @return A hardware renderer backed by OpenGL.
      */
-    static HardwareRenderer createGlRenderer(int glVersion, boolean translucent) {
-        switch (glVersion) {
-            case 2:
-                return Gl20Renderer.create(translucent);
+    static HardwareRenderer create(boolean translucent) {
+        if (GLES20Canvas.isAvailable()) {
+            return new GLRenderer(translucent);
         }
-        throw new IllegalArgumentException("Unknown GL version: " + glVersion);
+        return null;
     }
 
     /**
@@ -656,7 +545,7 @@
      *              see {@link android.content.ComponentCallbacks}
      */
     static void startTrimMemory(int level) {
-        Gl20Renderer.startTrimMemory(level);
+        GLRenderer.startTrimMemory(level);
     }
 
     /**
@@ -664,7 +553,7 @@
      * cleanup special resources used by the memory trimming process.
      */
     static void endTrimMemory() {
-        Gl20Renderer.endTrimMemory();
+        GLRenderer.endTrimMemory();
     }
 
     /**
@@ -798,1553 +687,4 @@
          */
         abstract void setupCurrentFramePaint(Paint paint);
     }
-
-    @SuppressWarnings({"deprecation"})
-    static abstract class GlRenderer extends HardwareRenderer {
-        static final int SURFACE_STATE_ERROR = 0;
-        static final int SURFACE_STATE_SUCCESS = 1;
-        static final int SURFACE_STATE_UPDATED = 2;
-
-        static final int FUNCTOR_PROCESS_DELAY = 4;
-
-        private static final int PROFILE_DRAW_MARGIN = 0;
-        private static final int PROFILE_DRAW_WIDTH = 3;
-        private static final int[] PROFILE_DRAW_COLORS = { 0xcf3e66cc, 0xcfdc3912, 0xcfe69800 };
-        private static final int PROFILE_DRAW_CURRENT_FRAME_COLOR = 0xcf5faa4d;
-        private static final int PROFILE_DRAW_THRESHOLD_COLOR = 0xff5faa4d;
-        private static final int PROFILE_DRAW_THRESHOLD_STROKE_WIDTH = 2;
-        private static final int PROFILE_DRAW_DP_PER_MS = 7;
-
-        private static final String[] VISUALIZERS = {
-                PROFILE_PROPERTY_VISUALIZE_BARS,
-                PROFILE_PROPERTY_VISUALIZE_LINES
-        };
-
-        private static final String[] OVERDRAW = {
-                OVERDRAW_PROPERTY_SHOW,
-                OVERDRAW_PROPERTY_COUNT
-        };
-        private static final int OVERDRAW_TYPE_COUNT = 1;
-
-        static EGL10 sEgl;
-        static EGLDisplay sEglDisplay;
-        static EGLConfig sEglConfig;
-        static final Object[] sEglLock = new Object[0];
-        int mWidth = -1, mHeight = -1;
-
-        static final ThreadLocal<ManagedEGLContext> sEglContextStorage
-                = new ThreadLocal<ManagedEGLContext>();
-
-        EGLContext mEglContext;
-        Thread mEglThread;
-
-        EGLSurface mEglSurface;
-
-        GL mGl;
-        HardwareCanvas mCanvas;
-
-        String mName;
-
-        long mFrameCount;
-        Paint mDebugPaint;
-
-        static boolean sDirtyRegions;
-        static final boolean sDirtyRegionsRequested;
-        static {
-            String dirtyProperty = SystemProperties.get(RENDER_DIRTY_REGIONS_PROPERTY, "true");
-            //noinspection PointlessBooleanExpression,ConstantConditions
-            sDirtyRegions = RENDER_DIRTY_REGIONS && "true".equalsIgnoreCase(dirtyProperty);
-            sDirtyRegionsRequested = sDirtyRegions;
-        }
-
-        boolean mDirtyRegionsEnabled;
-        boolean mUpdateDirtyRegions;
-
-        boolean mProfileEnabled;
-        int mProfileVisualizerType = -1;
-        float[] mProfileData;
-        ReentrantLock mProfileLock;
-        int mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
-
-        GraphDataProvider mDebugDataProvider;
-        float[][] mProfileShapes;
-        Paint mProfilePaint;
-
-        boolean mDebugDirtyRegions;
-        int mDebugOverdraw = -1;
-        HardwareLayer mDebugOverdrawLayer;
-        Paint mDebugOverdrawPaint;
-
-        final int mGlVersion;
-        final boolean mTranslucent;
-
-        private boolean mDestroyed;
-
-        private final Rect mRedrawClip = new Rect();
-
-        private final int[] mSurfaceSize = new int[2];
-        private final FunctorsRunnable mFunctorsRunnable = new FunctorsRunnable();
-
-        private long mDrawDelta = Long.MAX_VALUE;
-
-        GlRenderer(int glVersion, boolean translucent) {
-            mGlVersion = glVersion;
-            mTranslucent = translucent;
-
-            loadSystemProperties(null);
-        }
-
-        @Override
-        boolean loadSystemProperties(Surface surface) {
-            boolean value;
-            boolean changed = false;
-
-            String profiling = SystemProperties.get(PROFILE_PROPERTY);
-            int graphType = search(VISUALIZERS, profiling);
-            value = graphType >= 0;
-
-            if (graphType != mProfileVisualizerType) {
-                changed = true;
-                mProfileVisualizerType = graphType;
-
-                mProfileShapes = null;
-                mProfilePaint = null;
-
-                if (value) {
-                    mDebugDataProvider = new DrawPerformanceDataProvider(graphType);
-                } else {
-                    mDebugDataProvider = null;
-                }
-            }
-
-            // If on-screen profiling is not enabled, we need to check whether
-            // console profiling only is enabled
-            if (!value) {
-                value = Boolean.parseBoolean(profiling);
-            }
-
-            if (value != mProfileEnabled) {
-                changed = true;
-                mProfileEnabled = value;
-
-                if (mProfileEnabled) {
-                    Log.d(LOG_TAG, "Profiling hardware renderer");
-
-                    int maxProfileFrames = SystemProperties.getInt(PROFILE_MAXFRAMES_PROPERTY,
-                            PROFILE_MAX_FRAMES);
-                    mProfileData = new float[maxProfileFrames * PROFILE_FRAME_DATA_COUNT];
-                    for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
-                        mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
-                    }
-
-                    mProfileLock = new ReentrantLock();
-                } else {
-                    mProfileData = null;
-                    mProfileLock = null;
-                    mProfileVisualizerType = -1;
-                }
-
-                mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
-            }
-
-            value = SystemProperties.getBoolean(DEBUG_DIRTY_REGIONS_PROPERTY, false);
-            if (value != mDebugDirtyRegions) {
-                changed = true;
-                mDebugDirtyRegions = value;
-
-                if (mDebugDirtyRegions) {
-                    Log.d(LOG_TAG, "Debugging dirty regions");
-                }
-            }
-
-            String overdraw = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
-            int debugOverdraw = search(OVERDRAW, overdraw);
-            if (debugOverdraw != mDebugOverdraw) {
-                changed = true;
-                mDebugOverdraw = debugOverdraw;
-
-                if (mDebugOverdraw != OVERDRAW_TYPE_COUNT) {
-                    if (mDebugOverdrawLayer != null) {
-                        mDebugOverdrawLayer.destroy();
-                        mDebugOverdrawLayer = null;
-                        mDebugOverdrawPaint = null;
-                    }
-                }
-            }
-
-            if (nLoadProperties()) {
-                changed = true;
-            }
-
-            return changed;
-        }
-
-        private static int search(String[] values, String value) {
-            for (int i = 0; i < values.length; i++) {
-                if (values[i].equals(value)) return i;
-            }
-            return -1;
-        }
-
-        @Override
-        void dumpGfxInfo(PrintWriter pw) {
-            if (mProfileEnabled) {
-                pw.printf("\n\tDraw\tProcess\tExecute\n");
-
-                mProfileLock.lock();
-                try {
-                    for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
-                        if (mProfileData[i] < 0) {
-                            break;
-                        }
-                        pw.printf("\t%3.2f\t%3.2f\t%3.2f\n", mProfileData[i], mProfileData[i + 1],
-                                mProfileData[i + 2]);
-                        mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
-                    }
-                    mProfileCurrentFrame = mProfileData.length;
-                } finally {
-                    mProfileLock.unlock();
-                }
-            }
-        }
-
-        @Override
-        long getFrameCount() {
-            return mFrameCount;
-        }
-
-        /**
-         * Indicates whether this renderer instance can track and update dirty regions.
-         */
-        boolean hasDirtyRegions() {
-            return mDirtyRegionsEnabled;
-        }
-
-        /**
-         * Checks for OpenGL errors. If an error has occured, {@link #destroy(boolean)}
-         * is invoked and the requested flag is turned off. The error code is
-         * also logged as a warning.
-         */
-        void checkEglErrors() {
-            if (isEnabled()) {
-                checkEglErrorsForced();
-            }
-        }
-
-        private void checkEglErrorsForced() {
-            int error = sEgl.eglGetError();
-            if (error != EGL_SUCCESS) {
-                // something bad has happened revert to
-                // normal rendering.
-                Log.w(LOG_TAG, "EGL error: " + GLUtils.getEGLErrorString(error));
-                fallback(error != EGL11.EGL_CONTEXT_LOST);
-            }
-        }
-
-        private void fallback(boolean fallback) {
-            destroy(true);
-            if (fallback) {
-                // we'll try again if it was context lost
-                setRequested(false);
-                Log.w(LOG_TAG, "Mountain View, we've had a problem here. "
-                        + "Switching back to software rendering.");
-            }
-        }
-
-        @Override
-        boolean initialize(Surface surface) throws OutOfResourcesException {
-            if (isRequested() && !isEnabled()) {
-                boolean contextCreated = initializeEgl();
-                mGl = createEglSurface(surface);
-                mDestroyed = false;
-
-                if (mGl != null) {
-                    int err = sEgl.eglGetError();
-                    if (err != EGL_SUCCESS) {
-                        destroy(true);
-                        setRequested(false);
-                    } else {
-                        if (mCanvas == null) {
-                            mCanvas = createCanvas();
-                            mCanvas.setName(mName);
-                        }
-                        setEnabled(true);
-
-                        if (contextCreated) {
-                            initAtlas();
-                        }
-                    }
-
-                    return mCanvas != null;
-                }
-            }
-            return false;
-        }
-
-        @Override
-        void updateSurface(Surface surface) throws OutOfResourcesException {
-            if (isRequested() && isEnabled()) {
-                createEglSurface(surface);
-            }
-        }
-
-        abstract HardwareCanvas createCanvas();
-
-        abstract int[] getConfig(boolean dirtyRegions);
-
-        boolean initializeEgl() {
-            synchronized (sEglLock) {
-                if (sEgl == null && sEglConfig == null) {
-                    sEgl = (EGL10) EGLContext.getEGL();
-
-                    // Get to the default display.
-                    sEglDisplay = sEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
-
-                    if (sEglDisplay == EGL_NO_DISPLAY) {
-                        throw new RuntimeException("eglGetDisplay failed "
-                                + GLUtils.getEGLErrorString(sEgl.eglGetError()));
-                    }
-
-                    // We can now initialize EGL for that display
-                    int[] version = new int[2];
-                    if (!sEgl.eglInitialize(sEglDisplay, version)) {
-                        throw new RuntimeException("eglInitialize failed " +
-                                GLUtils.getEGLErrorString(sEgl.eglGetError()));
-                    }
-
-                    checkEglErrorsForced();
-
-                    sEglConfig = loadEglConfig();
-                }
-            }
-
-            ManagedEGLContext managedContext = sEglContextStorage.get();
-            mEglContext = managedContext != null ? managedContext.getContext() : null;
-            mEglThread = Thread.currentThread();
-
-            if (mEglContext == null) {
-                mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
-                sEglContextStorage.set(createManagedContext(mEglContext));
-                return true;
-            }
-
-            return false;
-        }
-
-        private EGLConfig loadEglConfig() {
-            EGLConfig eglConfig = chooseEglConfig();
-            if (eglConfig == null) {
-                // We tried to use EGL_SWAP_BEHAVIOR_PRESERVED_BIT, try again without
-                if (sDirtyRegions) {
-                    sDirtyRegions = false;
-                    eglConfig = chooseEglConfig();
-                    if (eglConfig == null) {
-                        throw new RuntimeException("eglConfig not initialized");
-                    }
-                } else {
-                    throw new RuntimeException("eglConfig not initialized");
-                }
-            }
-            return eglConfig;
-        }
-
-        abstract ManagedEGLContext createManagedContext(EGLContext eglContext);
-
-        private EGLConfig chooseEglConfig() {
-            EGLConfig[] configs = new EGLConfig[1];
-            int[] configsCount = new int[1];
-            int[] configSpec = getConfig(sDirtyRegions);
-
-            // Debug
-            final String debug = SystemProperties.get(PRINT_CONFIG_PROPERTY, "");
-            if ("all".equalsIgnoreCase(debug)) {
-                sEgl.eglChooseConfig(sEglDisplay, configSpec, null, 0, configsCount);
-
-                EGLConfig[] debugConfigs = new EGLConfig[configsCount[0]];
-                sEgl.eglChooseConfig(sEglDisplay, configSpec, debugConfigs,
-                        configsCount[0], configsCount);
-
-                for (EGLConfig config : debugConfigs) {
-                    printConfig(config);
-                }
-            }
-
-            if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) {
-                throw new IllegalArgumentException("eglChooseConfig failed " +
-                        GLUtils.getEGLErrorString(sEgl.eglGetError()));
-            } else if (configsCount[0] > 0) {
-                if ("choice".equalsIgnoreCase(debug)) {
-                    printConfig(configs[0]);
-                }
-                return configs[0];
-            }
-
-            return null;
-        }
-
-        private static void printConfig(EGLConfig config) {
-            int[] value = new int[1];
-
-            Log.d(LOG_TAG, "EGL configuration " + config + ":");
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_RED_SIZE, value);
-            Log.d(LOG_TAG, "  RED_SIZE = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_GREEN_SIZE, value);
-            Log.d(LOG_TAG, "  GREEN_SIZE = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_BLUE_SIZE, value);
-            Log.d(LOG_TAG, "  BLUE_SIZE = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_ALPHA_SIZE, value);
-            Log.d(LOG_TAG, "  ALPHA_SIZE = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_DEPTH_SIZE, value);
-            Log.d(LOG_TAG, "  DEPTH_SIZE = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_STENCIL_SIZE, value);
-            Log.d(LOG_TAG, "  STENCIL_SIZE = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLE_BUFFERS, value);
-            Log.d(LOG_TAG, "  SAMPLE_BUFFERS = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLES, value);
-            Log.d(LOG_TAG, "  SAMPLES = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SURFACE_TYPE, value);
-            Log.d(LOG_TAG, "  SURFACE_TYPE = 0x" + Integer.toHexString(value[0]));
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_CONFIG_CAVEAT, value);
-            Log.d(LOG_TAG, "  CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0]));
-        }
-
-        GL createEglSurface(Surface surface) throws OutOfResourcesException {
-            // Check preconditions.
-            if (sEgl == null) {
-                throw new RuntimeException("egl not initialized");
-            }
-            if (sEglDisplay == null) {
-                throw new RuntimeException("eglDisplay not initialized");
-            }
-            if (sEglConfig == null) {
-                throw new RuntimeException("eglConfig not initialized");
-            }
-            if (Thread.currentThread() != mEglThread) {
-                throw new IllegalStateException("HardwareRenderer cannot be used "
-                        + "from multiple threads");
-            }
-
-            // In case we need to destroy an existing surface
-            destroySurface();
-
-            // Create an EGL surface we can render into.
-            if (!createSurface(surface)) {
-                return null;
-            }
-
-            initCaches();
-
-            return mEglContext.getGL();
-        }
-
-        private void enableDirtyRegions() {
-            // If mDirtyRegions is set, this means we have an EGL configuration
-            // with EGL_SWAP_BEHAVIOR_PRESERVED_BIT set
-            if (sDirtyRegions) {
-                if (!(mDirtyRegionsEnabled = preserveBackBuffer())) {
-                    Log.w(LOG_TAG, "Backbuffer cannot be preserved");
-                }
-            } else if (sDirtyRegionsRequested) {
-                // If mDirtyRegions is not set, our EGL configuration does not
-                // have EGL_SWAP_BEHAVIOR_PRESERVED_BIT; however, the default
-                // swap behavior might be EGL_BUFFER_PRESERVED, which means we
-                // want to set mDirtyRegions. We try to do this only if dirty
-                // regions were initially requested as part of the device
-                // configuration (see RENDER_DIRTY_REGIONS)
-                mDirtyRegionsEnabled = isBackBufferPreserved();
-            }
-        }
-
-        abstract void initCaches();
-        abstract void initAtlas();
-
-        EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
-            int[] attribs = { EGL14.EGL_CONTEXT_CLIENT_VERSION, mGlVersion, EGL_NONE };
-
-            EGLContext context = egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT,
-                    mGlVersion != 0 ? attribs : null);
-            if (context == null || context == EGL_NO_CONTEXT) {
-                //noinspection ConstantConditions
-                throw new IllegalStateException(
-                        "Could not create an EGL context. eglCreateContext failed with error: " +
-                        GLUtils.getEGLErrorString(sEgl.eglGetError()));
-            }
-
-            return context;
-        }
-
-        @Override
-        void destroy(boolean full) {
-            if (full && mCanvas != null) {
-                mCanvas = null;
-            }
-
-            if (!isEnabled() || mDestroyed) {
-                setEnabled(false);
-                return;
-            }
-
-            destroySurface();
-            setEnabled(false);
-
-            mDestroyed = true;
-            mGl = null;
-        }
-
-        void destroySurface() {
-            if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
-                if (mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW))) {
-                    sEgl.eglMakeCurrent(sEglDisplay,
-                            EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-                }
-                sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
-                mEglSurface = null;
-            }
-        }
-
-        @Override
-        void invalidate(Surface surface) {
-            // Cancels any existing buffer to ensure we'll get a buffer
-            // of the right size before we call eglSwapBuffers
-            sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-            if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
-                sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
-                mEglSurface = null;
-                setEnabled(false);
-            }
-
-            if (surface.isValid()) {
-                if (!createSurface(surface)) {
-                    return;
-                }
-
-                mUpdateDirtyRegions = true;
-
-                if (mCanvas != null) {
-                    setEnabled(true);
-                }
-            }
-        }
-
-        private boolean createSurface(Surface surface) {
-            mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, surface, null);
-
-            if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
-                int error = sEgl.eglGetError();
-                if (error == EGL_BAD_NATIVE_WINDOW) {
-                    Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
-                    return false;
-                }
-                throw new RuntimeException("createWindowSurface failed "
-                        + GLUtils.getEGLErrorString(error));
-            }
-
-            if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
-                throw new IllegalStateException("eglMakeCurrent failed " +
-                        GLUtils.getEGLErrorString(sEgl.eglGetError()));
-            }
-
-            enableDirtyRegions();
-
-            return true;
-        }
-
-        @Override
-        boolean validate() {
-            return checkRenderContext() != SURFACE_STATE_ERROR;
-        }
-
-        @Override
-        void setup(int width, int height) {
-            if (validate()) {
-                mCanvas.setViewport(width, height);
-                mWidth = width;
-                mHeight = height;
-            }
-        }
-
-        @Override
-        int getWidth() {
-            return mWidth;
-        }
-
-        @Override
-        int getHeight() {
-            return mHeight;
-        }
-
-        @Override
-        HardwareCanvas getCanvas() {
-            return mCanvas;
-        }
-
-        @Override
-        void setName(String name) {
-            mName = name;
-        }
-
-        boolean canDraw() {
-            return mGl != null && mCanvas != null;
-        }
-
-        int onPreDraw(Rect dirty) {
-            return DisplayList.STATUS_DONE;
-        }
-
-        void onPostDraw() {
-        }
-
-        class FunctorsRunnable implements Runnable {
-            View.AttachInfo attachInfo;
-
-            @Override
-            public void run() {
-                final HardwareRenderer renderer = attachInfo.mHardwareRenderer;
-                if (renderer == null || !renderer.isEnabled() || renderer != GlRenderer.this) {
-                    return;
-                }
-
-                if (checkRenderContext() != SURFACE_STATE_ERROR) {
-                    int status = mCanvas.invokeFunctors(mRedrawClip);
-                    handleFunctorStatus(attachInfo, status);
-                }
-            }
-        }
-
-        @Override
-        void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
-                Rect dirty) {
-            if (canDraw()) {
-                if (!hasDirtyRegions()) {
-                    dirty = null;
-                }
-                attachInfo.mIgnoreDirtyState = true;
-                attachInfo.mDrawingTime = SystemClock.uptimeMillis();
-
-                view.mPrivateFlags |= View.PFLAG_DRAWN;
-
-                // We are already on the correct thread
-                final int surfaceState = checkRenderContextUnsafe();
-                if (surfaceState != SURFACE_STATE_ERROR) {
-                    HardwareCanvas canvas = mCanvas;
-                    attachInfo.mHardwareCanvas = canvas;
-
-                    if (mProfileEnabled) {
-                        mProfileLock.lock();
-                    }
-
-                    dirty = beginFrame(canvas, dirty, surfaceState);
-
-                    DisplayList displayList = buildDisplayList(view, canvas);
-
-                    // buildDisplayList() calls into user code which can cause
-                    // an eglMakeCurrent to happen with a different surface/context.
-                    // We must therefore check again here.
-                    if (checkRenderContextUnsafe() == SURFACE_STATE_ERROR) {
-                        return;
-                    }
-
-                    int saveCount = 0;
-                    int status = DisplayList.STATUS_DONE;
-
-                    long start = getSystemTime();
-                    try {
-                        status = prepareFrame(dirty);
-
-                        saveCount = canvas.save();
-                        callbacks.onHardwarePreDraw(canvas);
-
-                        if (displayList != null) {
-                            status |= drawDisplayList(attachInfo, canvas, displayList, status);
-                        } else {
-                            // Shouldn't reach here
-                            view.draw(canvas);
-                        }
-                    } catch (Exception e) {
-                        Log.e(LOG_TAG, "An error has occurred while drawing:", e);
-                    } finally {
-                        callbacks.onHardwarePostDraw(canvas);
-                        canvas.restoreToCount(saveCount);
-                        view.mRecreateDisplayList = false;
-
-                        mDrawDelta = getSystemTime() - start;
-
-                        if (mDrawDelta > 0) {
-                            mFrameCount++;
-
-                            debugOverdraw(attachInfo, dirty, canvas, displayList);
-                            debugDirtyRegions(dirty, canvas);
-                            drawProfileData(attachInfo);
-                        }
-                    }
-
-                    onPostDraw();
-
-                    swapBuffers(status);
-
-                    if (mProfileEnabled) {
-                        mProfileLock.unlock();
-                    }
-
-                    attachInfo.mIgnoreDirtyState = false;
-                }
-            }
-        }
-
-        abstract void countOverdraw(HardwareCanvas canvas);
-        abstract float getOverdraw(HardwareCanvas canvas);
-
-        private void debugOverdraw(View.AttachInfo attachInfo, Rect dirty,
-                HardwareCanvas canvas, DisplayList displayList) {
-
-            if (mDebugOverdraw == OVERDRAW_TYPE_COUNT) {
-                if (mDebugOverdrawLayer == null) {
-                    mDebugOverdrawLayer = createHardwareLayer(mWidth, mHeight, true);
-                } else if (mDebugOverdrawLayer.getWidth() != mWidth ||
-                        mDebugOverdrawLayer.getHeight() != mHeight) {
-                    mDebugOverdrawLayer.resize(mWidth, mHeight);
-                }
-
-                if (!mDebugOverdrawLayer.isValid()) {
-                    mDebugOverdraw = -1;
-                    return;
-                }
-
-                HardwareCanvas layerCanvas = mDebugOverdrawLayer.start(canvas, dirty);
-                countOverdraw(layerCanvas);
-                final int restoreCount = layerCanvas.save();
-                layerCanvas.drawDisplayList(displayList, null, DisplayList.FLAG_CLIP_CHILDREN);
-                layerCanvas.restoreToCount(restoreCount);
-                mDebugOverdrawLayer.end(canvas);
-
-                float overdraw = getOverdraw(layerCanvas);
-                DisplayMetrics metrics = attachInfo.mRootView.getResources().getDisplayMetrics();
-
-                drawOverdrawCounter(canvas, overdraw, metrics.density);
-            }
-        }
-
-        private void drawOverdrawCounter(HardwareCanvas canvas, float overdraw, float density) {
-            final String text = String.format("%.2fx", overdraw);
-            final Paint paint = setupPaint(density);
-            // HSBtoColor will clamp the values in the 0..1 range
-            paint.setColor(Color.HSBtoColor(0.28f - 0.28f * overdraw / 3.5f, 0.8f, 1.0f));
-
-            canvas.drawText(text, density * 4.0f, mHeight - paint.getFontMetrics().bottom, paint);
-        }
-
-        private Paint setupPaint(float density) {
-            if (mDebugOverdrawPaint == null) {
-                mDebugOverdrawPaint = new Paint();
-                mDebugOverdrawPaint.setAntiAlias(true);
-                mDebugOverdrawPaint.setShadowLayer(density * 3.0f, 0.0f, 0.0f, 0xff000000);
-                mDebugOverdrawPaint.setTextSize(density * 20.0f);
-            }
-            return mDebugOverdrawPaint;
-        }
-
-        private DisplayList buildDisplayList(View view, HardwareCanvas canvas) {
-            if (mDrawDelta <= 0) {
-                return view.mDisplayList;
-            }
-
-            view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
-                    == View.PFLAG_INVALIDATED;
-            view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
-
-            long buildDisplayListStartTime = startBuildDisplayListProfiling();
-            canvas.clearLayerUpdates();
-
-            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
-            DisplayList displayList = view.getDisplayList();
-            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
-
-            endBuildDisplayListProfiling(buildDisplayListStartTime);
-
-            return displayList;
-        }
-
-        abstract void drawProfileData(View.AttachInfo attachInfo);
-
-        private Rect beginFrame(HardwareCanvas canvas, Rect dirty, int surfaceState) {
-            // We had to change the current surface and/or context, redraw everything
-            if (surfaceState == SURFACE_STATE_UPDATED) {
-                dirty = null;
-                beginFrame(null);
-            } else {
-                int[] size = mSurfaceSize;
-                beginFrame(size);
-
-                if (size[1] != mHeight || size[0] != mWidth) {
-                    mWidth = size[0];
-                    mHeight = size[1];
-
-                    canvas.setViewport(mWidth, mHeight);
-
-                    dirty = null;
-                }
-            }
-
-            if (mDebugDataProvider != null) dirty = null;
-
-            return dirty;
-        }
-
-        private long startBuildDisplayListProfiling() {
-            if (mProfileEnabled) {
-                mProfileCurrentFrame += PROFILE_FRAME_DATA_COUNT;
-                if (mProfileCurrentFrame >= mProfileData.length) {
-                    mProfileCurrentFrame = 0;
-                }
-
-                return System.nanoTime();
-            }
-            return 0;
-        }
-
-        private void endBuildDisplayListProfiling(long getDisplayListStartTime) {
-            if (mProfileEnabled) {
-                long now = System.nanoTime();
-                float total = (now - getDisplayListStartTime) * 0.000001f;
-                //noinspection PointlessArithmeticExpression
-                mProfileData[mProfileCurrentFrame] = total;
-            }
-        }
-
-        private int prepareFrame(Rect dirty) {
-            int status;
-            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "prepareFrame");
-            try {
-                status = onPreDraw(dirty);
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
-            }
-            return status;
-        }
-
-        private int drawDisplayList(View.AttachInfo attachInfo, HardwareCanvas canvas,
-                DisplayList displayList, int status) {
-
-            long drawDisplayListStartTime = 0;
-            if (mProfileEnabled) {
-                drawDisplayListStartTime = System.nanoTime();
-            }
-
-            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList");
-            try {
-                status |= canvas.drawDisplayList(displayList, mRedrawClip,
-                        DisplayList.FLAG_CLIP_CHILDREN);
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
-            }
-
-            if (mProfileEnabled) {
-                long now = System.nanoTime();
-                float total = (now - drawDisplayListStartTime) * 0.000001f;
-                mProfileData[mProfileCurrentFrame + 1] = total;
-            }
-
-            handleFunctorStatus(attachInfo, status);
-            return status;
-        }
-
-        private void swapBuffers(int status) {
-            if ((status & DisplayList.STATUS_DREW) == DisplayList.STATUS_DREW) {
-                long eglSwapBuffersStartTime = 0;
-                if (mProfileEnabled) {
-                    eglSwapBuffersStartTime = System.nanoTime();
-                }
-
-                sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
-
-                if (mProfileEnabled) {
-                    long now = System.nanoTime();
-                    float total = (now - eglSwapBuffersStartTime) * 0.000001f;
-                    mProfileData[mProfileCurrentFrame + 2] = total;
-                }
-
-                checkEglErrors();
-            }
-        }
-
-        private void debugDirtyRegions(Rect dirty, HardwareCanvas canvas) {
-            if (mDebugDirtyRegions) {
-                if (mDebugPaint == null) {
-                    mDebugPaint = new Paint();
-                    mDebugPaint.setColor(0x7fff0000);
-                }
-
-                if (dirty != null && (mFrameCount & 1) == 0) {
-                    canvas.drawRect(dirty, mDebugPaint);
-                }
-            }
-        }
-
-        private void handleFunctorStatus(View.AttachInfo attachInfo, int status) {
-            // If the draw flag is set, functors will be invoked while executing
-            // the tree of display lists
-            if ((status & DisplayList.STATUS_DRAW) != 0) {
-                if (mRedrawClip.isEmpty()) {
-                    attachInfo.mViewRootImpl.invalidate();
-                } else {
-                    attachInfo.mViewRootImpl.invalidateChildInParent(null, mRedrawClip);
-                    mRedrawClip.setEmpty();
-                }
-            }
-
-            if ((status & DisplayList.STATUS_INVOKE) != 0 ||
-                    attachInfo.mHandler.hasCallbacks(mFunctorsRunnable)) {
-                attachInfo.mHandler.removeCallbacks(mFunctorsRunnable);
-                mFunctorsRunnable.attachInfo = attachInfo;
-                attachInfo.mHandler.postDelayed(mFunctorsRunnable, FUNCTOR_PROCESS_DELAY);
-            }
-        }
-
-        @Override
-        void detachFunctor(int functor) {
-            if (mCanvas != null) {
-                mCanvas.detachFunctor(functor);
-            }
-        }
-
-        @Override
-        boolean attachFunctor(View.AttachInfo attachInfo, int functor) {
-            if (mCanvas != null) {
-                mCanvas.attachFunctor(functor);
-                mFunctorsRunnable.attachInfo = attachInfo;
-                attachInfo.mHandler.removeCallbacks(mFunctorsRunnable);
-                attachInfo.mHandler.postDelayed(mFunctorsRunnable,  0);
-                return true;
-            }
-            return false;
-        }
-
-        /**
-         * Ensures the current EGL context and surface are the ones we expect.
-         * This method throws an IllegalStateException if invoked from a thread
-         * that did not initialize EGL.
-         *
-         * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
-         *         {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
-         *         {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
-         *
-         * @see #checkRenderContextUnsafe()
-         */
-        int checkRenderContext() {
-            if (mEglThread != Thread.currentThread()) {
-                throw new IllegalStateException("Hardware acceleration can only be used with a " +
-                        "single UI thread.\nOriginal thread: " + mEglThread + "\n" +
-                        "Current thread: " + Thread.currentThread());
-            }
-
-            return checkRenderContextUnsafe();
-        }
-
-        /**
-         * Ensures the current EGL context and surface are the ones we expect.
-         * This method does not check the current thread.
-         *
-         * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
-         *         {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
-         *         {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
-         *
-         * @see #checkRenderContext()
-         */
-        private int checkRenderContextUnsafe() {
-            if (!mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW)) ||
-                    !mEglContext.equals(sEgl.eglGetCurrentContext())) {
-                if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
-                    Log.e(LOG_TAG, "eglMakeCurrent failed " +
-                            GLUtils.getEGLErrorString(sEgl.eglGetError()));
-                    fallback(true);
-                    return SURFACE_STATE_ERROR;
-                } else {
-                    if (mUpdateDirtyRegions) {
-                        enableDirtyRegions();
-                        mUpdateDirtyRegions = false;
-                    }
-                    return SURFACE_STATE_UPDATED;
-                }
-            }
-            return SURFACE_STATE_SUCCESS;
-        }
-
-        private static int dpToPx(int dp, float density) {
-            return (int) (dp * density + 0.5f);
-        }
-
-        class DrawPerformanceDataProvider extends GraphDataProvider {
-            private final int mGraphType;
-
-            private int mVerticalUnit;
-            private int mHorizontalUnit;
-            private int mHorizontalMargin;
-            private int mThresholdStroke;
-
-            DrawPerformanceDataProvider(int graphType) {
-                mGraphType = graphType;
-            }
-
-            @Override
-            void prepare(DisplayMetrics metrics) {
-                final float density = metrics.density;
-
-                mVerticalUnit = dpToPx(PROFILE_DRAW_DP_PER_MS, density);
-                mHorizontalUnit = dpToPx(PROFILE_DRAW_WIDTH, density);
-                mHorizontalMargin = dpToPx(PROFILE_DRAW_MARGIN, density);
-                mThresholdStroke = dpToPx(PROFILE_DRAW_THRESHOLD_STROKE_WIDTH, density);
-            }
-
-            @Override
-            int getGraphType() {
-                return mGraphType;
-            }
-
-            @Override
-            int getVerticalUnitSize() {
-                return mVerticalUnit;
-            }
-
-            @Override
-            int getHorizontalUnitSize() {
-                return mHorizontalUnit;
-            }
-
-            @Override
-            int getHorizontaUnitMargin() {
-                return mHorizontalMargin;
-            }
-
-            @Override
-            float[] getData() {
-                return mProfileData;
-            }
-
-            @Override
-            float getThreshold() {
-                return 16;
-            }
-
-            @Override
-            int getFrameCount() {
-                return mProfileData.length / PROFILE_FRAME_DATA_COUNT;
-            }
-
-            @Override
-            int getElementCount() {
-                return PROFILE_FRAME_DATA_COUNT;
-            }
-
-            @Override
-            int getCurrentFrame() {
-                return mProfileCurrentFrame / PROFILE_FRAME_DATA_COUNT;
-            }
-
-            @Override
-            void setupGraphPaint(Paint paint, int elementIndex) {
-                paint.setColor(PROFILE_DRAW_COLORS[elementIndex]);
-                if (mGraphType == GRAPH_TYPE_LINES) paint.setStrokeWidth(mThresholdStroke);
-            }
-
-            @Override
-            void setupThresholdPaint(Paint paint) {
-                paint.setColor(PROFILE_DRAW_THRESHOLD_COLOR);
-                paint.setStrokeWidth(mThresholdStroke);
-            }
-
-            @Override
-            void setupCurrentFramePaint(Paint paint) {
-                paint.setColor(PROFILE_DRAW_CURRENT_FRAME_COLOR);
-                if (mGraphType == GRAPH_TYPE_LINES) paint.setStrokeWidth(mThresholdStroke);
-            }
-        }
-    }
-
-    /**
-     * Hardware renderer using OpenGL ES 2.0.
-     */
-    static class Gl20Renderer extends GlRenderer {
-        private GLES20Canvas mGlCanvas;
-
-        private DisplayMetrics mDisplayMetrics;
-
-        private static EGLSurface sPbuffer;
-        private static final Object[] sPbufferLock = new Object[0];
-
-        static class Gl20RendererEglContext extends ManagedEGLContext {
-            final Handler mHandler = new Handler();
-
-            public Gl20RendererEglContext(EGLContext context) {
-                super(context);
-            }
-
-            @Override
-            public void onTerminate(final EGLContext eglContext) {
-                // Make sure we do this on the correct thread.
-                if (mHandler.getLooper() != Looper.myLooper()) {
-                    mHandler.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            onTerminate(eglContext);
-                        }
-                    });
-                    return;
-                }
-
-                synchronized (sEglLock) {
-                    if (sEgl == null) return;
-
-                    if (EGLImpl.getInitCount(sEglDisplay) == 1) {
-                        usePbufferSurface(eglContext);
-                        GLES20Canvas.terminateCaches();
-
-                        sEgl.eglDestroyContext(sEglDisplay, eglContext);
-                        sEglContextStorage.set(null);
-                        sEglContextStorage.remove();
-
-                        sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
-                        sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
-                                EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-                        sEgl.eglReleaseThread();
-                        sEgl.eglTerminate(sEglDisplay);
-
-                        sEgl = null;
-                        sEglDisplay = null;
-                        sEglConfig = null;
-                        sPbuffer = null;
-                    }
-                }
-            }
-        }
-
-        Gl20Renderer(boolean translucent) {
-            super(2, translucent);
-        }
-
-        @Override
-        HardwareCanvas createCanvas() {
-            return mGlCanvas = new GLES20Canvas(mTranslucent);
-        }
-
-        @Override
-        ManagedEGLContext createManagedContext(EGLContext eglContext) {
-            return new Gl20Renderer.Gl20RendererEglContext(mEglContext);
-        }
-
-        @Override
-        int[] getConfig(boolean dirtyRegions) {
-            //noinspection PointlessBooleanExpression,ConstantConditions
-            final int stencilSize = GLES20Canvas.getStencilSize();
-            final int swapBehavior = dirtyRegions ? EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
-
-            return new int[] {
-                    EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
-                    EGL_RED_SIZE, 8,
-                    EGL_GREEN_SIZE, 8,
-                    EGL_BLUE_SIZE, 8,
-                    EGL_ALPHA_SIZE, 8,
-                    EGL_DEPTH_SIZE, 0,
-                    EGL_CONFIG_CAVEAT, EGL_NONE,
-                    EGL_STENCIL_SIZE, stencilSize,
-                    EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior,
-                    EGL_NONE
-            };
-        }
-
-        @Override
-        void initCaches() {
-            if (GLES20Canvas.initCaches()) {
-                // Caches were (re)initialized, rebind atlas
-                initAtlas();
-            }
-        }
-
-        @Override
-        void initAtlas() {
-            IBinder binder = ServiceManager.getService("assetatlas");
-            if (binder == null) return;
-
-            IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
-            try {
-                if (atlas.isCompatible(android.os.Process.myPpid())) {
-                    GraphicBuffer buffer = atlas.getBuffer();
-                    if (buffer != null) {
-                        int[] map = atlas.getMap();
-                        if (map != null) {
-                            GLES20Canvas.initAtlas(buffer, map);
-                        }
-                        // If IAssetAtlas is not the same class as the IBinder
-                        // we are using a remote service and we can safely
-                        // destroy the graphic buffer
-                        if (atlas.getClass() != binder.getClass()) {
-                            buffer.destroy();
-                        }
-                    }
-                }
-            } catch (RemoteException e) {
-                Log.w(LOG_TAG, "Could not acquire atlas", e);
-            }
-        }
-
-        @Override
-        boolean canDraw() {
-            return super.canDraw() && mGlCanvas != null;
-        }
-
-        @Override
-        int onPreDraw(Rect dirty) {
-            return mGlCanvas.onPreDraw(dirty);
-        }
-
-        @Override
-        void onPostDraw() {
-            mGlCanvas.onPostDraw();
-        }
-
-        @Override
-        void drawProfileData(View.AttachInfo attachInfo) {
-            if (mDebugDataProvider != null) {
-                final GraphDataProvider provider = mDebugDataProvider;
-                initProfileDrawData(attachInfo, provider);
-
-                final int height = provider.getVerticalUnitSize();
-                final int margin = provider.getHorizontaUnitMargin();
-                final int width = provider.getHorizontalUnitSize();
-
-                int x = 0;
-                int count = 0;
-                int current = 0;
-
-                final float[] data = provider.getData();
-                final int elementCount = provider.getElementCount();
-                final int graphType = provider.getGraphType();
-
-                int totalCount = provider.getFrameCount() * elementCount;
-                if (graphType == GraphDataProvider.GRAPH_TYPE_LINES) {
-                    totalCount -= elementCount;
-                }
-
-                for (int i = 0; i < totalCount; i += elementCount) {
-                    if (data[i] < 0.0f) break;
-
-                    int index = count * 4;
-                    if (i == provider.getCurrentFrame() * elementCount) current = index;
-
-                    x += margin;
-                    int x2 = x + width;
-
-                    int y2 = mHeight;
-                    int y1 = (int) (y2 - data[i] * height);
-
-                    switch (graphType) {
-                        case GraphDataProvider.GRAPH_TYPE_BARS: {
-                            for (int j = 0; j < elementCount; j++) {
-                                //noinspection MismatchedReadAndWriteOfArray
-                                final float[] r = mProfileShapes[j];
-                                r[index] = x;
-                                r[index + 1] = y1;
-                                r[index + 2] = x2;
-                                r[index + 3] = y2;
-
-                                y2 = y1;
-                                if (j < elementCount - 1) {
-                                    y1 = (int) (y2 - data[i + j + 1] * height);
-                                }
-                            }
-                        } break;
-                        case GraphDataProvider.GRAPH_TYPE_LINES: {
-                            for (int j = 0; j < elementCount; j++) {
-                                //noinspection MismatchedReadAndWriteOfArray
-                                final float[] r = mProfileShapes[j];
-                                r[index] = (x + x2) * 0.5f;
-                                r[index + 1] = index == 0 ? y1 : r[index - 1];
-                                r[index + 2] = r[index] + width;
-                                r[index + 3] = y1;
-
-                                y2 = y1;
-                                if (j < elementCount - 1) {
-                                    y1 = (int) (y2 - data[i + j + 1] * height);
-                                }
-                            }
-                        } break;
-                    }
-
-
-                    x += width;
-                    count++;
-                }
-
-                x += margin;
-
-                drawGraph(graphType, count);
-                drawCurrentFrame(graphType, current);
-                drawThreshold(x, height);
-            }
-        }
-
-        private void drawGraph(int graphType, int count) {
-            for (int i = 0; i < mProfileShapes.length; i++) {
-                mDebugDataProvider.setupGraphPaint(mProfilePaint, i);
-                switch (graphType) {
-                    case GraphDataProvider.GRAPH_TYPE_BARS:
-                        mGlCanvas.drawRects(mProfileShapes[i], count * 4, mProfilePaint);
-                        break;
-                    case GraphDataProvider.GRAPH_TYPE_LINES:
-                        mGlCanvas.drawLines(mProfileShapes[i], 0, count * 4, mProfilePaint);
-                        break;
-                }
-            }
-        }
-
-        private void drawCurrentFrame(int graphType, int index) {
-            if (index >= 0) {
-                mDebugDataProvider.setupCurrentFramePaint(mProfilePaint);
-                switch (graphType) {
-                    case GraphDataProvider.GRAPH_TYPE_BARS:
-                        mGlCanvas.drawRect(mProfileShapes[2][index], mProfileShapes[2][index + 1],
-                                mProfileShapes[2][index + 2], mProfileShapes[0][index + 3],
-                                mProfilePaint);
-                        break;
-                    case GraphDataProvider.GRAPH_TYPE_LINES:
-                        mGlCanvas.drawLine(mProfileShapes[2][index], mProfileShapes[2][index + 1],
-                                mProfileShapes[2][index], mHeight, mProfilePaint);
-                        break;
-                }
-            }
-        }
-
-        private void drawThreshold(int x, int height) {
-            float threshold = mDebugDataProvider.getThreshold();
-            if (threshold > 0.0f) {
-                mDebugDataProvider.setupThresholdPaint(mProfilePaint);
-                int y = (int) (mHeight - threshold * height);
-                mGlCanvas.drawLine(0.0f, y, x, y, mProfilePaint);
-            }
-        }
-
-        private void initProfileDrawData(View.AttachInfo attachInfo, GraphDataProvider provider) {
-            if (mProfileShapes == null) {
-                final int elementCount = provider.getElementCount();
-                final int frameCount = provider.getFrameCount();
-
-                mProfileShapes = new float[elementCount][];
-                for (int i = 0; i < elementCount; i++) {
-                    mProfileShapes[i] = new float[frameCount * 4];
-                }
-
-                mProfilePaint = new Paint();
-            }
-
-            mProfilePaint.reset();
-            if (provider.getGraphType() == GraphDataProvider.GRAPH_TYPE_LINES) {
-                mProfilePaint.setAntiAlias(true);
-            }
-
-            if (mDisplayMetrics == null) {
-                mDisplayMetrics = new DisplayMetrics();
-            }
-
-            attachInfo.mDisplay.getMetrics(mDisplayMetrics);
-            provider.prepare(mDisplayMetrics);
-        }
-
-        @Override
-        void destroy(boolean full) {
-            try {
-                super.destroy(full);
-            } finally {
-                if (full && mGlCanvas != null) {
-                    mGlCanvas = null;
-                }
-            }
-        }
-
-        @Override
-        void pushLayerUpdate(HardwareLayer layer) {
-            mGlCanvas.pushLayerUpdate(layer);
-        }
-
-        @Override
-        void cancelLayerUpdate(HardwareLayer layer) {
-            mGlCanvas.cancelLayerUpdate(layer);
-        }
-
-        @Override
-        void flushLayerUpdates() {
-            mGlCanvas.flushLayerUpdates();
-        }
-
-        @Override
-        public DisplayList createDisplayList(String name) {
-            return new GLES20DisplayList(name);
-        }
-
-        @Override
-        HardwareLayer createHardwareLayer(boolean isOpaque) {
-            return new GLES20TextureLayer(isOpaque);
-        }
-
-        @Override
-        public HardwareLayer createHardwareLayer(int width, int height, boolean isOpaque) {
-            return new GLES20RenderLayer(width, height, isOpaque);
-        }
-
-        @Override
-        void countOverdraw(HardwareCanvas canvas) {
-            ((GLES20Canvas) canvas).setCountOverdrawEnabled(true);
-        }
-
-        @Override
-        float getOverdraw(HardwareCanvas canvas) {
-            return ((GLES20Canvas) canvas).getOverdraw();
-        }
-
-        @Override
-        public SurfaceTexture createSurfaceTexture(HardwareLayer layer) {
-            return ((GLES20TextureLayer) layer).getSurfaceTexture();
-        }
-
-        @Override
-        void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture) {
-            ((GLES20TextureLayer) layer).setSurfaceTexture(surfaceTexture);
-        }
-
-        @Override
-        boolean safelyRun(Runnable action) {
-            boolean needsContext = !isEnabled() || checkRenderContext() == SURFACE_STATE_ERROR;
-
-            if (needsContext) {
-                Gl20RendererEglContext managedContext =
-                        (Gl20RendererEglContext) sEglContextStorage.get();
-                if (managedContext == null) return false;
-                usePbufferSurface(managedContext.getContext());
-            }
-
-            try {
-                action.run();
-            } finally {
-                if (needsContext) {
-                    sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
-                            EGL_NO_SURFACE, EGL_NO_CONTEXT);
-                }
-            }
-
-            return true;
-        }
-
-        @Override
-        void destroyLayers(final View view) {
-            if (view != null) {
-                safelyRun(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCanvas != null) {
-                            mCanvas.clearLayerUpdates();
-                        }
-                        destroyHardwareLayer(view);
-                        GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
-                    }
-                });
-            }
-        }
-
-        private static void destroyHardwareLayer(View view) {
-            view.destroyLayer(true);
-
-            if (view instanceof ViewGroup) {
-                ViewGroup group = (ViewGroup) view;
-
-                int count = group.getChildCount();
-                for (int i = 0; i < count; i++) {
-                    destroyHardwareLayer(group.getChildAt(i));
-                }
-            }
-        }
-
-        @Override
-        void destroyHardwareResources(final View view) {
-            if (view != null) {
-                safelyRun(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCanvas != null) {
-                            mCanvas.clearLayerUpdates();
-                        }
-                        destroyResources(view);
-                        GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
-                    }
-                });
-            }
-        }
-
-        private static void destroyResources(View view) {
-            view.destroyHardwareResources();
-
-            if (view instanceof ViewGroup) {
-                ViewGroup group = (ViewGroup) view;
-
-                int count = group.getChildCount();
-                for (int i = 0; i < count; i++) {
-                    destroyResources(group.getChildAt(i));
-                }
-            }
-        }
-
-        static HardwareRenderer create(boolean translucent) {
-            if (GLES20Canvas.isAvailable()) {
-                return new Gl20Renderer(translucent);
-            }
-            return null;
-        }
-
-        static void startTrimMemory(int level) {
-            if (sEgl == null || sEglConfig == null) return;
-
-            Gl20RendererEglContext managedContext =
-                    (Gl20RendererEglContext) sEglContextStorage.get();
-            // We do not have OpenGL objects
-            if (managedContext == null) {
-                return;
-            } else {
-                usePbufferSurface(managedContext.getContext());
-            }
-
-            if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
-                GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
-            } else if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
-                GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
-            }
-        }
-
-        static void endTrimMemory() {
-            if (sEgl != null && sEglDisplay != null) {
-                sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-            }
-        }
-
-        private static void usePbufferSurface(EGLContext eglContext) {
-            synchronized (sPbufferLock) {
-                // Create a temporary 1x1 pbuffer so we have a context
-                // to clear our OpenGL objects
-                if (sPbuffer == null) {
-                    sPbuffer = sEgl.eglCreatePbufferSurface(sEglDisplay, sEglConfig, new int[] {
-                            EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE
-                    });
-                }
-            }
-            sEgl.eglMakeCurrent(sEglDisplay, sPbuffer, sPbuffer, eglContext);
-        }
-    }
 }
diff --git a/core/java/android/view/InputQueue.java b/core/java/android/view/InputQueue.java
index e3de89d..b552c20 100644
--- a/core/java/android/view/InputQueue.java
+++ b/core/java/android/view/InputQueue.java
@@ -18,7 +18,6 @@
 
 import dalvik.system.CloseGuard;
 
-import android.os.Handler;
 import android.os.Looper;
 import android.os.MessageQueue;
 import android.util.Pools.Pool;
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 5a5fc10..30b1e52 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -20,7 +20,6 @@
 import android.os.Parcelable;
 import android.text.method.MetaKeyKeyListener;
 import android.util.Log;
-import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.view.KeyCharacterMap;
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 1bfda2d..a2775d4 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.annotation.IntDef;
 import android.content.res.CompatibilityInfo.Translator;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
@@ -24,6 +25,10 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 import dalvik.system.CloseGuard;
 
 /**
@@ -80,6 +85,11 @@
     // non compatibility mode.
     private Matrix mCompatibleMatrix;
 
+    /** @hide */
+    @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Rotation {}
+
     /**
      * Rotation constant: 0 degree rotation (natural orientation)
      */
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index a06a20b..914a5ca 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -22,7 +22,6 @@
 import android.graphics.Region;
 import android.view.Surface;
 import android.os.IBinder;
-import android.os.SystemProperties;
 import android.util.Log;
 import android.view.Surface.OutOfResourcesException;
 
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 22d4c9b..65d3f6d 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -188,8 +188,13 @@
         init();
     }
 
-    public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         init();
     }
 
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 47f7628..bf81811 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -156,14 +156,32 @@
      * 
      * @param context The context to associate this view with.
      * @param attrs The attributes of the XML tag that is inflating the view.
-     * @param defStyle The default style to apply to this view. If 0, no style
-     *        will be applied (beyond what is included in the theme). This may
-     *        either be an attribute resource, whose value will be retrieved
-     *        from the current theme, or an explicit style resource.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
     @SuppressWarnings({"UnusedDeclaration"})
-    public TextureView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TextureView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    /**
+     * Creates a new TextureView.
+     *
+     * @param context The context to associate this view with.
+     * @param attrs The attributes of the XML tag that is inflating the view.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     */
+    @SuppressWarnings({"UnusedDeclaration"})
+    public TextureView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         init();
     }
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 06f8e8c..5d264b6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16,6 +16,9 @@
 
 package android.view;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.ClipData;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -86,6 +89,8 @@
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
@@ -729,6 +734,11 @@
      */
     private static final int FITS_SYSTEM_WINDOWS = 0x00000002;
 
+    /** @hide */
+    @IntDef({VISIBLE, INVISIBLE, GONE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Visibility {}
+
     /**
      * This view is visible.
      * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
@@ -896,6 +906,11 @@
      */
     static final int FOCUSABLE_IN_TOUCH_MODE = 0x00040000;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH, DRAWING_CACHE_QUALITY_AUTO})
+    public @interface DrawingCacheQuality {}
+
     /**
      * <p>Enables low quality mode for the drawing cache.</p>
      */
@@ -940,6 +955,16 @@
      */
     static final int DUPLICATE_PARENT_STATE = 0x00400000;
 
+    /** @hide */
+    @IntDef({
+        SCROLLBARS_INSIDE_OVERLAY,
+        SCROLLBARS_INSIDE_INSET,
+        SCROLLBARS_OUTSIDE_OVERLAY,
+        SCROLLBARS_OUTSIDE_INSET
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScrollBarStyle {}
+
     /**
      * The scrollbar style to display the scrollbars inside the content area,
      * without increasing the padding. The scrollbars will be overlaid with
@@ -1020,6 +1045,15 @@
      */
     static final int PARENT_SAVE_DISABLED_MASK = 0x20000000;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                FOCUSABLES_ALL,
+                FOCUSABLES_TOUCH_MODE
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FocusableMode {}
+
     /**
      * View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
      * should add all focusable Views regardless if they are focusable in touch mode.
@@ -1032,6 +1066,28 @@
      */
     public static final int FOCUSABLES_TOUCH_MODE = 0x00000001;
 
+    /** @hide */
+    @IntDef({
+            FOCUS_BACKWARD,
+            FOCUS_FORWARD,
+            FOCUS_LEFT,
+            FOCUS_UP,
+            FOCUS_RIGHT,
+            FOCUS_DOWN
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FocusDirection {}
+
+    /** @hide */
+    @IntDef({
+            FOCUS_LEFT,
+            FOCUS_UP,
+            FOCUS_RIGHT,
+            FOCUS_DOWN
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FocusRealDirection {} // Like @FocusDirection, but without forward/backward
+
     /**
      * Use with {@link #focusSearch(int)}. Move focus to the previous selectable
      * item.
@@ -1804,6 +1860,25 @@
      */
     static final int PFLAG2_DRAG_HOVERED               = 0x00000002;
 
+    /** @hide */
+    @IntDef({
+        LAYOUT_DIRECTION_LTR,
+        LAYOUT_DIRECTION_RTL,
+        LAYOUT_DIRECTION_INHERIT,
+        LAYOUT_DIRECTION_LOCALE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    // Not called LayoutDirection to avoid conflict with android.util.LayoutDirection
+    public @interface LayoutDir {}
+
+    /** @hide */
+    @IntDef({
+        LAYOUT_DIRECTION_LTR,
+        LAYOUT_DIRECTION_RTL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ResolvedLayoutDir {}
+
     /**
      * Horizontal layout direction of this view is from Left to Right.
      * Use with {@link #setLayoutDirection}.
@@ -1982,7 +2057,20 @@
     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT =
             TEXT_DIRECTION_RESOLVED_DEFAULT << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
 
-    /*
+    /** @hide */
+    @IntDef({
+        TEXT_ALIGNMENT_INHERIT,
+        TEXT_ALIGNMENT_GRAVITY,
+        TEXT_ALIGNMENT_CENTER,
+        TEXT_ALIGNMENT_TEXT_START,
+        TEXT_ALIGNMENT_TEXT_END,
+        TEXT_ALIGNMENT_VIEW_START,
+        TEXT_ALIGNMENT_VIEW_END
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TextAlignment {}
+
+    /**
      * Default text alignment. The text alignment of this View is inherited from its parent.
      * Use with {@link #setTextAlignment(int)}
      */
@@ -2664,6 +2752,12 @@
             SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
             | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = { FIND_VIEWS_WITH_TEXT, FIND_VIEWS_WITH_CONTENT_DESCRIPTION })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FindViewFlags {}
+
     /**
      * Find views that render the specified text.
      *
@@ -2685,7 +2779,7 @@
      * added and it is a responsibility of the client to call the APIs of
      * the provider to determine whether the virtual tree rooted at this View
      * contains the text, i.e. getting the list of {@link AccessibilityNodeInfo}s
-     * represeting the virtual views with this text.
+     * representing the virtual views with this text.
      *
      * @see #findViewsWithText(ArrayList, CharSequence, int)
      *
@@ -3485,27 +3579,64 @@
     }
 
     /**
-     * Perform inflation from XML and apply a class-specific base style. This
-     * constructor of View allows subclasses to use their own base style when
-     * they are inflating. For example, a Button class's constructor would call
-     * this version of the super class constructor and supply
-     * <code>R.attr.buttonStyle</code> for <var>defStyle</var>; this allows
-     * the theme's button style to modify all of the base view attributes (in
-     * particular its background) as well as the Button class's attributes.
+     * Perform inflation from XML and apply a class-specific base style from a
+     * theme attribute. This constructor of View allows subclasses to use their
+     * own base style when they are inflating. For example, a Button class's
+     * constructor would call this version of the super class constructor and
+     * supply <code>R.attr.buttonStyle</code> for <var>defStyleAttr</var>; this
+     * allows the theme's button style to modify all of the base view attributes
+     * (in particular its background) as well as the Button class's attributes.
      *
      * @param context The Context the view is running in, through which it can
      *        access the current theme, resources, etc.
      * @param attrs The attributes of the XML tag that is inflating the view.
      * @param defStyleAttr An attribute in the current theme that contains a
-     *        reference to a style resource to apply to this view. If 0, no
-     *        default style will be applied.
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      * @see #View(Context, AttributeSet)
      */
     public View(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * Perform inflation from XML and apply a class-specific base style from a
+     * theme attribute or style resource. This constructor of View allows
+     * subclasses to use their own base style when they are inflating.
+     * <p>
+     * When determining the final value of a particular attribute, there are
+     * four inputs that come into play:
+     * <ol>
+     * <li>Any attribute values in the given AttributeSet.
+     * <li>The style resource specified in the AttributeSet (named "style").
+     * <li>The default style specified by <var>defStyleAttr</var>.
+     * <li>The default style specified by <var>defStyleRes</var>.
+     * <li>The base values in this theme.
+     * </ol>
+     * <p>
+     * Each of these inputs is considered in-order, with the first listed taking
+     * precedence over the following ones. In other words, if in the
+     * AttributeSet you have supplied <code>&lt;Button * textColor="#ff000000"&gt;</code>
+     * , then the button's text will <em>always</em> be black, regardless of
+     * what is specified in any of the styles.
+     *
+     * @param context The Context the view is running in, through which it can
+     *        access the current theme, resources, etc.
+     * @param attrs The attributes of the XML tag that is inflating the view.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     * @see #View(Context, AttributeSet, int)
+     */
+    public View(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         this(context);
 
-        TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View,
-                defStyleAttr, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
 
         Drawable background = null;
 
@@ -4596,7 +4727,7 @@
      * @param previouslyFocusedRect The rectangle of the view that had focus
      *        prior in this View's coordinate system.
      */
-    void handleFocusGainInternal(int direction, Rect previouslyFocusedRect) {
+    void handleFocusGainInternal(@FocusRealDirection int direction, Rect previouslyFocusedRect) {
         if (DBG) {
             System.out.println(this + " requestFocus()");
         }
@@ -4807,7 +4938,8 @@
      *        passed in as finer grained information about where the focus is coming
      *        from (in addition to direction).  Will be <code>null</code> otherwise.
      */
-    protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
+    protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
+            @Nullable Rect previouslyFocusedRect) {
         if (gainFocus) {
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
         } else {
@@ -5667,6 +5799,7 @@
      *
      * @attr ref android.R.styleable#View_drawingCacheQuality
      */
+    @DrawingCacheQuality
     public int getDrawingCacheQuality() {
         return mViewFlags & DRAWING_CACHE_QUALITY_MASK;
     }
@@ -5684,7 +5817,7 @@
      *
      * @attr ref android.R.styleable#View_drawingCacheQuality
      */
-    public void setDrawingCacheQuality(int quality) {
+    public void setDrawingCacheQuality(@DrawingCacheQuality int quality) {
         setFlags(quality, DRAWING_CACHE_QUALITY_MASK);
     }
 
@@ -6021,6 +6154,7 @@
         @ViewDebug.IntToString(from = INVISIBLE, to = "INVISIBLE"),
         @ViewDebug.IntToString(from = GONE,      to = "GONE")
     })
+    @Visibility
     public int getVisibility() {
         return mViewFlags & VISIBILITY_MASK;
     }
@@ -6032,7 +6166,7 @@
      * @attr ref android.R.styleable#View_visibility
      */
     @RemotableViewMethod
-    public void setVisibility(int visibility) {
+    public void setVisibility(@Visibility int visibility) {
         setFlags(visibility, VISIBILITY_MASK);
         if (mBackground != null) mBackground.setVisible(visibility == VISIBLE, false);
     }
@@ -6191,6 +6325,7 @@
         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_INHERIT, to = "INHERIT"),
         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LOCALE,  to = "LOCALE")
     })
+    @LayoutDir
     public int getRawLayoutDirection() {
         return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >> PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
     }
@@ -6213,7 +6348,7 @@
      * @attr ref android.R.styleable#View_layoutDirection
      */
     @RemotableViewMethod
-    public void setLayoutDirection(int layoutDirection) {
+    public void setLayoutDirection(@LayoutDir int layoutDirection) {
         if (getRawLayoutDirection() != layoutDirection) {
             // Reset the current layout direction and the resolved one
             mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_MASK;
@@ -6243,6 +6378,7 @@
         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "RESOLVED_DIRECTION_LTR"),
         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RESOLVED_DIRECTION_RTL")
     })
+    @ResolvedLayoutDir
     public int getLayoutDirection() {
         final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
         if (targetSdkVersion < JELLY_BEAN_MR1) {
@@ -6612,7 +6748,7 @@
      * @return The nearest focusable in the specified direction, or null if none
      *         can be found.
      */
-    public View focusSearch(int direction) {
+    public View focusSearch(@FocusRealDirection int direction) {
         if (mParent != null) {
             return mParent.focusSearch(this, direction);
         } else {
@@ -6631,7 +6767,7 @@
      *        FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT.
      * @return True if the this view consumed this unhandled move.
      */
-    public boolean dispatchUnhandledMove(View focused, int direction) {
+    public boolean dispatchUnhandledMove(View focused, @FocusRealDirection int direction) {
         return false;
     }
 
@@ -6643,7 +6779,7 @@
      * or FOCUS_BACKWARD.
      * @return The user specified next view, or null if there is none.
      */
-    View findUserSetNextFocus(View root, int direction) {
+    View findUserSetNextFocus(View root, @FocusDirection int direction) {
         switch (direction) {
             case FOCUS_LEFT:
                 if (mNextFocusLeftId == View.NO_ID) return null;
@@ -6693,7 +6829,7 @@
      * @param direction The direction of the focus
      * @return A list of focusable views
      */
-    public ArrayList<View> getFocusables(int direction) {
+    public ArrayList<View> getFocusables(@FocusDirection int direction) {
         ArrayList<View> result = new ArrayList<View>(24);
         addFocusables(result, direction);
         return result;
@@ -6707,7 +6843,7 @@
      * @param views Focusable views found so far
      * @param direction The direction of the focus
      */
-    public void addFocusables(ArrayList<View> views, int direction) {
+    public void addFocusables(ArrayList<View> views, @FocusDirection int direction) {
         addFocusables(views, direction, FOCUSABLES_TOUCH_MODE);
     }
 
@@ -6727,7 +6863,8 @@
      * @see #FOCUSABLES_ALL
      * @see #FOCUSABLES_TOUCH_MODE
      */
-    public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
+    public void addFocusables(ArrayList<View> views, @FocusDirection int direction,
+            @FocusableMode int focusableMode) {
         if (views == null) {
             return;
         }
@@ -6756,7 +6893,8 @@
      * @see #FIND_VIEWS_WITH_CONTENT_DESCRIPTION
      * @see #setContentDescription(CharSequence)
      */
-    public void findViewsWithText(ArrayList<View> outViews, CharSequence searched, int flags) {
+    public void findViewsWithText(ArrayList<View> outViews, CharSequence searched,
+            @FindViewFlags int flags) {
         if (getAccessibilityNodeProvider() != null) {
             if ((flags & FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS) != 0) {
                 outViews.add(this);
@@ -7247,7 +7385,7 @@
     }
 
     /**
-     * Returns whether the View has registered callbacks wich makes it
+     * Returns whether the View has registered callbacks which makes it
      * important for accessibility.
      *
      * @return True if the view is actionable for accessibility.
@@ -7266,7 +7404,7 @@
      * notification is at at most once every
      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
      * to avoid unnecessary load to the system. Also once a view has a pending
-     * notifucation this method is a NOP until the notification has been sent.
+     * notification this method is a NOP until the notification has been sent.
      *
      * @hide
      */
@@ -7946,7 +8084,8 @@
      * @param visibility The new visibility of changedView: {@link #VISIBLE},
      * {@link #INVISIBLE} or {@link #GONE}.
      */
-    protected void dispatchVisibilityChanged(View changedView, int visibility) {
+    protected void dispatchVisibilityChanged(@NonNull View changedView,
+            @Visibility int visibility) {
         onVisibilityChanged(changedView, visibility);
     }
 
@@ -7957,7 +8096,7 @@
      * @param visibility The new visibility of changedView: {@link #VISIBLE},
      * {@link #INVISIBLE} or {@link #GONE}.
      */
-    protected void onVisibilityChanged(View changedView, int visibility) {
+    protected void onVisibilityChanged(@NonNull View changedView, @Visibility int visibility) {
         if (visibility == VISIBLE) {
             if (mAttachInfo != null) {
                 initialAwakenScrollBars();
@@ -7976,7 +8115,7 @@
      * @param hint A hint about whether or not this view is displayed:
      * {@link #VISIBLE} or {@link #INVISIBLE}.
      */
-    public void dispatchDisplayHint(int hint) {
+    public void dispatchDisplayHint(@Visibility int hint) {
         onDisplayHint(hint);
     }
 
@@ -7989,7 +8128,7 @@
      * @param hint A hint about whether or not this view is displayed:
      * {@link #VISIBLE} or {@link #INVISIBLE}.
      */
-    protected void onDisplayHint(int hint) {
+    protected void onDisplayHint(@Visibility int hint) {
     }
 
     /**
@@ -8000,7 +8139,7 @@
      *
      * @see #onWindowVisibilityChanged(int)
      */
-    public void dispatchWindowVisibilityChanged(int visibility) {
+    public void dispatchWindowVisibilityChanged(@Visibility int visibility) {
         onWindowVisibilityChanged(visibility);
     }
 
@@ -8014,7 +8153,7 @@
      *
      * @param visibility The new visibility of the window.
      */
-    protected void onWindowVisibilityChanged(int visibility) {
+    protected void onWindowVisibilityChanged(@Visibility int visibility) {
         if (visibility == VISIBLE) {
             initialAwakenScrollBars();
         }
@@ -8026,6 +8165,7 @@
      *
      * @return Returns the current visibility of the view's window.
      */
+    @Visibility
     public int getWindowVisibility() {
         return mAttachInfo != null ? mAttachInfo.mWindowVisibility : GONE;
     }
@@ -9060,9 +9200,9 @@
      */
     public interface OnLayoutChangeListener {
         /**
-         * Called when the focus state of a view has changed.
+         * Called when the layout bounds of a view changes due to layout processing.
          *
-         * @param v The view whose state has changed.
+         * @param v The view whose bounds have changed.
          * @param left The new value of the view's left property.
          * @param top The new value of the view's top property.
          * @param right The new value of the view's right property.
@@ -10303,7 +10443,7 @@
     }
 
     /**
-     * The horizontal location of this view relative to its {@link #getTop() top} position.
+     * The vertical location of this view relative to its {@link #getTop() top} position.
      * This position is post-layout, in addition to wherever the object's
      * layout placed it.
      *
@@ -10818,15 +10958,6 @@
             mPrivateFlags |= PFLAG_DIRTY;
             final ViewParent p = mParent;
             final AttachInfo ai = mAttachInfo;
-            //noinspection PointlessBooleanExpression,ConstantConditions
-            if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
-                if (p != null && ai != null && ai.mHardwareAccelerated) {
-                    // fast-track for GL-enabled applications; just invalidate the whole hierarchy
-                    // with a null dirty rect, which tells the ViewAncestor to redraw everything
-                    p.invalidateChild(this, null);
-                    return;
-                }
-            }
             if (p != null && ai != null) {
                 final int scrollX = mScrollX;
                 final int scrollY = mScrollY;
@@ -10861,15 +10992,6 @@
             mPrivateFlags |= PFLAG_DIRTY;
             final ViewParent p = mParent;
             final AttachInfo ai = mAttachInfo;
-            //noinspection PointlessBooleanExpression,ConstantConditions
-            if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
-                if (p != null && ai != null && ai.mHardwareAccelerated) {
-                    // fast-track for GL-enabled applications; just invalidate the whole hierarchy
-                    // with a null dirty rect, which tells the ViewAncestor to redraw everything
-                    p.invalidateChild(this, null);
-                    return;
-                }
-            }
             if (p != null && ai != null && l < r && t < b) {
                 final int scrollX = mScrollX;
                 final int scrollY = mScrollY;
@@ -10917,15 +11039,6 @@
             }
             final AttachInfo ai = mAttachInfo;
             final ViewParent p = mParent;
-            //noinspection PointlessBooleanExpression,ConstantConditions
-            if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
-                if (p != null && ai != null && ai.mHardwareAccelerated) {
-                    // fast-track for GL-enabled applications; just invalidate the whole hierarchy
-                    // with a null dirty rect, which tells the ViewAncestor to redraw everything
-                    p.invalidateChild(this, null);
-                    return;
-                }
-            }
 
             if (p != null && ai != null) {
                 final Rect r = ai.mTmpInvalRect;
@@ -11212,10 +11325,9 @@
                 attachInfo.mHandler.removeCallbacks(action);
                 attachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
                         Choreographer.CALLBACK_ANIMATION, action, null);
-            } else {
-                // Assume that post will succeed later
-                ViewRootImpl.getRunQueue().removeCallbacks(action);
             }
+            // Assume that post will succeed later
+            ViewRootImpl.getRunQueue().removeCallbacks(action);
         }
         return true;
     }
@@ -11706,7 +11818,7 @@
      *
      * @attr ref android.R.styleable#View_scrollbarStyle
      */
-    public void setScrollBarStyle(int style) {
+    public void setScrollBarStyle(@ScrollBarStyle int style) {
         if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) {
             mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK);
             computeOpaqueFlags();
@@ -11730,6 +11842,7 @@
             @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_OVERLAY, to = "OUTSIDE_OVERLAY"),
             @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_INSET, to = "OUTSIDE_INSET")
     })
+    @ScrollBarStyle
     public int getScrollBarStyle() {
         return mViewFlags & SCROLLBARS_STYLE_MASK;
     }
@@ -12231,7 +12344,7 @@
      * @see #LAYOUT_DIRECTION_LTR
      * @see #LAYOUT_DIRECTION_RTL
      */
-    public void onRtlPropertiesChanged(int layoutDirection) {
+    public void onRtlPropertiesChanged(@ResolvedLayoutDir int layoutDirection) {
     }
 
     /**
@@ -13260,20 +13373,6 @@
     }
 
     /**
-     * @return The {@link HardwareRenderer} associated with that view or null if
-     *         hardware rendering is not supported or this view is not attached
-     *         to a window.
-     *
-     * @hide
-     */
-    public HardwareRenderer getHardwareRenderer() {
-        if (mAttachInfo != null) {
-            return mAttachInfo.mHardwareRenderer;
-        }
-        return null;
-    }
-
-    /**
      * Returns a DisplayList. If the incoming displayList is null, one will be created.
      * Otherwise, the same display list will be returned (after having been rendered into
      * along the way, depending on the invalidation state of the view).
@@ -13308,7 +13407,7 @@
                 mRecreateDisplayList = true;
             }
             if (displayList == null) {
-                displayList = mAttachInfo.mHardwareRenderer.createDisplayList(getClass().getName());
+                displayList = DisplayList.create(getClass().getName());
                 // If we're creating a new display list, make sure our parent gets invalidated
                 // since they will need to recreate their display list to account for this
                 // new child display list.
@@ -15003,9 +15102,8 @@
             if (mAttachInfo != null) {
                 mAttachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
                         Choreographer.CALLBACK_ANIMATION, what, who);
-            } else {
-                ViewRootImpl.getRunQueue().removeCallbacks(what);
             }
+            ViewRootImpl.getRunQueue().removeCallbacks(what);
         }
     }
 
@@ -15068,7 +15166,7 @@
      *
      * @hide
      */
-    public void onResolveDrawables(int layoutDirection) {
+    public void onResolveDrawables(@ResolvedLayoutDir int layoutDirection) {
     }
 
     /**
@@ -15835,8 +15933,10 @@
             return false;
         }
 
-        transformMotionEventToGlobal(ev);
-        ev.offsetLocation(info.mWindowLeft, info.mWindowTop);
+        final Matrix m = info.mTmpMatrix;
+        m.set(Matrix.IDENTITY_MATRIX);
+        transformMatrixToGlobal(m);
+        ev.transform(m);
         return true;
     }
 
@@ -15854,54 +15954,60 @@
             return false;
         }
 
-        ev.offsetLocation(-info.mWindowLeft, -info.mWindowTop);
-        transformMotionEventToLocal(ev);
+        final Matrix m = info.mTmpMatrix;
+        m.set(Matrix.IDENTITY_MATRIX);
+        transformMatrixToLocal(m);
+        ev.transform(m);
         return true;
     }
 
     /**
-     * Recursive helper method that applies transformations in post-order.
+     * Modifies the input matrix such that it maps view-local coordinates to
+     * on-screen coordinates.
      *
-     * @param ev the on-screen motion event
+     * @param m input matrix to modify
      */
-    private void transformMotionEventToLocal(MotionEvent ev) {
+    void transformMatrixToGlobal(Matrix m) {
         final ViewParent parent = mParent;
         if (parent instanceof View) {
             final View vp = (View) parent;
-            vp.transformMotionEventToLocal(ev);
-            ev.offsetLocation(vp.mScrollX, vp.mScrollY);
+            vp.transformMatrixToGlobal(m);
+            m.postTranslate(-vp.mScrollX, -vp.mScrollY);
         } else if (parent instanceof ViewRootImpl) {
             final ViewRootImpl vr = (ViewRootImpl) parent;
-            ev.offsetLocation(0, vr.mCurScrollY);
+            vr.transformMatrixToGlobal(m);
+            m.postTranslate(0, -vr.mCurScrollY);
         }
 
-        ev.offsetLocation(-mLeft, -mTop);
+        m.postTranslate(mLeft, mTop);
 
         if (!hasIdentityMatrix()) {
-            ev.transform(getInverseMatrix());
+            m.postConcat(getMatrix());
         }
     }
 
     /**
-     * Recursive helper method that applies transformations in pre-order.
+     * Modifies the input matrix such that it maps on-screen coordinates to
+     * view-local coordinates.
      *
-     * @param ev the on-screen motion event
+     * @param m input matrix to modify
      */
-    private void transformMotionEventToGlobal(MotionEvent ev) {
-        if (!hasIdentityMatrix()) {
-            ev.transform(getMatrix());
-        }
-
-        ev.offsetLocation(mLeft, mTop);
-
+    void transformMatrixToLocal(Matrix m) {
         final ViewParent parent = mParent;
         if (parent instanceof View) {
             final View vp = (View) parent;
-            ev.offsetLocation(-vp.mScrollX, -vp.mScrollY);
-            vp.transformMotionEventToGlobal(ev);
+            vp.transformMatrixToLocal(m);
+            m.preTranslate(vp.mScrollX, vp.mScrollY);
         } else if (parent instanceof ViewRootImpl) {
             final ViewRootImpl vr = (ViewRootImpl) parent;
-            ev.offsetLocation(0, -vr.mCurScrollY);
+            vr.transformMatrixToLocal(m);
+            m.preTranslate(0, vr.mCurScrollY);
+        }
+
+        m.preTranslate(-mLeft, -mTop);
+
+        if (!hasIdentityMatrix()) {
+            m.preConcat(getInverseMatrix());
         }
     }
 
@@ -17870,6 +17976,7 @@
             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"),
             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
     })
+    @TextAlignment
     public int getRawTextAlignment() {
         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_MASK) >> PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
     }
@@ -17893,7 +18000,7 @@
      *
      * @attr ref android.R.styleable#View_textAlignment
      */
-    public void setTextAlignment(int textAlignment) {
+    public void setTextAlignment(@TextAlignment int textAlignment) {
         if (textAlignment != getRawTextAlignment()) {
             // Reset the current and resolved text alignment
             mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK;
@@ -17934,6 +18041,7 @@
             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"),
             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
     })
+    @TextAlignment
     public int getTextAlignment() {
         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK) >>
                 PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
@@ -18746,7 +18854,6 @@
         View mRootView;
 
         IBinder mPanelParentWindowToken;
-        Surface mSurface;
 
         boolean mHardwareAccelerated;
         boolean mHardwareAccelerationRequested;
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index c3f064f..e67659c 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -212,6 +212,14 @@
      */
     private static final int OVERFLING_DISTANCE = 6;
 
+    /**
+     * Configuration values for overriding {@link #hasPermanentMenuKey()} behavior.
+     * These constants must match the definition in res/values/config.xml.
+     */
+    private static final int HAS_PERMANENT_MENU_KEY_AUTODETECT = 0;
+    private static final int HAS_PERMANENT_MENU_KEY_TRUE = 1;
+    private static final int HAS_PERMANENT_MENU_KEY_FALSE = 2;
+
     private final int mEdgeSlop;
     private final int mFadingEdgeLength;
     private final int mMinimumFlingVelocity;
@@ -296,12 +304,31 @@
         mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);
 
         if (!sHasPermanentMenuKeySet) {
-            IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
-            try {
-                sHasPermanentMenuKey = !wm.hasNavigationBar();
-                sHasPermanentMenuKeySet = true;
-            } catch (RemoteException ex) {
-                sHasPermanentMenuKey = false;
+            final int configVal = res.getInteger(
+                    com.android.internal.R.integer.config_overrideHasPermanentMenuKey);
+
+            switch (configVal) {
+                default:
+                case HAS_PERMANENT_MENU_KEY_AUTODETECT: {
+                    IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+                    try {
+                        sHasPermanentMenuKey = !wm.hasNavigationBar();
+                        sHasPermanentMenuKeySet = true;
+                    } catch (RemoteException ex) {
+                        sHasPermanentMenuKey = false;
+                    }
+                }
+                break;
+
+                case HAS_PERMANENT_MENU_KEY_TRUE:
+                    sHasPermanentMenuKey = true;
+                    sHasPermanentMenuKeySet = true;
+                    break;
+
+                case HAS_PERMANENT_MENU_KEY_FALSE:
+                    sHasPermanentMenuKey = false;
+                    sHasPermanentMenuKeySet = true;
+                    break;
             }
         }
 
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 9414237..a1b7ef6 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -38,7 +38,6 @@
 import android.util.Pools.SynchronizedPool;
 import android.util.SparseArray;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
@@ -456,20 +455,21 @@
     private int mChildCountWithTransientState = 0;
 
     public ViewGroup(Context context) {
-        super(context);
-        initViewGroup();
+        this(context, null);
     }
 
     public ViewGroup(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        initViewGroup();
-        initFromAttributes(context, attrs);
+        this(context, attrs, 0);
     }
 
-    public ViewGroup(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ViewGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initViewGroup();
-        initFromAttributes(context, attrs);
+        initFromAttributes(context, attrs, defStyleAttr, defStyleRes);
     }
 
     private boolean debugDraw() {
@@ -499,9 +499,9 @@
         mPersistentDrawingCache = PERSISTENT_SCROLLING_CACHE;
     }
 
-    private void initFromAttributes(Context context, AttributeSet attrs) {
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                R.styleable.ViewGroup);
+    private void initFromAttributes(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewGroup);
 
         final int N = a.getIndexCount();
         for (int i = 0; i < N; i++) {
@@ -2510,13 +2510,13 @@
     void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfoInternal(info);
         if (mAttachInfo != null) {
-            ArrayList<View> childrenForAccessibility = mAttachInfo.mTempArrayList;
+            final ArrayList<View> childrenForAccessibility = mAttachInfo.mTempArrayList;
             childrenForAccessibility.clear();
             addChildrenForAccessibility(childrenForAccessibility);
             final int childrenForAccessibilityCount = childrenForAccessibility.size();
             for (int i = 0; i < childrenForAccessibilityCount; i++) {
-                View child = childrenForAccessibility.get(i);
-                info.addChild(child);
+                final View child = childrenForAccessibility.get(i);
+                info.addChildUnchecked(child);
             }
             childrenForAccessibility.clear();
         }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bc0d7e3..ff74f9d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -28,6 +28,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
@@ -108,7 +109,6 @@
     private static final boolean DEBUG_IMF = false || LOCAL_LOGV;
     private static final boolean DEBUG_CONFIGURATION = false || LOCAL_LOGV;
     private static final boolean DEBUG_FPS = false;
-    private static final boolean DEBUG_INPUT_PROCESSING = false || LOCAL_LOGV;
 
     /**
      * Set this system property to true to force the view hierarchy to render
@@ -719,7 +719,7 @@
                 }
 
                 final boolean translucent = attrs.format != PixelFormat.OPAQUE;
-                mAttachInfo.mHardwareRenderer = HardwareRenderer.createGlRenderer(2, translucent);
+                mAttachInfo.mHardwareRenderer = HardwareRenderer.create(translucent);
                 if (mAttachInfo.mHardwareRenderer != null) {
                     mAttachInfo.mHardwareRenderer.setName(attrs.getTitle().toString());
                     mAttachInfo.mHardwareAccelerated =
@@ -1125,6 +1125,28 @@
         return windowSizeMayChange;
     }
 
+    /**
+     * Modifies the input matrix such that it maps view-local coordinates to
+     * on-screen coordinates.
+     *
+     * @param m input matrix to modify
+     */
+    void transformMatrixToGlobal(Matrix m) {
+        final View.AttachInfo attachInfo = mAttachInfo;
+        m.postTranslate(attachInfo.mWindowLeft, attachInfo.mWindowTop);
+    }
+
+    /**
+     * Modifies the input matrix such that it maps on-screen coordinates to
+     * view-local coordinates.
+     *
+     * @param m input matrix to modify
+     */
+    void transformMatrixToLocal(Matrix m) {
+        final View.AttachInfo attachInfo = mAttachInfo;
+        m.preTranslate(-attachInfo.mWindowLeft, -attachInfo.mWindowTop);
+    }
+
     private void performTraversals() {
         // cache mView since it is used so much below...
         final View host = mView;
@@ -1195,11 +1217,6 @@
                 desiredWindowHeight = packageMetrics.heightPixels;
             }
 
-            // For the very first time, tell the view hierarchy that it
-            // is attached to the window.  Note that at this point the surface
-            // object is not initialized to its backing store, but soon it
-            // will be (assuming the window is visible).
-            attachInfo.mSurface = mSurface;
             // We used to use the following condition to choose 32 bits drawing caches:
             // PixelFormat.hasAlpha(lp.format) || lp.format == PixelFormat.RGBX_8888
             // However, windows are now always 32 bits by default, so choose 32 bits
@@ -1548,7 +1565,7 @@
                         if (mAttachInfo.mHardwareRenderer != null) {
                             try {
                                 hwInitialized = mAttachInfo.mHardwareRenderer.initialize(
-                                        mHolder.getSurface());
+                                        mSurface);
                             } catch (OutOfResourcesException e) {
                                 handleOutOfResourcesException(e);
                                 return;
@@ -1575,7 +1592,7 @@
                         mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
                     mFullRedrawNeeded = true;
                     try {
-                        mAttachInfo.mHardwareRenderer.updateSurface(mHolder.getSurface());
+                        mAttachInfo.mHardwareRenderer.updateSurface(mSurface);
                     } catch (OutOfResourcesException e) {
                         handleOutOfResourcesException(e);
                         return;
@@ -1658,7 +1675,7 @@
                         mHeight != mAttachInfo.mHardwareRenderer.getHeight()) {
                     mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
                     if (!hwInitialized) {
-                        mAttachInfo.mHardwareRenderer.invalidate(mHolder.getSurface());
+                        mAttachInfo.mHardwareRenderer.invalidate(mSurface);
                         mFullRedrawNeeded = true;
                     }
                 }
@@ -2395,7 +2412,7 @@
 
                     try {
                         attachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight,
-                                mHolder.getSurface());
+                                mSurface);
                     } catch (OutOfResourcesException e) {
                         handleOutOfResourcesException(e);
                         return;
@@ -2530,28 +2547,35 @@
      * @param canvas The canvas on which to draw.
      */
     private void drawAccessibilityFocusedDrawableIfNeeded(Canvas canvas) {
-        AccessibilityManager manager = AccessibilityManager.getInstance(mView.mContext);
+        if (!mAttachInfo.mHasWindowFocus) {
+            return;
+        }
+
+        final AccessibilityManager manager = AccessibilityManager.getInstance(mView.mContext);
         if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
             return;
         }
-        if (mAccessibilityFocusedHost == null || mAccessibilityFocusedHost.mAttachInfo == null) {
+
+        final View host = mAccessibilityFocusedHost;
+        if (host == null || host.mAttachInfo == null) {
             return;
         }
-        Drawable drawable = getAccessibilityFocusedDrawable();
+
+        final Drawable drawable = getAccessibilityFocusedDrawable();
         if (drawable == null) {
             return;
         }
-        AccessibilityNodeProvider provider =
-            mAccessibilityFocusedHost.getAccessibilityNodeProvider();
-        Rect bounds = mView.mAttachInfo.mTmpInvalRect;
+
+        final AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
+        final Rect bounds = mView.mAttachInfo.mTmpInvalRect;
         if (provider == null) {
-            mAccessibilityFocusedHost.getBoundsOnScreen(bounds);
-        } else {
-            if (mAccessibilityFocusedVirtualView == null) {
-                return;
-            }
+            host.getBoundsOnScreen(bounds);
+        } else if (mAccessibilityFocusedVirtualView != null) {
             mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds);
+        } else {
+            return;
         }
+
         bounds.offset(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop);
         bounds.intersect(0, 0, mAttachInfo.mViewRootImpl.mWidth, mAttachInfo.mViewRootImpl.mHeight);
         drawable.setBounds(bounds);
@@ -2850,7 +2874,6 @@
         mView.assignParent(null);
         mView = null;
         mAttachInfo.mRootView = null;
-        mAttachInfo.mSurface = null;
 
         mSurface.release();
 
@@ -3110,7 +3133,7 @@
                             mFullRedrawNeeded = true;
                             try {
                                 mAttachInfo.mHardwareRenderer.initializeIfNeeded(
-                                        mWidth, mHeight, mHolder.getSurface());
+                                        mWidth, mHeight, mSurface);
                             } catch (OutOfResourcesException e) {
                                 Log.e(TAG, "OutOfResourcesException locking surface", e);
                                 try {
@@ -3159,8 +3182,6 @@
                         mHasHadWindowFocus = true;
                     }
 
-                    setAccessibilityFocus(null, null);
-
                     if (mView != null && mAccessibilityManager.isEnabled()) {
                         if (hasWindowFocus) {
                             mView.sendAccessibilityEvent(
@@ -4506,8 +4527,7 @@
         // The active pointer id, or -1 if none.
         private int mActivePointerId = -1;
 
-        // Time and location where tracking started.
-        private long mStartTime;
+        // Location where tracking started.
         private float mStartX;
         private float mStartY;
 
@@ -4535,9 +4555,6 @@
         private boolean mFlinging;
         private float mFlingVelocity;
 
-        // The last time a confirm key was pressed on the touch nav device
-        private long mLastConfirmKeyTime = Long.MAX_VALUE;
-
         public SyntheticTouchNavigationHandler() {
             super(true);
         }
@@ -4604,7 +4621,6 @@
                     mActivePointerId = event.getPointerId(0);
                     mVelocityTracker = VelocityTracker.obtain();
                     mVelocityTracker.addMovement(event);
-                    mStartTime = time;
                     mStartX = event.getX();
                     mStartY = event.getY();
                     mLastX = mStartX;
@@ -5388,7 +5404,7 @@
 
                 // Hardware rendering
                 if (mAttachInfo.mHardwareRenderer != null) {
-                    if (mAttachInfo.mHardwareRenderer.loadSystemProperties(mHolder.getSurface())) {
+                    if (mAttachInfo.mHardwareRenderer.loadSystemProperties(mSurface)) {
                         invalidate();
                     }
                 }
@@ -6335,68 +6351,6 @@
         }
     }
 
-    private final SurfaceHolder mHolder = new SurfaceHolder() {
-        // we only need a SurfaceHolder for opengl. it would be nice
-        // to implement everything else though, especially the callback
-        // support (opengl doesn't make use of it right now, but eventually
-        // will).
-        @Override
-        public Surface getSurface() {
-            return mSurface;
-        }
-
-        @Override
-        public boolean isCreating() {
-            return false;
-        }
-
-        @Override
-        public void addCallback(Callback callback) {
-        }
-
-        @Override
-        public void removeCallback(Callback callback) {
-        }
-
-        @Override
-        public void setFixedSize(int width, int height) {
-        }
-
-        @Override
-        public void setSizeFromLayout() {
-        }
-
-        @Override
-        public void setFormat(int format) {
-        }
-
-        @Override
-        public void setType(int type) {
-        }
-
-        @Override
-        public void setKeepScreenOn(boolean screenOn) {
-        }
-
-        @Override
-        public Canvas lockCanvas() {
-            return null;
-        }
-
-        @Override
-        public Canvas lockCanvas(Rect dirty) {
-            return null;
-        }
-
-        @Override
-        public void unlockCanvasAndPost(Canvas canvas) {
-        }
-        @Override
-        public Rect getSurfaceFrame() {
-            return null;
-        }
-    };
-
     static RunQueue getRunQueue() {
         RunQueue rq = sRunQueues.get();
         if (rq != null) {
diff --git a/core/java/android/view/ViewStub.java b/core/java/android/view/ViewStub.java
index a5dc3ae..d68a860 100644
--- a/core/java/android/view/ViewStub.java
+++ b/core/java/android/view/ViewStub.java
@@ -97,16 +97,21 @@
     }
 
     @SuppressWarnings({"UnusedDeclaration"})
-    public ViewStub(Context context, AttributeSet attrs, int defStyle) {
-        TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.ViewStub,
-                defStyle, 0);
+    public ViewStub(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ViewStub(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ViewStub, defStyleAttr, defStyleRes);
 
         mInflatedId = a.getResourceId(R.styleable.ViewStub_inflatedId, NO_ID);
         mLayoutResource = a.getResourceId(R.styleable.ViewStub_layout, 0);
 
         a.recycle();
 
-        a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View, defStyle, 0);
+        a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
         mID = a.getResourceId(R.styleable.View_id, NO_ID);
         a.recycle();
 
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index f0e6677..52f9c0b 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -311,7 +311,6 @@
         lp.type = LayoutParams.TYPE_VOLUME_OVERLAY;
         lp.width = LayoutParams.WRAP_CONTENT;
         lp.height = LayoutParams.WRAP_CONTENT;
-        lp.privateFlags |= LayoutParams.PRIVATE_FLAG_FORCE_SHOW_NAV_BAR;
         window.setAttributes(lp);
         window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCH_MODAL
                 | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index b3a0699..2f62431 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -16,6 +16,8 @@
 
 package android.view;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
@@ -25,6 +27,8 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.SystemProperties;
+import android.transition.Scene;
+import android.transition.TransitionManager;
 import android.view.accessibility.AccessibilityEvent;
 
 /**
@@ -89,12 +93,21 @@
      * If overlay is enabled, the action mode UI will be allowed to cover existing window content.
      */
     public static final int FEATURE_ACTION_MODE_OVERLAY = 10;
+    /**
+     * Flag for requesting that window content changes should be represented
+     * with scenes and transitions.
+     *
+     * TODO Add docs
+     *
+     * @see #setContentView
+     */
+    public static final int FEATURE_CONTENT_TRANSITIONS = 11;
 
     /**
      * Max value used as a feature ID
      * @hide
      */
-    public static final int FEATURE_MAX = FEATURE_ACTION_MODE_OVERLAY;
+    public static final int FEATURE_MAX = FEATURE_CONTENT_TRANSITIONS;
 
     /** Flag for setting the progress bar's visibility to VISIBLE */
     public static final int PROGRESS_VISIBILITY_ON = -1;
@@ -240,6 +253,7 @@
          *
          * @see #onPreparePanel
          */
+        @Nullable
         public View onCreatePanelView(int featureId);
 
         /**
@@ -368,6 +382,7 @@
          * @param callback Callback to control the lifecycle of this action mode
          * @return The ActionMode that was started, or null if the system should present it
          */
+        @Nullable
         public ActionMode onWindowStartingActionMode(ActionMode.Callback callback);
 
         /**
@@ -969,6 +984,7 @@
      *
      * @return View The current View with focus or null.
      */
+    @Nullable
     public abstract View getCurrentFocus();
 
     /**
@@ -977,10 +993,12 @@
      *
      * @return LayoutInflater The shared LayoutInflater.
      */
+    @NonNull
     public abstract LayoutInflater getLayoutInflater();
 
     public abstract void setTitle(CharSequence title);
 
+    @Deprecated
     public abstract void setTitleColor(int textColor);
 
     public abstract void openPanel(int featureId, KeyEvent event);
@@ -1317,4 +1335,47 @@
      * @param event A key or touch event to inject to this window.
      */
     public void injectInputEvent(InputEvent event) { }
+
+    /**
+     * Retrieve the {@link TransitionManager} responsible for  for default transitions
+     * in this window. Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * <p>This method will return non-null after content has been initialized (e.g. by using
+     * {@link #setContentView}) if {@link #FEATURE_CONTENT_TRANSITIONS} has been granted.</p>
+     *
+     * @return This window's content TransitionManager or null if none is set.
+     */
+    public TransitionManager getTransitionManager() {
+        return null;
+    }
+
+    /**
+     * Set the {@link TransitionManager} to use for default transitions in this window.
+     * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * @param tm The TransitionManager to use for scene changes.
+     */
+    public void setTransitionManager(TransitionManager tm) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Retrieve the {@link Scene} representing this window's current content.
+     * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * <p>This method will return null if the current content is not represented by a Scene.</p>
+     *
+     * @return Current Scene being shown or null
+     */
+    public Scene getContentScene() {
+        return null;
+    }
+
+    /**
+     * Set options that can affect the transition behavior within this window.
+     * @param options Options to set or null for none
+     */
+    public void setTransitionOptions(Bundle options) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 0ce4da5..53a4c0d0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1063,13 +1063,6 @@
         public static final int PRIVATE_FLAG_SHOW_FOR_ALL_USERS = 0x00000010;
 
         /**
-         * Special flag for the volume overlay: force the window manager out of "hide nav bar"
-         * mode while the window is on screen.
-         *
-         * {@hide} */
-        public static final int PRIVATE_FLAG_FORCE_SHOW_NAV_BAR = 0x00000020;
-
-        /**
          * Never animate position changes of the window.
          *
          * {@hide} */
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index c5a1b86c..d9e140e 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -16,7 +16,9 @@
 
 package android.view;
 
+import android.annotation.IntDef;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -27,6 +29,8 @@
 import android.view.animation.Animation;
 
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * This interface supplies all UI-specific behavior of the window manager.  An
@@ -464,6 +468,11 @@
     /** Screen turned off because of proximity sensor */
     public final int OFF_BECAUSE_OF_PROX_SENSOR = 4;
 
+    /** @hide */
+    @IntDef({USER_ROTATION_FREE, USER_ROTATION_LOCKED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UserRotationMode {}
+
     /** When not otherwise specified by the activity's screenOrientation, rotation should be
      * determined by the system (that is, using sensors). */
     public final int USER_ROTATION_FREE = 0;
@@ -1022,7 +1031,8 @@
      * @param lastRotation The most recently used rotation.
      * @return The surface rotation to use.
      */
-    public int rotationForOrientationLw(int orientation, int lastRotation);
+    public int rotationForOrientationLw(@ActivityInfo.ScreenOrientation int orientation,
+            int lastRotation);
 
     /**
      * Given an orientation constant and a rotation, returns true if the rotation
@@ -1037,7 +1047,8 @@
      * @param rotation The rotation to check.
      * @return True if the rotation is compatible with the requested orientation.
      */
-    public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation);
+    public boolean rotationHasCompatibleMetricsLw(@ActivityInfo.ScreenOrientation int orientation,
+            int rotation);
 
     /**
      * Called by the window manager when the rotation changes.
@@ -1086,7 +1097,7 @@
      */
     public void enableScreenAfterBoot();
     
-    public void setCurrentOrientationLw(int newOrientation);
+    public void setCurrentOrientationLw(@ActivityInfo.ScreenOrientation int newOrientation);
     
     /**
      * Call from application to perform haptic feedback on its window.
@@ -1113,6 +1124,7 @@
      * @see WindowManagerPolicy#USER_ROTATION_LOCKED
      * @see WindowManagerPolicy#USER_ROTATION_FREE 
      */
+    @UserRotationMode
     public int getUserRotationMode();
 
     /**
@@ -1123,12 +1135,12 @@
      * @param rotation One of {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
      *                 {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}.
      */
-    public void setUserRotationMode(int mode, int rotation);
+    public void setUserRotationMode(@UserRotationMode int mode, @Surface.Rotation int rotation);
 
     /**
      * Called when a new system UI visibility is being reported, allowing
      * the policy to adjust what is actually reported.
-     * @param visibility The raw visiblity reported by the status bar.
+     * @param visibility The raw visibility reported by the status bar.
      * @return The new desired visibility.
      */
     public int adjustSystemUiVisibilityLw(int visibility);
@@ -1151,6 +1163,11 @@
     public void setLastInputMethodWindowLw(WindowState ime, WindowState target);
 
     /**
+     * @return The current height of the input method window.
+     */
+    public int getInputMethodWindowVisibleHeightLw();
+
+    /**
      * Called when the current user changes. Guaranteed to be called before the broadcast
      * of the new user id is made to all listeners.
      *
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index f635eee..8b91155 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -722,7 +722,7 @@
     int mAction;
     int mContentChangeTypes;
 
-    private final ArrayList<AccessibilityRecord> mRecords = new ArrayList<AccessibilityRecord>();
+    private ArrayList<AccessibilityRecord> mRecords;
 
     /*
      * Hide constructor from clients.
@@ -755,11 +755,13 @@
     @Override
     public void setSealed(boolean sealed) {
         super.setSealed(sealed);
-        List<AccessibilityRecord> records = mRecords;
-        final int recordCount = records.size();
-        for (int i = 0; i < recordCount; i++) {
-            AccessibilityRecord record = records.get(i);
-            record.setSealed(sealed);
+        final List<AccessibilityRecord> records = mRecords;
+        if (records != null) {
+            final int recordCount = records.size();
+            for (int i = 0; i < recordCount; i++) {
+                AccessibilityRecord record = records.get(i);
+                record.setSealed(sealed);
+            }
         }
     }
 
@@ -769,7 +771,7 @@
      * @return The number of records.
      */
     public int getRecordCount() {
-        return mRecords.size();
+        return mRecords == null ? 0 : mRecords.size();
     }
 
     /**
@@ -781,6 +783,9 @@
      */
     public void appendRecord(AccessibilityRecord record) {
         enforceNotSealed();
+        if (mRecords == null) {
+            mRecords = new ArrayList<AccessibilityRecord>();
+        }
         mRecords.add(record);
     }
 
@@ -791,6 +796,9 @@
      * @return The record at the specified index.
      */
     public AccessibilityRecord getRecord(int index) {
+        if (mRecords == null) {
+            throw new IndexOutOfBoundsException("Invalid index " + index + ", size is 0");
+        }
         return mRecords.get(index);
     }
 
@@ -964,11 +972,14 @@
         AccessibilityEvent eventClone = AccessibilityEvent.obtain();
         eventClone.init(event);
 
-        final int recordCount = event.mRecords.size();
-        for (int i = 0; i < recordCount; i++) {
-            AccessibilityRecord record = event.mRecords.get(i);
-            AccessibilityRecord recordClone = AccessibilityRecord.obtain(record);
-            eventClone.mRecords.add(recordClone);
+        if (event.mRecords != null) {
+            final int recordCount = event.mRecords.size();
+            eventClone.mRecords = new ArrayList<AccessibilityRecord>(recordCount);
+            for (int i = 0; i < recordCount; i++) {
+                final AccessibilityRecord record = event.mRecords.get(i);
+                final AccessibilityRecord recordClone = AccessibilityRecord.obtain(record);
+                eventClone.mRecords.add(recordClone);
+            }
         }
 
         return eventClone;
@@ -1013,9 +1024,11 @@
         mContentChangeTypes = 0;
         mPackageName = null;
         mEventTime = 0;
-        while (!mRecords.isEmpty()) {
-            AccessibilityRecord record = mRecords.remove(0);
-            record.recycle();
+        if (mRecords != null) {
+            while (!mRecords.isEmpty()) {
+                AccessibilityRecord record = mRecords.remove(0);
+                record.recycle();
+            }
         }
     }
 
@@ -1037,11 +1050,14 @@
 
         // Read the records.
         final int recordCount = parcel.readInt();
-        for (int i = 0; i < recordCount; i++) {
-            AccessibilityRecord record = AccessibilityRecord.obtain();
-            readAccessibilityRecordFromParcel(record, parcel);
-            record.mConnectionId = mConnectionId;
-            mRecords.add(record);
+        if (recordCount > 0) {
+            mRecords = new ArrayList<AccessibilityRecord>(recordCount);
+            for (int i = 0; i < recordCount; i++) {
+                AccessibilityRecord record = AccessibilityRecord.obtain();
+                readAccessibilityRecordFromParcel(record, parcel);
+                record.mConnectionId = mConnectionId;
+                mRecords.add(record);
+            }
         }
     }
 
@@ -1147,8 +1163,8 @@
             builder.append("; ContentChangeTypes: ").append(mContentChangeTypes);
             builder.append("; sourceWindowId: ").append(mSourceWindowId);
             builder.append("; mSourceNodeId: ").append(mSourceNodeId);
-            for (int i = 0; i < mRecords.size(); i++) {
-                AccessibilityRecord record = mRecords.get(i);
+            for (int i = 0; i < getRecordCount(); i++) {
+                final AccessibilityRecord record = getRecord(i);
                 builder.append("  Record ");
                 builder.append(i);
                 builder.append(":");
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 139df3e..5a55e34 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -27,7 +27,6 @@
 import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.SparseArray;
-import android.util.SparseLongArray;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -718,10 +717,9 @@
                 Log.e(LOG_TAG, "Duplicate node.");
                 return;
             }
-            SparseLongArray childIds = current.getChildNodeIds();
-            final int childCount = childIds.size();
+            final int childCount = current.getChildCount();
             for (int i = 0; i < childCount; i++) {
-                final long childId = childIds.valueAt(i);
+                final long childId = current.getChildId(i);
                 for (int j = 0; j < infoCount; j++) {
                     AccessibilityNodeInfo child = infos.get(j);
                     if (child.getSourceNodeId() == childId) {
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 00f4adb..324ba77 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -75,6 +75,42 @@
     /** @hide */
     public static final int STATE_FLAG_TOUCH_EXPLORATION_ENABLED = 0x00000002;
 
+    /** @hide */
+    public static final int INVERSION_DISABLED = -1;
+
+    /** @hide */
+    public static final int INVERSION_STANDARD = 0;
+
+    /** @hide */
+    public static final int INVERSION_HUE_ONLY = 1;
+
+    /** @hide */
+    public static final int INVERSION_VALUE_ONLY = 2;
+
+    /** @hide */
+    public static final int DALTONIZER_DISABLED = -1;
+
+    /** @hide */
+    public static final int DALTONIZER_SIMULATE_MONOCHROMACY = 0;
+
+    /** @hide */
+    public static final int DALTONIZER_SIMULATE_PROTANOMALY = 1;
+
+    /** @hide */
+    public static final int DALTONIZER_SIMULATE_DEUTERANOMALY = 2;
+
+    /** @hide */
+    public static final int DALTONIZER_SIMULATE_TRITANOMALY = 3;
+
+    /** @hide */
+    public static final int DALTONIZER_CORRECT_PROTANOMALY = 11;
+
+    /** @hide */
+    public static final int DALTONIZER_CORRECT_DEUTERANOMALY = 12;
+
+    /** @hide */
+    public static final int DALTONIZER_CORRECT_TRITANOMALY = 13;
+
     static final Object sInstanceSync = new Object();
 
     private static AccessibilityManager sInstance;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 4f53c1e..61aabea 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -22,8 +22,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.InputType;
+import android.util.LongArray;
 import android.util.Pools.SynchronizedPool;
-import android.util.SparseLongArray;
 import android.view.View;
 
 import java.util.Collections;
@@ -503,7 +503,7 @@
     private CharSequence mContentDescription;
     private String mViewIdResourceName;
 
-    private final SparseLongArray mChildNodeIds = new SparseLongArray();
+    private LongArray mChildNodeIds;
     private int mActions;
 
     private int mMovementGranularities;
@@ -666,21 +666,35 @@
     }
 
     /**
-     * @return The ids of the children.
+     * Returns the array containing the IDs of this node's children.
      *
      * @hide
      */
-    public SparseLongArray getChildNodeIds() {
+    public LongArray getChildNodeIds() {
         return mChildNodeIds;
     }
 
     /**
+     * Returns the id of the child at the specified index.
+     *
+     * @throws IndexOutOfBoundsException when index &lt; 0 || index &gt;=
+     *             getChildCount()
+     * @hide
+     */
+    public long getChildId(int index) {
+        if (mChildNodeIds == null) {
+            throw new IndexOutOfBoundsException();
+        }
+        return mChildNodeIds.get(index);
+    }
+
+    /**
      * Gets the number of children.
      *
      * @return The child count.
      */
     public int getChildCount() {
-        return mChildNodeIds.size();
+        return mChildNodeIds == null ? 0 : mChildNodeIds.size();
     }
 
     /**
@@ -699,6 +713,9 @@
      */
     public AccessibilityNodeInfo getChild(int index) {
         enforceSealed();
+        if (mChildNodeIds == null) {
+            return null;
+        }
         if (!canPerformRequestOverConnection(mSourceNodeId)) {
             return null;
         }
@@ -721,7 +738,35 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void addChild(View child) {
-        addChild(child, UNDEFINED);
+        addChildInternal(child, UNDEFINED, true);
+    }
+
+    /**
+     * Unchecked version of {@link #addChild(View)} that does not verify
+     * uniqueness. For framework use only.
+     *
+     * @hide
+     */
+    public void addChildUnchecked(View child) {
+        addChildInternal(child, UNDEFINED, false);
+    }
+
+    /**
+     * Removes a child. If the child was not previously added to the node,
+     * calling this method has no effect.
+     * <p>
+     * <strong>Note:</strong> Cannot be called from an
+     * {@link android.accessibilityservice.AccessibilityService}.
+     * This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param child The child.
+     * @return true if the child was present
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public boolean removeChild(View child) {
+        return removeChild(child, UNDEFINED);
     }
 
     /**
@@ -739,12 +784,49 @@
      * @param virtualDescendantId The id of the virtual child.
      */
     public void addChild(View root, int virtualDescendantId) {
+        addChildInternal(root, virtualDescendantId, true);
+    }
+
+    private void addChildInternal(View root, int virtualDescendantId, boolean checked) {
         enforceNotSealed();
-        final int index = mChildNodeIds.size();
+        if (mChildNodeIds == null) {
+            mChildNodeIds = new LongArray();
+        }
         final int rootAccessibilityViewId =
             (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
         final long childNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
-        mChildNodeIds.put(index, childNodeId);
+        // If we're checking uniqueness and the ID already exists, abort.
+        if (checked && mChildNodeIds.indexOf(childNodeId) >= 0) {
+            return;
+        }
+        mChildNodeIds.add(childNodeId);
+    }
+
+    /**
+     * Removes a virtual child which is a descendant of the given
+     * <code>root</code>. If the child was not previously added to the node,
+     * calling this method has no effect.
+     *
+     * @param root The root of the virtual subtree.
+     * @param virtualDescendantId The id of the virtual child.
+     * @return true if the child was present
+     * @see #addChild(View, int)
+     */
+    public boolean removeChild(View root, int virtualDescendantId) {
+        enforceNotSealed();
+        final LongArray childIds = mChildNodeIds;
+        if (childIds == null) {
+            return false;
+        }
+        final int rootAccessibilityViewId =
+                (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
+        final long childNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
+        final int index = childIds.indexOf(childNodeId);
+        if (index < 0) {
+            return false;
+        }
+        childIds.remove(index);
+        return true;
     }
 
     /**
@@ -789,6 +871,24 @@
     }
 
     /**
+     * Removes an action that can be performed on the node. If the action was
+     * not already added to the node, calling this method has no effect.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param action The action.
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public void removeAction(int action) {
+        enforceNotSealed();
+        mActions &= ~action;
+    }
+
+    /**
      * Sets the movement granularities for traversing the text of this node.
      * <p>
      *   <strong>Note:</strong> Cannot be called from an
@@ -1408,8 +1508,6 @@
      *   {@link android.accessibilityservice.AccessibilityService}.
      *   This class is made immutable before being delivered to an AccessibilityService.
      * </p>
-     *
-     * @return collectionItem True if the node is an item.
      */
     public void setCollectionItemInfo(CollectionItemInfo collectionItemInfo) {
         enforceNotSealed();
@@ -1951,6 +2049,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public int describeContents() {
         return 0;
     }
@@ -2114,6 +2213,7 @@
      *      is recycled. You must not touch the object after calling this function.
      * </p>
      */
+    @Override
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(isSealed() ? 1 : 0);
         parcel.writeLong(mSourceNodeId);
@@ -2123,11 +2223,15 @@
         parcel.writeLong(mLabeledById);
         parcel.writeInt(mConnectionId);
 
-        SparseLongArray childIds = mChildNodeIds;
-        final int childIdsSize = childIds.size();
-        parcel.writeInt(childIdsSize);
-        for (int i = 0; i < childIdsSize; i++) {
-            parcel.writeLong(childIds.valueAt(i));
+        final LongArray childIds = mChildNodeIds;
+        if (childIds == null) {
+            parcel.writeInt(0);
+        } else {
+            final int childIdsSize = childIds.size();
+            parcel.writeInt(childIdsSize);
+            for (int i = 0; i < childIdsSize; i++) {
+                parcel.writeLong(childIds.get(i));
+            }
         }
 
         parcel.writeInt(mBoundsInParent.top);
@@ -2222,10 +2326,16 @@
         mActions= other.mActions;
         mBooleanProperties = other.mBooleanProperties;
         mMovementGranularities = other.mMovementGranularities;
-        final int otherChildIdCount = other.mChildNodeIds.size();
-        for (int i = 0; i < otherChildIdCount; i++) {
-            mChildNodeIds.put(i, other.mChildNodeIds.valueAt(i));
+
+        final LongArray otherChildNodeIds = other.mChildNodeIds;
+        if (otherChildNodeIds != null && otherChildNodeIds.size() > 0) {
+            if (mChildNodeIds == null) {
+                mChildNodeIds = otherChildNodeIds.clone();
+            } else {
+                mChildNodeIds.addAll(otherChildNodeIds);
+            }
         }
+
         mTextSelectionStart = other.mTextSelectionStart;
         mTextSelectionEnd = other.mTextSelectionEnd;
         mInputType = other.mInputType;
@@ -2255,11 +2365,15 @@
         mLabeledById = parcel.readLong();
         mConnectionId = parcel.readInt();
 
-        SparseLongArray childIds = mChildNodeIds;
         final int childrenSize = parcel.readInt();
-        for (int i = 0; i < childrenSize; i++) {
-            final long childId = parcel.readLong();
-            childIds.put(i, childId);
+        if (childrenSize <= 0) {
+            mChildNodeIds = null;
+        } else {
+            mChildNodeIds = new LongArray(childrenSize);
+            for (int i = 0; i < childrenSize; i++) {
+                final long childId = parcel.readLong();
+                mChildNodeIds.add(childId);
+            }
         }
 
         mBoundsInParent.top = parcel.readInt();
@@ -2331,7 +2445,9 @@
         mWindowId = UNDEFINED;
         mConnectionId = UNDEFINED;
         mMovementGranularities = 0;
-        mChildNodeIds.clear();
+        if (mChildNodeIds != null) {
+            mChildNodeIds.clear();
+        }
         mBoundsInParent.set(0, 0, 0, 0);
         mBoundsInScreen.set(0, 0, 0, 0);
         mBooleanProperties = 0;
@@ -2493,12 +2609,14 @@
             }
             builder.append("]");
 
-            SparseLongArray childIds = mChildNodeIds;
             builder.append("; childAccessibilityIds: [");
-            for (int i = 0, count = childIds.size(); i < count; i++) {
-                builder.append(childIds.valueAt(i));
-                if (i < count - 1) {
-                    builder.append(", ");
+            final LongArray childIds = mChildNodeIds;
+            if (childIds != null) {
+                for (int i = 0, count = childIds.size(); i < count; i++) {
+                    builder.append(childIds.get(i));
+                    if (i < count - 1) {
+                        builder.append(", ");
+                    }
                 }
             }
             builder.append("]");
@@ -2893,16 +3011,18 @@
     }
 
     /**
-     * @see Parcelable.Creator
+     * @see android.os.Parcelable.Creator
      */
     public static final Parcelable.Creator<AccessibilityNodeInfo> CREATOR =
             new Parcelable.Creator<AccessibilityNodeInfo>() {
+        @Override
         public AccessibilityNodeInfo createFromParcel(Parcel parcel) {
             AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
             info.initFromParcel(parcel);
             return info;
         }
 
+        @Override
         public AccessibilityNodeInfo[] newArray(int size) {
             return new AccessibilityNodeInfo[size];
         }
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
index a9473a8..3f79b47 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
@@ -18,8 +18,8 @@
 
 import android.os.Build;
 import android.util.Log;
+import android.util.LongArray;
 import android.util.LongSparseArray;
-import android.util.SparseLongArray;
 
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -172,12 +172,12 @@
                     // the new one represents a source state where some of the
                     // children have been removed to avoid having disconnected
                     // subtrees in the cache.
-                    SparseLongArray oldChildrenIds = oldInfo.getChildNodeIds();
-                    SparseLongArray newChildrenIds = info.getChildNodeIds();
-                    final int oldChildCount = oldChildrenIds.size();
+                    // TODO: Runs in O(n^2), could optimize to O(n + n log n)
+                    final LongArray newChildrenIds = info.getChildNodeIds();
+                    final int oldChildCount = oldInfo.getChildCount();
                     for (int i = 0; i < oldChildCount; i++) {
-                        final long oldChildId = oldChildrenIds.valueAt(i);
-                        if (newChildrenIds.indexOfValue(oldChildId) < 0) {
+                        final long oldChildId = oldInfo.getChildId(i);
+                        if (newChildrenIds.indexOf(oldChildId) < 0) {
                             clearSubTreeLocked(oldChildId);
                         }
                     }
@@ -237,10 +237,9 @@
             return;
         }
         mCacheImpl.remove(rootNodeId);
-        SparseLongArray childNodeIds = current.getChildNodeIds();
-        final int childCount = childNodeIds.size();
+        final int childCount = current.getChildCount();
         for (int i = 0; i < childCount; i++) {
-            final long childNodeId = childNodeIds.valueAt(i);
+            final long childNodeId = current.getChildId(i);
             clearSubTreeRecursiveLocked(childNodeId);
         }
     }
@@ -301,11 +300,10 @@
                     }
                 }
 
-                SparseLongArray childIds = current.getChildNodeIds();
-                final int childCount = childIds.size();
+                final int childCount = current.getChildCount();
                 for (int i = 0; i < childCount; i++) {
-                    final long childId = childIds.valueAt(i);
-                    AccessibilityNodeInfo child = mCacheImpl.get(childId);
+                    final long childId = current.getChildId(i);
+                    final AccessibilityNodeInfo child = mCacheImpl.get(childId);
                     if (child != null) {
                         fringe.add(child);
                     }
diff --git a/core/java/android/view/animation/BounceInterpolator.java b/core/java/android/view/animation/BounceInterpolator.java
index f79e730..ecf99a7 100644
--- a/core/java/android/view/animation/BounceInterpolator.java
+++ b/core/java/android/view/animation/BounceInterpolator.java
@@ -17,7 +17,6 @@
 package android.view.animation;
 
 import android.content.Context;
-import android.content.res.TypedArray;
 import android.util.AttributeSet;
 
 /**
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index f730cf7..5552952 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -601,7 +601,11 @@
         }
         
         beginBatchEdit();
-        
+        if (!composing && !TextUtils.isEmpty(text)) {
+            // Notify the text is committed by the user to InputMethodManagerService
+            mIMM.notifyTextCommitted();
+        }
+
         // delete composing text set previously.
         int a = getComposingSpanStart(content);
         int b = getComposingSpanEnd(content);
diff --git a/core/java/android/view/inputmethod/ExtractedTextRequest.java b/core/java/android/view/inputmethod/ExtractedTextRequest.java
index f658b87..bf0bef3 100644
--- a/core/java/android/view/inputmethod/ExtractedTextRequest.java
+++ b/core/java/android/view/inputmethod/ExtractedTextRequest.java
@@ -18,7 +18,6 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.text.TextUtils;
 
 /**
  * Description of what an input method would like from an application when
diff --git a/core/java/android/view/inputmethod/InputBinding.java b/core/java/android/view/inputmethod/InputBinding.java
index f4209ef..bcd459e 100644
--- a/core/java/android/view/inputmethod/InputBinding.java
+++ b/core/java/android/view/inputmethod/InputBinding.java
@@ -19,7 +19,6 @@
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.text.TextUtils;
 
 /**
  * Information given to an {@link InputMethod} about a client connecting
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 53f7c79..70c53d2 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1805,6 +1805,20 @@
     }
 
     /**
+     * Notify the current IME commits text
+     * @hide
+     */
+    public void notifyTextCommitted() {
+        synchronized (mH) {
+            try {
+                mService.notifyTextCommitted();
+            } catch (RemoteException e) {
+                Log.w(TAG, "IME died: " + mCurId, e);
+            }
+        }
+    }
+
+    /**
      * Returns a map of all shortcut input method info and their subtypes.
      */
     public Map<InputMethodInfo, List<InputMethodSubtype>> getShortcutInputMethodsAndSubtypes() {
@@ -1840,6 +1854,21 @@
     }
 
     /**
+     * @return The current height of the input method window.
+     * @hide
+     */
+    public int getInputMethodWindowVisibleHeight() {
+        synchronized (mH) {
+            try {
+                return mService.getInputMethodWindowVisibleHeight();
+            } catch (RemoteException e) {
+                Log.w(TAG, "IME died: " + mCurId, e);
+                return 0;
+            }
+        }
+    }
+
+    /**
      * Force switch to the last used input method and subtype. If the last input method didn't have
      * any subtypes, the framework will simply switch to the last input method with no subtype
      * specified.
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index 2ab3024..e7ada27 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -472,12 +472,12 @@
                 return (subtype.hashCode() == hashCode());
             }
             return (subtype.hashCode() == hashCode())
-                && (subtype.getNameResId() == getNameResId())
-                && (subtype.getMode().equals(getMode()))
-                && (subtype.getIconResId() == getIconResId())
                 && (subtype.getLocale().equals(getLocale()))
+                && (subtype.getMode().equals(getMode()))
                 && (subtype.getExtraValue().equals(getExtraValue()))
                 && (subtype.isAuxiliary() == isAuxiliary())
+                && (subtype.overridesImplicitlyEnabledSubtype()
+                        == overridesImplicitlyEnabledSubtype())
                 && (subtype.isAsciiCapable() == isAsciiCapable());
         }
         return false;
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index bbd3f2b..45e6eb3 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -16,13 +16,7 @@
 
 package android.webkit;
 
-import android.content.Context;
-import android.net.http.Headers;
-import android.util.Log;
-
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
diff --git a/core/java/android/webkit/DateSorter.java b/core/java/android/webkit/DateSorter.java
index 82c13ae..fede244 100644
--- a/core/java/android/webkit/DateSorter.java
+++ b/core/java/android/webkit/DateSorter.java
@@ -20,7 +20,6 @@
 import android.content.res.Resources;
 
 import java.util.Calendar;
-import java.util.Date;
 import java.util.Locale;
 
 import libcore.icu.LocaleData;
diff --git a/core/java/android/webkit/Plugin.java b/core/java/android/webkit/Plugin.java
index 529820b..072e02a 100644
--- a/core/java/android/webkit/Plugin.java
+++ b/core/java/android/webkit/Plugin.java
@@ -21,7 +21,6 @@
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.webkit.WebView;
 
 /**
  * Represents a plugin (Java equivalent of the PluginPackageAndroid
diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java
index b7171ee..f21e2b4 100644
--- a/core/java/android/webkit/WebResourceResponse.java
+++ b/core/java/android/webkit/WebResourceResponse.java
@@ -16,8 +16,6 @@
 
 package android.webkit;
 
-import android.net.http.Headers;
-
 import java.io.InputStream;
 
 /**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 5bc39f15..7ee33c1 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -28,7 +28,6 @@
 import android.net.http.SslCertificate;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.CancellationSignal;
 import android.os.Looper;
 import android.os.Message;
 import android.os.StrictMode;
@@ -255,7 +254,7 @@
     // Throwing an exception for incorrect thread usage if the
     // build target is JB MR2 or newer. Defaults to false, and is
     // set in the WebView constructor.
-    private static Boolean sEnforceThreadChecking = false;
+    private static volatile boolean sEnforceThreadChecking = false;
 
     /**
      *  Transportation object for returning WebView across thread boundaries.
@@ -449,10 +448,12 @@
      *
      * @param context a Context object used to access application assets
      * @param attrs an AttributeSet passed to our parent
-     * @param defStyle the default style resource ID
+     * @param defStyleAttr an attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public WebView(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, false);
+    public WebView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
     /**
@@ -460,7 +461,26 @@
      *
      * @param context a Context object used to access application assets
      * @param attrs an AttributeSet passed to our parent
-     * @param defStyle the default style resource ID
+     * @param defStyleAttr an attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes a resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     */
+    public WebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        this(context, attrs, defStyleAttr, defStyleRes, null, false);
+    }
+
+    /**
+     * Constructs a new WebView with layout parameters and a default style.
+     *
+     * @param context a Context object used to access application assets
+     * @param attrs an AttributeSet passed to our parent
+     * @param defStyleAttr an attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      * @param privateBrowsing whether this WebView will be initialized in
      *                        private mode
      *
@@ -470,9 +490,9 @@
      * and {@link WebStorage} for fine-grained control of privacy data.
      */
     @Deprecated
-    public WebView(Context context, AttributeSet attrs, int defStyle,
+    public WebView(Context context, AttributeSet attrs, int defStyleAttr,
             boolean privateBrowsing) {
-        this(context, attrs, defStyle, null, privateBrowsing);
+        this(context, attrs, defStyleAttr, 0, null, privateBrowsing);
     }
 
     /**
@@ -483,7 +503,9 @@
      *
      * @param context a Context object used to access application assets
      * @param attrs an AttributeSet passed to our parent
-     * @param defStyle the default style resource ID
+     * @param defStyleAttr an attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      * @param javaScriptInterfaces a Map of interface names, as keys, and
      *                             object implementing those interfaces, as
      *                             values
@@ -492,10 +514,18 @@
      * @hide This is used internally by dumprendertree, as it requires the javaScript interfaces to
      *       be added synchronously, before a subsequent loadUrl call takes effect.
      */
-    @SuppressWarnings("deprecation")  // for super() call into deprecated base class constructor.
-    protected WebView(Context context, AttributeSet attrs, int defStyle,
+    protected WebView(Context context, AttributeSet attrs, int defStyleAttr,
             Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
-        super(context, attrs, defStyle);
+        this(context, attrs, defStyleAttr, 0, javaScriptInterfaces, privateBrowsing);
+    }
+
+    /**
+     * @hide
+     */
+    @SuppressWarnings("deprecation")  // for super() call into deprecated base class constructor.
+    protected WebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes,
+            Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         if (context == null) {
             throw new IllegalArgumentException("Invalid context argument");
         }
@@ -686,6 +716,15 @@
     }
 
     /**
+     * Used only by internal tests to free up memory.
+     *
+     * @hide
+     */
+    public static void freeMemoryForTests() {
+        getFactory().getStatics().freeMemoryForTests();
+    }
+
+    /**
      * Informs WebView of the network state. This is used to set
      * the JavaScript property window.navigator.isOnline and
      * generates the online/offline event as specified in HTML5, sec. 5.7.7
@@ -781,7 +820,15 @@
      */
     public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
         checkThread();
-        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadUrl(extra headers)=" + url);
+        if (DebugFlags.TRACE_API) {
+            StringBuilder headers = new StringBuilder();
+            if (additionalHttpHeaders != null) {
+                for (Map.Entry<String, String> entry : additionalHttpHeaders.entrySet()) {
+                    headers.append(entry.getKey() + ":" + entry.getValue() + "\n");
+                }
+            }
+            Log.d(LOGTAG, "loadUrl(extra headers)=" + url + "\n" + headers);
+        }
         mProvider.loadUrl(url, additionalHttpHeaders);
     }
 
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index b9131bf..25bcd44 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -16,9 +16,7 @@
 
 package android.webkit;
 
-import android.os.Build;
 import android.os.StrictMode;
-import android.os.SystemProperties;
 import android.util.AndroidRuntimeException;
 import android.util.Log;
 
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index 9d9d882..e391aaf 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -50,6 +50,11 @@
         String getDefaultUserAgent(Context context);
 
         /**
+         * Used for tests only.
+         */
+         void freeMemoryForTests();
+
+        /**
          * Implements the API method:
          * {@link android.webkit.WebView#setWebContentsDebuggingEnabled(boolean) }
          */
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 092f474..413d6cfb 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -55,6 +55,7 @@
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.ViewParent;
+import android.view.ViewRootImpl;
 import android.view.ViewTreeObserver;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -581,7 +582,13 @@
     /**
      * Helper object that renders and controls the fast scroll thumb.
      */
-    private FastScroller mFastScroller;
+    private FastScroller mFastScroll;
+
+    /**
+     * Temporary holder for fast scroller style until a FastScroller object
+     * is created.
+     */
+    private int mFastScrollStyle;
 
     private boolean mGlobalLayoutListenerAddedFilter;
 
@@ -773,14 +780,18 @@
         this(context, attrs, com.android.internal.R.attr.absListViewStyle);
     }
 
-    public AbsListView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public AbsListView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AbsListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initAbsListView();
 
         mOwnerThread = Thread.currentThread();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.AbsListView, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.AbsListView, defStyleAttr, defStyleRes);
 
         Drawable d = a.getDrawable(com.android.internal.R.styleable.AbsListView_listSelector);
         if (d != null) {
@@ -809,6 +820,9 @@
         boolean enableFastScroll = a.getBoolean(R.styleable.AbsListView_fastScrollEnabled, false);
         setFastScrollEnabled(enableFastScroll);
 
+        int fastScrollStyle = a.getResourceId(R.styleable.AbsListView_fastScrollStyle, 0);
+        setFastScrollStyle(fastScrollStyle);
+
         boolean smoothScrollbar = a.getBoolean(R.styleable.AbsListView_smoothScrollbar, true);
         setSmoothScrollbarEnabled(smoothScrollbar);
 
@@ -1238,17 +1252,31 @@
     }
 
     private void setFastScrollerEnabledUiThread(boolean enabled) {
-        if (mFastScroller != null) {
-            mFastScroller.setEnabled(enabled);
+        if (mFastScroll != null) {
+            mFastScroll.setEnabled(enabled);
         } else if (enabled) {
-            mFastScroller = new FastScroller(this);
-            mFastScroller.setEnabled(true);
+            mFastScroll = new FastScroller(this, mFastScrollStyle);
+            mFastScroll.setEnabled(true);
         }
 
         resolvePadding();
 
-        if (mFastScroller != null) {
-            mFastScroller.updateLayout();
+        if (mFastScroll != null) {
+            mFastScroll.updateLayout();
+        }
+    }
+
+    /**
+     * Specifies the style of the fast scroller decorations.
+     *
+     * @param styleResId style resource containing fast scroller properties
+     * @see android.R.styleable#FastScroll
+     */
+    public void setFastScrollStyle(int styleResId) {
+        if (mFastScroll == null) {
+            mFastScrollStyle = styleResId;
+        } else {
+            mFastScroll.setStyle(styleResId);
         }
     }
 
@@ -1288,8 +1316,8 @@
     }
 
     private void setFastScrollerAlwaysVisibleUiThread(boolean alwaysShow) {
-        if (mFastScroller != null) {
-            mFastScroller.setAlwaysShow(alwaysShow);
+        if (mFastScroll != null) {
+            mFastScroll.setAlwaysShow(alwaysShow);
         }
     }
 
@@ -1307,17 +1335,17 @@
      * @see #setFastScrollAlwaysVisible(boolean)
      */
     public boolean isFastScrollAlwaysVisible() {
-        if (mFastScroller == null) {
+        if (mFastScroll == null) {
             return mFastScrollEnabled && mFastScrollAlwaysVisible;
         } else {
-            return mFastScroller.isEnabled() && mFastScroller.isAlwaysShowEnabled();
+            return mFastScroll.isEnabled() && mFastScroll.isAlwaysShowEnabled();
         }
     }
 
     @Override
     public int getVerticalScrollbarWidth() {
-        if (mFastScroller != null && mFastScroller.isEnabled()) {
-            return Math.max(super.getVerticalScrollbarWidth(), mFastScroller.getWidth());
+        if (mFastScroll != null && mFastScroll.isEnabled()) {
+            return Math.max(super.getVerticalScrollbarWidth(), mFastScroll.getWidth());
         }
         return super.getVerticalScrollbarWidth();
     }
@@ -1330,26 +1358,26 @@
      */
     @ViewDebug.ExportedProperty
     public boolean isFastScrollEnabled() {
-        if (mFastScroller == null) {
+        if (mFastScroll == null) {
             return mFastScrollEnabled;
         } else {
-            return mFastScroller.isEnabled();
+            return mFastScroll.isEnabled();
         }
     }
 
     @Override
     public void setVerticalScrollbarPosition(int position) {
         super.setVerticalScrollbarPosition(position);
-        if (mFastScroller != null) {
-            mFastScroller.setScrollbarPosition(position);
+        if (mFastScroll != null) {
+            mFastScroll.setScrollbarPosition(position);
         }
     }
 
     @Override
     public void setScrollBarStyle(int style) {
         super.setScrollBarStyle(style);
-        if (mFastScroller != null) {
-            mFastScroller.setScrollBarStyle(style);
+        if (mFastScroll != null) {
+            mFastScroll.setScrollBarStyle(style);
         }
     }
 
@@ -1410,8 +1438,8 @@
      * Notify our scroll listener (if there is one) of a change in scroll state
      */
     void invokeOnItemScrollListener() {
-        if (mFastScroller != null) {
-            mFastScroller.onScroll(mFirstPosition, getChildCount(), mItemCount);
+        if (mFastScroll != null) {
+            mFastScroll.onScroll(mFirstPosition, getChildCount(), mItemCount);
         }
         if (mOnScrollListener != null) {
             mOnScrollListener.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
@@ -2084,8 +2112,8 @@
             mRecycler.markChildrenDirty();
         }
 
-        if (mFastScroller != null && (mItemCount != mOldItemCount || mDataChanged)) {
-            mFastScroller.onItemCountChanged(mItemCount);
+        if (mFastScroll != null && (mItemCount != mOldItemCount || mDataChanged)) {
+            mFastScroll.onItemCountChanged(mItemCount);
         }
 
         layoutChildren();
@@ -2120,6 +2148,34 @@
     protected void layoutChildren() {
     }
 
+    /**
+     * @return the direct child that contains accessibility focus, or null if no
+     *         child contains accessibility focus
+     */
+    View getAccessibilityFocusedChild() {
+        final ViewRootImpl viewRootImpl = getViewRootImpl();
+        if (viewRootImpl == null) {
+            return null;
+        }
+
+        View focusedView = viewRootImpl.getAccessibilityFocusedHost();
+        if (focusedView == null) {
+            return null;
+        }
+
+        ViewParent viewParent = focusedView.getParent();
+        while ((viewParent instanceof View) && (viewParent != this)) {
+            focusedView = (View) viewParent;
+            viewParent = viewParent.getParent();
+        }
+
+        if (!(viewParent instanceof View)) {
+            return null;
+        }
+
+        return focusedView;
+    }
+
     void updateScrollIndicators() {
         if (mScrollUp != null) {
             boolean canScrollUp;
@@ -2499,8 +2555,8 @@
             rememberSyncState();
         }
 
-        if (mFastScroller != null) {
-            mFastScroller.onSizeChanged(w, h, oldw, oldh);
+        if (mFastScroll != null) {
+            mFastScroll.onSizeChanged(w, h, oldw, oldh);
         }
     }
 
@@ -2829,8 +2885,8 @@
     @Override
     public void onRtlPropertiesChanged(int layoutDirection) {
         super.onRtlPropertiesChanged(layoutDirection);
-        if (mFastScroller != null) {
-           mFastScroller.setScrollbarPosition(getVerticalScrollbarPosition());
+        if (mFastScroll != null) {
+           mFastScroll.setScrollbarPosition(getVerticalScrollbarPosition());
         }
     }
 
@@ -3403,8 +3459,8 @@
             return false;
         }
 
-        if (mFastScroller != null) {
-            boolean intercepted = mFastScroller.onTouchEvent(ev);
+        if (mFastScroll != null) {
+            boolean intercepted = mFastScroll.onTouchEvent(ev);
             if (intercepted) {
                 return true;
             }
@@ -3893,7 +3949,7 @@
 
     @Override
     public boolean onInterceptHoverEvent(MotionEvent event) {
-        if (mFastScroller != null && mFastScroller.onInterceptHoverEvent(event)) {
+        if (mFastScroll != null && mFastScroll.onInterceptHoverEvent(event)) {
             return true;
         }
 
@@ -3917,7 +3973,7 @@
             return false;
         }
 
-        if (mFastScroller != null && mFastScroller.onInterceptTouchEvent(ev)) {
+        if (mFastScroll != null && mFastScroll.onInterceptTouchEvent(ev)) {
             return true;
         }
 
@@ -6278,16 +6334,16 @@
         @Override
         public void onChanged() {
             super.onChanged();
-            if (mFastScroller != null) {
-                mFastScroller.onSectionsChanged();
+            if (mFastScroll != null) {
+                mFastScroll.onSectionsChanged();
             }
         }
 
         @Override
         public void onInvalidated() {
             super.onInvalidated();
-            if (mFastScroller != null) {
-                mFastScroller.onSectionsChanged();
+            if (mFastScroll != null) {
+                mFastScroll.onSectionsChanged();
             }
         }
     }
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 7674837..941cdd0 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -65,11 +65,15 @@
         super(context, attrs);
     }
 
-    public AbsSeekBar(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public AbsSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.SeekBar, defStyle, 0);
+    public AbsSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.SeekBar, defStyleAttr, defStyleRes);
         Drawable thumb = a.getDrawable(com.android.internal.R.styleable.SeekBar_thumb);
         setThumb(thumb); // will guess mThumbOffset if thumb != null...
         // ...but allow layout to override this
diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java
index f26527f..6a4ad75 100644
--- a/core/java/android/widget/AbsSpinner.java
+++ b/core/java/android/widget/AbsSpinner.java
@@ -64,12 +64,16 @@
         this(context, attrs, 0);
     }
 
-    public AbsSpinner(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public AbsSpinner(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AbsSpinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initAbsSpinner();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.AbsSpinner, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.AbsSpinner, defStyleAttr, defStyleRes);
 
         CharSequence[] entries = a.getTextArray(R.styleable.AbsSpinner_entries);
         if (entries != null) {
diff --git a/core/java/android/widget/AbsoluteLayout.java b/core/java/android/widget/AbsoluteLayout.java
index 7df6aab..4ce0d5d 100644
--- a/core/java/android/widget/AbsoluteLayout.java
+++ b/core/java/android/widget/AbsoluteLayout.java
@@ -40,16 +40,19 @@
 @RemoteView
 public class AbsoluteLayout extends ViewGroup {
     public AbsoluteLayout(Context context) {
-        super(context);
+        this(context, null);
     }
 
     public AbsoluteLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
     }
 
-    public AbsoluteLayout(Context context, AttributeSet attrs,
-            int defStyle) {
-        super(context, attrs, defStyle);
+    public AbsoluteLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AbsoluteLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 8612964..f9af2f9 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -18,7 +18,6 @@
 
 import com.android.internal.R;
 
-import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -31,7 +30,6 @@
 import android.util.Log;
 import android.view.ActionProvider;
 import android.view.LayoutInflater;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
@@ -204,13 +202,32 @@
      *
      * @param context The application environment.
      * @param attrs A collection of attributes.
-     * @param defStyle The default style to apply to this view.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public ActivityChooserView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ActivityChooserView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * Create a new instance.
+     *
+     * @param context The application environment.
+     * @param attrs A collection of attributes.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     */
+    public ActivityChooserView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         TypedArray attributesArray = context.obtainStyledAttributes(attrs,
-                R.styleable.ActivityChooserView, defStyle, 0);
+                R.styleable.ActivityChooserView, defStyleAttr, defStyleRes);
 
         mInitialActivityCount = attributesArray.getInt(
                 R.styleable.ActivityChooserView_initialActivityCount,
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index a5fad60..962ffba 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -223,15 +223,19 @@
     boolean mBlockLayoutRequests = false;
 
     public AdapterView(Context context) {
-        super(context);
+        this(context, null);
     }
 
     public AdapterView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
     }
 
-    public AdapterView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public AdapterView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AdapterView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         // If not explicitly specified this view is important for accessibility.
         if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 90e949a..1bc2f4b 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -173,10 +173,15 @@
     }
 
     public AdapterViewAnimator(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.AdapterViewAnimator, defStyleAttr, 0);
+    public AdapterViewAnimator(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.AdapterViewAnimator, defStyleAttr, defStyleRes);
         int resource = a.getResourceId(
                 com.android.internal.R.styleable.AdapterViewAnimator_inAnimation, 0);
         if (resource > 0) {
diff --git a/core/java/android/widget/AdapterViewFlipper.java b/core/java/android/widget/AdapterViewFlipper.java
index aea029b..3b026bd 100644
--- a/core/java/android/widget/AdapterViewFlipper.java
+++ b/core/java/android/widget/AdapterViewFlipper.java
@@ -59,10 +59,19 @@
     }
 
     public AdapterViewFlipper(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.AdapterViewFlipper);
+    public AdapterViewFlipper(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AdapterViewFlipper(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.AdapterViewFlipper, defStyleAttr, defStyleRes);
         mFlipInterval = a.getInt(
                 com.android.internal.R.styleable.AdapterViewFlipper_flipInterval, DEFAULT_INTERVAL);
         mAutoStart = a.getBoolean(
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index c7da818..3c88e94 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -67,13 +67,16 @@
         this(context, attrs, 0);
     }
 
-    public AnalogClock(Context context, AttributeSet attrs,
-                       int defStyle) {
-        super(context, attrs, defStyle);
-        Resources r = mContext.getResources();
-        TypedArray a =
-                context.obtainStyledAttributes(
-                        attrs, com.android.internal.R.styleable.AnalogClock, defStyle, 0);
+    public AnalogClock(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AnalogClock(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final Resources r = context.getResources();
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.AnalogClock, defStyleAttr, defStyleRes);
 
         mDial = a.getDrawable(com.android.internal.R.styleable.AnalogClock_dial);
         if (mDial == null) {
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index f0eb94f..259c66b9 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -133,17 +133,21 @@
         this(context, attrs, com.android.internal.R.attr.autoCompleteTextViewStyle);
     }
 
-    public AutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public AutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AutoCompleteTextView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         mPopup = new ListPopupWindow(context, attrs,
                 com.android.internal.R.attr.autoCompleteTextViewStyle);
         mPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
         mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW);
 
-        TypedArray a =
-            context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.AutoCompleteTextView, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.AutoCompleteTextView, defStyleAttr, defStyleRes);
 
         mThreshold = a.getInt(
                 R.styleable.AutoCompleteTextView_completionThreshold, 2);
diff --git a/core/java/android/widget/BaseAdapter.java b/core/java/android/widget/BaseAdapter.java
index 401fcb8..c960342 100644
--- a/core/java/android/widget/BaseAdapter.java
+++ b/core/java/android/widget/BaseAdapter.java
@@ -24,8 +24,8 @@
 /**
  * Common base class of common implementation for an {@link Adapter} that can be
  * used in both {@link ListView} (by implementing the specialized
- * {@link ListAdapter} interface} and {@link Spinner} (by implementing the
- * specialized {@link SpinnerAdapter} interface.
+ * {@link ListAdapter} interface) and {@link Spinner} (by implementing the
+ * specialized {@link SpinnerAdapter} interface).
  */
 public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
     private final DataSetObservable mDataSetObservable = new DataSetObservable();
diff --git a/core/java/android/widget/Button.java b/core/java/android/widget/Button.java
index 2ac56ac..1663620 100644
--- a/core/java/android/widget/Button.java
+++ b/core/java/android/widget/Button.java
@@ -103,8 +103,12 @@
         this(context, attrs, com.android.internal.R.attr.buttonStyle);
     }
 
-    public Button(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public Button(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public Button(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index 0957ab4..a87c7d2 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -80,234 +80,7 @@
      */
     private static final String LOG_TAG = CalendarView.class.getSimpleName();
 
-    /**
-     * Default value whether to show week number.
-     */
-    private static final boolean DEFAULT_SHOW_WEEK_NUMBER = true;
-
-    /**
-     * The number of milliseconds in a day.e
-     */
-    private static final long MILLIS_IN_DAY = 86400000L;
-
-    /**
-     * The number of day in a week.
-     */
-    private static final int DAYS_PER_WEEK = 7;
-
-    /**
-     * The number of milliseconds in a week.
-     */
-    private static final long MILLIS_IN_WEEK = DAYS_PER_WEEK * MILLIS_IN_DAY;
-
-    /**
-     * Affects when the month selection will change while scrolling upe
-     */
-    private static final int SCROLL_HYST_WEEKS = 2;
-
-    /**
-     * How long the GoTo fling animation should last.
-     */
-    private static final int GOTO_SCROLL_DURATION = 1000;
-
-    /**
-     * The duration of the adjustment upon a user scroll in milliseconds.
-     */
-    private static final int ADJUSTMENT_SCROLL_DURATION = 500;
-
-    /**
-     * How long to wait after receiving an onScrollStateChanged notification
-     * before acting on it.
-     */
-    private static final int SCROLL_CHANGE_DELAY = 40;
-
-    /**
-     * String for parsing dates.
-     */
-    private static final String DATE_FORMAT = "MM/dd/yyyy";
-
-    /**
-     * The default minimal date.
-     */
-    private static final String DEFAULT_MIN_DATE = "01/01/1900";
-
-    /**
-     * The default maximal date.
-     */
-    private static final String DEFAULT_MAX_DATE = "01/01/2100";
-
-    private static final int DEFAULT_SHOWN_WEEK_COUNT = 6;
-
-    private static final int DEFAULT_DATE_TEXT_SIZE = 14;
-
-    private static final int UNSCALED_SELECTED_DATE_VERTICAL_BAR_WIDTH = 6;
-
-    private static final int UNSCALED_WEEK_MIN_VISIBLE_HEIGHT = 12;
-
-    private static final int UNSCALED_LIST_SCROLL_TOP_OFFSET = 2;
-
-    private static final int UNSCALED_BOTTOM_BUFFER = 20;
-
-    private static final int UNSCALED_WEEK_SEPARATOR_LINE_WIDTH = 1;
-
-    private static final int DEFAULT_WEEK_DAY_TEXT_APPEARANCE_RES_ID = -1;
-
-    private final int mWeekSeperatorLineWidth;
-
-    private int mDateTextSize;
-
-    private Drawable mSelectedDateVerticalBar;
-
-    private final int mSelectedDateVerticalBarWidth;
-
-    private int mSelectedWeekBackgroundColor;
-
-    private int mFocusedMonthDateColor;
-
-    private int mUnfocusedMonthDateColor;
-
-    private int mWeekSeparatorLineColor;
-
-    private int mWeekNumberColor;
-
-    private int mWeekDayTextAppearanceResId;
-
-    private int mDateTextAppearanceResId;
-
-    /**
-     * The top offset of the weeks list.
-     */
-    private int mListScrollTopOffset = 2;
-
-    /**
-     * The visible height of a week view.
-     */
-    private int mWeekMinVisibleHeight = 12;
-
-    /**
-     * The visible height of a week view.
-     */
-    private int mBottomBuffer = 20;
-
-    /**
-     * The number of shown weeks.
-     */
-    private int mShownWeekCount;
-
-    /**
-     * Flag whether to show the week number.
-     */
-    private boolean mShowWeekNumber;
-
-    /**
-     * The number of day per week to be shown.
-     */
-    private int mDaysPerWeek = 7;
-
-    /**
-     * The friction of the week list while flinging.
-     */
-    private float mFriction = .05f;
-
-    /**
-     * Scale for adjusting velocity of the week list while flinging.
-     */
-    private float mVelocityScale = 0.333f;
-
-    /**
-     * The adapter for the weeks list.
-     */
-    private WeeksAdapter mAdapter;
-
-    /**
-     * The weeks list.
-     */
-    private ListView mListView;
-
-    /**
-     * The name of the month to display.
-     */
-    private TextView mMonthName;
-
-    /**
-     * The header with week day names.
-     */
-    private ViewGroup mDayNamesHeader;
-
-    /**
-     * Cached labels for the week names header.
-     */
-    private String[] mDayLabels;
-
-    /**
-     * The first day of the week.
-     */
-    private int mFirstDayOfWeek;
-
-    /**
-     * Which month should be displayed/highlighted [0-11].
-     */
-    private int mCurrentMonthDisplayed = -1;
-
-    /**
-     * Used for tracking during a scroll.
-     */
-    private long mPreviousScrollPosition;
-
-    /**
-     * Used for tracking which direction the view is scrolling.
-     */
-    private boolean mIsScrollingUp = false;
-
-    /**
-     * The previous scroll state of the weeks ListView.
-     */
-    private int mPreviousScrollState = OnScrollListener.SCROLL_STATE_IDLE;
-
-    /**
-     * The current scroll state of the weeks ListView.
-     */
-    private int mCurrentScrollState = OnScrollListener.SCROLL_STATE_IDLE;
-
-    /**
-     * Listener for changes in the selected day.
-     */
-    private OnDateChangeListener mOnDateChangeListener;
-
-    /**
-     * Command for adjusting the position after a scroll/fling.
-     */
-    private ScrollStateRunnable mScrollStateChangedRunnable = new ScrollStateRunnable();
-
-    /**
-     * Temporary instance to avoid multiple instantiations.
-     */
-    private Calendar mTempDate;
-
-    /**
-     * The first day of the focused month.
-     */
-    private Calendar mFirstDayOfMonth;
-
-    /**
-     * The start date of the range supported by this picker.
-     */
-    private Calendar mMinDate;
-
-    /**
-     * The end date of the range supported by this picker.
-     */
-    private Calendar mMaxDate;
-
-    /**
-     * Date format for parsing dates.
-     */
-    private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
-
-    /**
-     * The current locale.
-     */
-    private Locale mCurrentLocale;
+    private CalendarViewDelegate mDelegate;
 
     /**
      * The callback used to indicate the user changes the date.
@@ -330,91 +103,17 @@
     }
 
     public CalendarView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
+        this(context, attrs, R.attr.calendarViewStyle);
     }
 
-    public CalendarView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, 0);
+    public CalendarView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        // initialization based on locale
-        setCurrentLocale(Locale.getDefault());
+    public CalendarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
-        TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.CalendarView,
-                R.attr.calendarViewStyle, 0);
-        mShowWeekNumber = attributesArray.getBoolean(R.styleable.CalendarView_showWeekNumber,
-                DEFAULT_SHOW_WEEK_NUMBER);
-        mFirstDayOfWeek = attributesArray.getInt(R.styleable.CalendarView_firstDayOfWeek,
-                LocaleData.get(Locale.getDefault()).firstDayOfWeek);
-        String minDate = attributesArray.getString(R.styleable.CalendarView_minDate);
-        if (TextUtils.isEmpty(minDate) || !parseDate(minDate, mMinDate)) {
-            parseDate(DEFAULT_MIN_DATE, mMinDate);
-        }
-        String maxDate = attributesArray.getString(R.styleable.CalendarView_maxDate);
-        if (TextUtils.isEmpty(maxDate) || !parseDate(maxDate, mMaxDate)) {
-            parseDate(DEFAULT_MAX_DATE, mMaxDate);
-        }
-        if (mMaxDate.before(mMinDate)) {
-            throw new IllegalArgumentException("Max date cannot be before min date.");
-        }
-        mShownWeekCount = attributesArray.getInt(R.styleable.CalendarView_shownWeekCount,
-                DEFAULT_SHOWN_WEEK_COUNT);
-        mSelectedWeekBackgroundColor = attributesArray.getColor(
-                R.styleable.CalendarView_selectedWeekBackgroundColor, 0);
-        mFocusedMonthDateColor = attributesArray.getColor(
-                R.styleable.CalendarView_focusedMonthDateColor, 0);
-        mUnfocusedMonthDateColor = attributesArray.getColor(
-                R.styleable.CalendarView_unfocusedMonthDateColor, 0);
-        mWeekSeparatorLineColor = attributesArray.getColor(
-                R.styleable.CalendarView_weekSeparatorLineColor, 0);
-        mWeekNumberColor = attributesArray.getColor(R.styleable.CalendarView_weekNumberColor, 0);
-        mSelectedDateVerticalBar = attributesArray.getDrawable(
-                R.styleable.CalendarView_selectedDateVerticalBar);
-
-        mDateTextAppearanceResId = attributesArray.getResourceId(
-                R.styleable.CalendarView_dateTextAppearance, R.style.TextAppearance_Small);
-        updateDateTextSize();
-
-        mWeekDayTextAppearanceResId = attributesArray.getResourceId(
-                R.styleable.CalendarView_weekDayTextAppearance,
-                DEFAULT_WEEK_DAY_TEXT_APPEARANCE_RES_ID);
-        attributesArray.recycle();
-
-        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
-        mWeekMinVisibleHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                UNSCALED_WEEK_MIN_VISIBLE_HEIGHT, displayMetrics);
-        mListScrollTopOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                UNSCALED_LIST_SCROLL_TOP_OFFSET, displayMetrics);
-        mBottomBuffer = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                UNSCALED_BOTTOM_BUFFER, displayMetrics);
-        mSelectedDateVerticalBarWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                UNSCALED_SELECTED_DATE_VERTICAL_BAR_WIDTH, displayMetrics);
-        mWeekSeperatorLineWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                UNSCALED_WEEK_SEPARATOR_LINE_WIDTH, displayMetrics);
-
-        LayoutInflater layoutInflater = (LayoutInflater) context
-                .getSystemService(Service.LAYOUT_INFLATER_SERVICE);
-        View content = layoutInflater.inflate(R.layout.calendar_view, null, false);
-        addView(content);
-
-        mListView = (ListView) findViewById(R.id.list);
-        mDayNamesHeader = (ViewGroup) content.findViewById(com.android.internal.R.id.day_names);
-        mMonthName = (TextView) content.findViewById(com.android.internal.R.id.month_name);
-
-        setUpHeader();
-        setUpListView();
-        setUpAdapter();
-
-        // go to today or whichever is close to today min or max date
-        mTempDate.setTimeInMillis(System.currentTimeMillis());
-        if (mTempDate.before(mMinDate)) {
-            goTo(mMinDate, false, true, true);
-        } else if (mMaxDate.before(mTempDate)) {
-            goTo(mMaxDate, false, true, true);
-        } else {
-            goTo(mTempDate, false, true, true);
-        }
-
-        invalidate();
+        mDelegate = new LegacyCalendarViewDelegate(this, context, attrs, defStyleAttr, defStyleRes);
     }
 
     /**
@@ -425,10 +124,7 @@
      * @attr ref android.R.styleable#CalendarView_shownWeekCount
      */
     public void setShownWeekCount(int count) {
-        if (mShownWeekCount != count) {
-            mShownWeekCount = count;
-            invalidate();
-        }
+        mDelegate.setShownWeekCount(count);
     }
 
     /**
@@ -439,7 +135,7 @@
      * @attr ref android.R.styleable#CalendarView_shownWeekCount
      */
     public int getShownWeekCount() {
-        return mShownWeekCount;
+        return mDelegate.getShownWeekCount();
     }
 
     /**
@@ -450,16 +146,7 @@
      * @attr ref android.R.styleable#CalendarView_selectedWeekBackgroundColor
      */
     public void setSelectedWeekBackgroundColor(int color) {
-        if (mSelectedWeekBackgroundColor != color) {
-            mSelectedWeekBackgroundColor = color;
-            final int childCount = mListView.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                WeekView weekView = (WeekView) mListView.getChildAt(i);
-                if (weekView.mHasSelectedDay) {
-                    weekView.invalidate();
-                }
-            }
-        }
+        mDelegate.setSelectedWeekBackgroundColor(color);
     }
 
     /**
@@ -470,7 +157,7 @@
      * @attr ref android.R.styleable#CalendarView_selectedWeekBackgroundColor
      */
     public int getSelectedWeekBackgroundColor() {
-        return mSelectedWeekBackgroundColor;
+        return mDelegate.getSelectedWeekBackgroundColor();
     }
 
     /**
@@ -481,16 +168,7 @@
      * @attr ref android.R.styleable#CalendarView_focusedMonthDateColor
      */
     public void setFocusedMonthDateColor(int color) {
-        if (mFocusedMonthDateColor != color) {
-            mFocusedMonthDateColor = color;
-            final int childCount = mListView.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                WeekView weekView = (WeekView) mListView.getChildAt(i);
-                if (weekView.mHasFocusedDay) {
-                    weekView.invalidate();
-                }
-            }
-        }
+        mDelegate.setFocusedMonthDateColor(color);
     }
 
     /**
@@ -501,7 +179,7 @@
      * @attr ref android.R.styleable#CalendarView_focusedMonthDateColor
      */
     public int getFocusedMonthDateColor() {
-        return mFocusedMonthDateColor;
+        return mDelegate.getFocusedMonthDateColor();
     }
 
     /**
@@ -512,16 +190,7 @@
      * @attr ref android.R.styleable#CalendarView_unfocusedMonthDateColor
      */
     public void setUnfocusedMonthDateColor(int color) {
-        if (mUnfocusedMonthDateColor != color) {
-            mUnfocusedMonthDateColor = color;
-            final int childCount = mListView.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                WeekView weekView = (WeekView) mListView.getChildAt(i);
-                if (weekView.mHasUnfocusedDay) {
-                    weekView.invalidate();
-                }
-            }
-        }
+        mDelegate.setUnfocusedMonthDateColor(color);
     }
 
     /**
@@ -532,7 +201,7 @@
      * @attr ref android.R.styleable#CalendarView_unfocusedMonthDateColor
      */
     public int getUnfocusedMonthDateColor() {
-        return mFocusedMonthDateColor;
+        return mDelegate.getUnfocusedMonthDateColor();
     }
 
     /**
@@ -543,12 +212,7 @@
      * @attr ref android.R.styleable#CalendarView_weekNumberColor
      */
     public void setWeekNumberColor(int color) {
-        if (mWeekNumberColor != color) {
-            mWeekNumberColor = color;
-            if (mShowWeekNumber) {
-                invalidateAllWeekViews();
-            }
-        }
+        mDelegate.setWeekNumberColor(color);
     }
 
     /**
@@ -559,7 +223,7 @@
      * @attr ref android.R.styleable#CalendarView_weekNumberColor
      */
     public int getWeekNumberColor() {
-        return mWeekNumberColor;
+        return mDelegate.getWeekNumberColor();
     }
 
     /**
@@ -570,10 +234,7 @@
      * @attr ref android.R.styleable#CalendarView_weekSeparatorLineColor
      */
     public void setWeekSeparatorLineColor(int color) {
-        if (mWeekSeparatorLineColor != color) {
-            mWeekSeparatorLineColor = color;
-            invalidateAllWeekViews();
-        }
+        mDelegate.setWeekSeparatorLineColor(color);
     }
 
     /**
@@ -584,7 +245,7 @@
      * @attr ref android.R.styleable#CalendarView_weekSeparatorLineColor
      */
     public int getWeekSeparatorLineColor() {
-        return mWeekSeparatorLineColor;
+        return mDelegate.getWeekSeparatorLineColor();
     }
 
     /**
@@ -596,8 +257,7 @@
      * @attr ref android.R.styleable#CalendarView_selectedDateVerticalBar
      */
     public void setSelectedDateVerticalBar(int resourceId) {
-        Drawable drawable = getResources().getDrawable(resourceId);
-        setSelectedDateVerticalBar(drawable);
+        mDelegate.setSelectedDateVerticalBar(resourceId);
     }
 
     /**
@@ -609,16 +269,7 @@
      * @attr ref android.R.styleable#CalendarView_selectedDateVerticalBar
      */
     public void setSelectedDateVerticalBar(Drawable drawable) {
-        if (mSelectedDateVerticalBar != drawable) {
-            mSelectedDateVerticalBar = drawable;
-            final int childCount = mListView.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                WeekView weekView = (WeekView) mListView.getChildAt(i);
-                if (weekView.mHasSelectedDay) {
-                    weekView.invalidate();
-                }
-            }
-        }
+        mDelegate.setSelectedDateVerticalBar(drawable);
     }
 
     /**
@@ -628,7 +279,7 @@
      * @return The vertical bar drawable.
      */
     public Drawable getSelectedDateVerticalBar() {
-        return mSelectedDateVerticalBar;
+        return mDelegate.getSelectedDateVerticalBar();
     }
 
     /**
@@ -639,10 +290,7 @@
      * @attr ref android.R.styleable#CalendarView_weekDayTextAppearance
      */
     public void setWeekDayTextAppearance(int resourceId) {
-        if (mWeekDayTextAppearanceResId != resourceId) {
-            mWeekDayTextAppearanceResId = resourceId;
-            setUpHeader();
-        }
+        mDelegate.setWeekDayTextAppearance(resourceId);
     }
 
     /**
@@ -653,7 +301,7 @@
      * @attr ref android.R.styleable#CalendarView_weekDayTextAppearance
      */
     public int getWeekDayTextAppearance() {
-        return mWeekDayTextAppearanceResId;
+        return mDelegate.getWeekDayTextAppearance();
     }
 
     /**
@@ -664,11 +312,7 @@
      * @attr ref android.R.styleable#CalendarView_dateTextAppearance
      */
     public void setDateTextAppearance(int resourceId) {
-        if (mDateTextAppearanceResId != resourceId) {
-            mDateTextAppearanceResId = resourceId;
-            updateDateTextSize();
-            invalidateAllWeekViews();
-        }
+        mDelegate.setDateTextAppearance(resourceId);
     }
 
     /**
@@ -679,35 +323,17 @@
      * @attr ref android.R.styleable#CalendarView_dateTextAppearance
      */
     public int getDateTextAppearance() {
-        return mDateTextAppearanceResId;
+        return mDelegate.getDateTextAppearance();
     }
 
     @Override
     public void setEnabled(boolean enabled) {
-        mListView.setEnabled(enabled);
+        mDelegate.setEnabled(enabled);
     }
 
     @Override
     public boolean isEnabled() {
-        return mListView.isEnabled();
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        setCurrentLocale(newConfig.locale);
-    }
-
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        event.setClassName(CalendarView.class.getName());
-    }
-
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setClassName(CalendarView.class.getName());
+        return mDelegate.isEnabled();
     }
 
     /**
@@ -723,7 +349,7 @@
      * @attr ref android.R.styleable#CalendarView_minDate
      */
     public long getMinDate() {
-        return mMinDate.getTimeInMillis();
+        return mDelegate.getMinDate();
     }
 
     /**
@@ -736,30 +362,7 @@
      * @attr ref android.R.styleable#CalendarView_minDate
      */
     public void setMinDate(long minDate) {
-        mTempDate.setTimeInMillis(minDate);
-        if (isSameDate(mTempDate, mMinDate)) {
-            return;
-        }
-        mMinDate.setTimeInMillis(minDate);
-        // make sure the current date is not earlier than
-        // the new min date since the latter is used for
-        // calculating the indices in the adapter thus
-        // avoiding out of bounds error
-        Calendar date = mAdapter.mSelectedDate;
-        if (date.before(mMinDate)) {
-            mAdapter.setSelectedDay(mMinDate);
-        }
-        // reinitialize the adapter since its range depends on min date
-        mAdapter.init();
-        if (date.before(mMinDate)) {
-            setDate(mTempDate.getTimeInMillis());
-        } else {
-            // we go to the current date to force the ListView to query its
-            // adapter for the shown views since we have changed the adapter
-            // range and the base from which the later calculates item indices
-            // note that calling setDate will not work since the date is the same
-            goTo(date, false, true, false);
-        }
+        mDelegate.setMinDate(minDate);
     }
 
     /**
@@ -775,7 +378,7 @@
      * @attr ref android.R.styleable#CalendarView_maxDate
      */
     public long getMaxDate() {
-        return mMaxDate.getTimeInMillis();
+        return mDelegate.getMaxDate();
     }
 
     /**
@@ -788,23 +391,7 @@
      * @attr ref android.R.styleable#CalendarView_maxDate
      */
     public void setMaxDate(long maxDate) {
-        mTempDate.setTimeInMillis(maxDate);
-        if (isSameDate(mTempDate, mMaxDate)) {
-            return;
-        }
-        mMaxDate.setTimeInMillis(maxDate);
-        // reinitialize the adapter since its range depends on max date
-        mAdapter.init();
-        Calendar date = mAdapter.mSelectedDate;
-        if (date.after(mMaxDate)) {
-            setDate(mMaxDate.getTimeInMillis());
-        } else {
-            // we go to the current date to force the ListView to query its
-            // adapter for the shown views since we have changed the adapter
-            // range and the base from which the later calculates item indices
-            // note that calling setDate will not work since the date is the same
-            goTo(date, false, true, false);
-        }
+        mDelegate.setMaxDate(maxDate);
     }
 
     /**
@@ -815,12 +402,7 @@
      * @attr ref android.R.styleable#CalendarView_showWeekNumber
      */
     public void setShowWeekNumber(boolean showWeekNumber) {
-        if (mShowWeekNumber == showWeekNumber) {
-            return;
-        }
-        mShowWeekNumber = showWeekNumber;
-        mAdapter.notifyDataSetChanged();
-        setUpHeader();
+        mDelegate.setShowWeekNumber(showWeekNumber);
     }
 
     /**
@@ -831,7 +413,7 @@
      * @attr ref android.R.styleable#CalendarView_showWeekNumber
      */
     public boolean getShowWeekNumber() {
-        return mShowWeekNumber;
+        return mDelegate.getShowWeekNumber();
     }
 
     /**
@@ -850,7 +432,7 @@
      * @attr ref android.R.styleable#CalendarView_firstDayOfWeek
      */
     public int getFirstDayOfWeek() {
-        return mFirstDayOfWeek;
+        return mDelegate.getFirstDayOfWeek();
     }
 
     /**
@@ -869,12 +451,7 @@
      * @attr ref android.R.styleable#CalendarView_firstDayOfWeek
      */
     public void setFirstDayOfWeek(int firstDayOfWeek) {
-        if (mFirstDayOfWeek == firstDayOfWeek) {
-            return;
-        }
-        mFirstDayOfWeek = firstDayOfWeek;
-        mAdapter.init();
-        setUpHeader();
+        mDelegate.setFirstDayOfWeek(firstDayOfWeek);
     }
 
     /**
@@ -883,7 +460,7 @@
      * @param listener The listener to be notified.
      */
     public void setOnDateChangeListener(OnDateChangeListener listener) {
-        mOnDateChangeListener = listener;
+        mDelegate.setOnDateChangeListener(listener);
     }
 
     /**
@@ -893,7 +470,7 @@
      * @return The selected date.
      */
     public long getDate() {
-        return mAdapter.mSelectedDate.getTimeInMillis();
+        return mDelegate.getDate();
     }
 
     /**
@@ -910,7 +487,7 @@
      * @see #setMaxDate(long)
      */
     public void setDate(long date) {
-        setDate(date, false, false);
+        mDelegate.setDate(date);
     }
 
     /**
@@ -928,934 +505,1645 @@
      * @see #setMaxDate(long)
      */
     public void setDate(long date, boolean animate, boolean center) {
-        mTempDate.setTimeInMillis(date);
-        if (isSameDate(mTempDate, mAdapter.mSelectedDate)) {
-            return;
-        }
-        goTo(mTempDate, animate, true, center);
+        mDelegate.setDate(date, animate, center);
     }
 
-    private void updateDateTextSize() {
-        TypedArray dateTextAppearance = mContext.obtainStyledAttributes(
-                mDateTextAppearanceResId, R.styleable.TextAppearance);
-        mDateTextSize = dateTextAppearance.getDimensionPixelSize(
-                R.styleable.TextAppearance_textSize, DEFAULT_DATE_TEXT_SIZE);
-        dateTextAppearance.recycle();
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mDelegate.onConfigurationChanged(newConfig);
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        mDelegate.onInitializeAccessibilityEvent(event);
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        mDelegate.onInitializeAccessibilityNodeInfo(info);
     }
 
     /**
-     * Invalidates all week views.
+     * A delegate interface that defined the public API of the CalendarView. Allows different
+     * CalendarView implementations. This would need to be implemented by the CalendarView delegates
+     * for the real behavior.
      */
-    private void invalidateAllWeekViews() {
-        final int childCount = mListView.getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View view = mListView.getChildAt(i);
-            view.invalidate();
+    private interface CalendarViewDelegate {
+        void setShownWeekCount(int count);
+        int getShownWeekCount();
+
+        void setSelectedWeekBackgroundColor(int color);
+        int getSelectedWeekBackgroundColor();
+
+        void setFocusedMonthDateColor(int color);
+        int getFocusedMonthDateColor();
+
+        void setUnfocusedMonthDateColor(int color);
+        int getUnfocusedMonthDateColor();
+
+        void setWeekNumberColor(int color);
+        int getWeekNumberColor();
+
+        void setWeekSeparatorLineColor(int color);
+        int getWeekSeparatorLineColor();
+
+        void setSelectedDateVerticalBar(int resourceId);
+        void setSelectedDateVerticalBar(Drawable drawable);
+        Drawable getSelectedDateVerticalBar();
+
+        void setWeekDayTextAppearance(int resourceId);
+        int getWeekDayTextAppearance();
+
+        void setDateTextAppearance(int resourceId);
+        int getDateTextAppearance();
+
+        void setEnabled(boolean enabled);
+        boolean isEnabled();
+
+        void setMinDate(long minDate);
+        long getMinDate();
+
+        void setMaxDate(long maxDate);
+        long getMaxDate();
+
+        void setShowWeekNumber(boolean showWeekNumber);
+        boolean getShowWeekNumber();
+
+        void setFirstDayOfWeek(int firstDayOfWeek);
+        int getFirstDayOfWeek();
+
+        void setDate(long date);
+        void setDate(long date, boolean animate, boolean center);
+        long getDate();
+
+        void setOnDateChangeListener(OnDateChangeListener listener);
+
+        void onConfigurationChanged(Configuration newConfig);
+        void onInitializeAccessibilityEvent(AccessibilityEvent event);
+        void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
+    }
+
+    /**
+     * An abstract class which can be used as a start for CalendarView implementations
+     */
+    abstract static class AbstractCalendarViewDelegate implements CalendarViewDelegate {
+        // The delegator
+        protected CalendarView mDelegator;
+
+        // The context
+        protected Context mContext;
+
+        // The current locale
+        protected Locale mCurrentLocale;
+
+        AbstractCalendarViewDelegate(CalendarView delegator, Context context) {
+            mDelegator = delegator;
+            mContext = context;
+
+            // Initialization based on locale
+            setCurrentLocale(Locale.getDefault());
+        }
+
+        protected void setCurrentLocale(Locale locale) {
+            if (locale.equals(mCurrentLocale)) {
+                return;
+            }
+            mCurrentLocale = locale;
         }
     }
 
     /**
-     * Sets the current locale.
-     *
-     * @param locale The current locale.
+     * A delegate implementing the legacy CalendarView
      */
-    private void setCurrentLocale(Locale locale) {
-        if (locale.equals(mCurrentLocale)) {
-            return;
+    private static class LegacyCalendarViewDelegate extends AbstractCalendarViewDelegate {
+
+        /**
+         * Default value whether to show week number.
+         */
+        private static final boolean DEFAULT_SHOW_WEEK_NUMBER = true;
+
+        /**
+         * The number of milliseconds in a day.e
+         */
+        private static final long MILLIS_IN_DAY = 86400000L;
+
+        /**
+         * The number of day in a week.
+         */
+        private static final int DAYS_PER_WEEK = 7;
+
+        /**
+         * The number of milliseconds in a week.
+         */
+        private static final long MILLIS_IN_WEEK = DAYS_PER_WEEK * MILLIS_IN_DAY;
+
+        /**
+         * Affects when the month selection will change while scrolling upe
+         */
+        private static final int SCROLL_HYST_WEEKS = 2;
+
+        /**
+         * How long the GoTo fling animation should last.
+         */
+        private static final int GOTO_SCROLL_DURATION = 1000;
+
+        /**
+         * The duration of the adjustment upon a user scroll in milliseconds.
+         */
+        private static final int ADJUSTMENT_SCROLL_DURATION = 500;
+
+        /**
+         * How long to wait after receiving an onScrollStateChanged notification
+         * before acting on it.
+         */
+        private static final int SCROLL_CHANGE_DELAY = 40;
+
+        /**
+         * String for parsing dates.
+         */
+        private static final String DATE_FORMAT = "MM/dd/yyyy";
+
+        /**
+         * The default minimal date.
+         */
+        private static final String DEFAULT_MIN_DATE = "01/01/1900";
+
+        /**
+         * The default maximal date.
+         */
+        private static final String DEFAULT_MAX_DATE = "01/01/2100";
+
+        private static final int DEFAULT_SHOWN_WEEK_COUNT = 6;
+
+        private static final int DEFAULT_DATE_TEXT_SIZE = 14;
+
+        private static final int UNSCALED_SELECTED_DATE_VERTICAL_BAR_WIDTH = 6;
+
+        private static final int UNSCALED_WEEK_MIN_VISIBLE_HEIGHT = 12;
+
+        private static final int UNSCALED_LIST_SCROLL_TOP_OFFSET = 2;
+
+        private static final int UNSCALED_BOTTOM_BUFFER = 20;
+
+        private static final int UNSCALED_WEEK_SEPARATOR_LINE_WIDTH = 1;
+
+        private static final int DEFAULT_WEEK_DAY_TEXT_APPEARANCE_RES_ID = -1;
+
+        private final int mWeekSeperatorLineWidth;
+
+        private int mDateTextSize;
+
+        private Drawable mSelectedDateVerticalBar;
+
+        private final int mSelectedDateVerticalBarWidth;
+
+        private int mSelectedWeekBackgroundColor;
+
+        private int mFocusedMonthDateColor;
+
+        private int mUnfocusedMonthDateColor;
+
+        private int mWeekSeparatorLineColor;
+
+        private int mWeekNumberColor;
+
+        private int mWeekDayTextAppearanceResId;
+
+        private int mDateTextAppearanceResId;
+
+        /**
+         * The top offset of the weeks list.
+         */
+        private int mListScrollTopOffset = 2;
+
+        /**
+         * The visible height of a week view.
+         */
+        private int mWeekMinVisibleHeight = 12;
+
+        /**
+         * The visible height of a week view.
+         */
+        private int mBottomBuffer = 20;
+
+        /**
+         * The number of shown weeks.
+         */
+        private int mShownWeekCount;
+
+        /**
+         * Flag whether to show the week number.
+         */
+        private boolean mShowWeekNumber;
+
+        /**
+         * The number of day per week to be shown.
+         */
+        private int mDaysPerWeek = 7;
+
+        /**
+         * The friction of the week list while flinging.
+         */
+        private float mFriction = .05f;
+
+        /**
+         * Scale for adjusting velocity of the week list while flinging.
+         */
+        private float mVelocityScale = 0.333f;
+
+        /**
+         * The adapter for the weeks list.
+         */
+        private WeeksAdapter mAdapter;
+
+        /**
+         * The weeks list.
+         */
+        private ListView mListView;
+
+        /**
+         * The name of the month to display.
+         */
+        private TextView mMonthName;
+
+        /**
+         * The header with week day names.
+         */
+        private ViewGroup mDayNamesHeader;
+
+        /**
+         * Cached labels for the week names header.
+         */
+        private String[] mDayLabels;
+
+        /**
+         * The first day of the week.
+         */
+        private int mFirstDayOfWeek;
+
+        /**
+         * Which month should be displayed/highlighted [0-11].
+         */
+        private int mCurrentMonthDisplayed = -1;
+
+        /**
+         * Used for tracking during a scroll.
+         */
+        private long mPreviousScrollPosition;
+
+        /**
+         * Used for tracking which direction the view is scrolling.
+         */
+        private boolean mIsScrollingUp = false;
+
+        /**
+         * The previous scroll state of the weeks ListView.
+         */
+        private int mPreviousScrollState = OnScrollListener.SCROLL_STATE_IDLE;
+
+        /**
+         * The current scroll state of the weeks ListView.
+         */
+        private int mCurrentScrollState = OnScrollListener.SCROLL_STATE_IDLE;
+
+        /**
+         * Listener for changes in the selected day.
+         */
+        private OnDateChangeListener mOnDateChangeListener;
+
+        /**
+         * Command for adjusting the position after a scroll/fling.
+         */
+        private ScrollStateRunnable mScrollStateChangedRunnable = new ScrollStateRunnable();
+
+        /**
+         * Temporary instance to avoid multiple instantiations.
+         */
+        private Calendar mTempDate;
+
+        /**
+         * The first day of the focused month.
+         */
+        private Calendar mFirstDayOfMonth;
+
+        /**
+         * The start date of the range supported by this picker.
+         */
+        private Calendar mMinDate;
+
+        /**
+         * The end date of the range supported by this picker.
+         */
+        private Calendar mMaxDate;
+
+        /**
+         * Date format for parsing dates.
+         */
+        private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
+
+        LegacyCalendarViewDelegate(CalendarView delegator, Context context, AttributeSet attrs,
+                                   int defStyleAttr, int defStyleRes) {
+            super(delegator, context);
+
+            // initialization based on locale
+            setCurrentLocale(Locale.getDefault());
+
+            TypedArray attributesArray = context.obtainStyledAttributes(attrs,
+                    R.styleable.CalendarView, defStyleAttr, defStyleRes);
+            mShowWeekNumber = attributesArray.getBoolean(R.styleable.CalendarView_showWeekNumber,
+                    DEFAULT_SHOW_WEEK_NUMBER);
+            mFirstDayOfWeek = attributesArray.getInt(R.styleable.CalendarView_firstDayOfWeek,
+                    LocaleData.get(Locale.getDefault()).firstDayOfWeek);
+            String minDate = attributesArray.getString(R.styleable.CalendarView_minDate);
+            if (TextUtils.isEmpty(minDate) || !parseDate(minDate, mMinDate)) {
+                parseDate(DEFAULT_MIN_DATE, mMinDate);
+            }
+            String maxDate = attributesArray.getString(R.styleable.CalendarView_maxDate);
+            if (TextUtils.isEmpty(maxDate) || !parseDate(maxDate, mMaxDate)) {
+                parseDate(DEFAULT_MAX_DATE, mMaxDate);
+            }
+            if (mMaxDate.before(mMinDate)) {
+                throw new IllegalArgumentException("Max date cannot be before min date.");
+            }
+            mShownWeekCount = attributesArray.getInt(R.styleable.CalendarView_shownWeekCount,
+                    DEFAULT_SHOWN_WEEK_COUNT);
+            mSelectedWeekBackgroundColor = attributesArray.getColor(
+                    R.styleable.CalendarView_selectedWeekBackgroundColor, 0);
+            mFocusedMonthDateColor = attributesArray.getColor(
+                    R.styleable.CalendarView_focusedMonthDateColor, 0);
+            mUnfocusedMonthDateColor = attributesArray.getColor(
+                    R.styleable.CalendarView_unfocusedMonthDateColor, 0);
+            mWeekSeparatorLineColor = attributesArray.getColor(
+                    R.styleable.CalendarView_weekSeparatorLineColor, 0);
+            mWeekNumberColor = attributesArray.getColor(R.styleable.CalendarView_weekNumberColor, 0);
+            mSelectedDateVerticalBar = attributesArray.getDrawable(
+                    R.styleable.CalendarView_selectedDateVerticalBar);
+
+            mDateTextAppearanceResId = attributesArray.getResourceId(
+                    R.styleable.CalendarView_dateTextAppearance, R.style.TextAppearance_Small);
+            updateDateTextSize();
+
+            mWeekDayTextAppearanceResId = attributesArray.getResourceId(
+                    R.styleable.CalendarView_weekDayTextAppearance,
+                    DEFAULT_WEEK_DAY_TEXT_APPEARANCE_RES_ID);
+            attributesArray.recycle();
+
+            DisplayMetrics displayMetrics = mDelegator.getResources().getDisplayMetrics();
+            mWeekMinVisibleHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    UNSCALED_WEEK_MIN_VISIBLE_HEIGHT, displayMetrics);
+            mListScrollTopOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    UNSCALED_LIST_SCROLL_TOP_OFFSET, displayMetrics);
+            mBottomBuffer = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    UNSCALED_BOTTOM_BUFFER, displayMetrics);
+            mSelectedDateVerticalBarWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    UNSCALED_SELECTED_DATE_VERTICAL_BAR_WIDTH, displayMetrics);
+            mWeekSeperatorLineWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    UNSCALED_WEEK_SEPARATOR_LINE_WIDTH, displayMetrics);
+
+            LayoutInflater layoutInflater = (LayoutInflater) mContext
+                    .getSystemService(Service.LAYOUT_INFLATER_SERVICE);
+            View content = layoutInflater.inflate(R.layout.calendar_view, null, false);
+            mDelegator.addView(content);
+
+            mListView = (ListView) mDelegator.findViewById(R.id.list);
+            mDayNamesHeader = (ViewGroup) content.findViewById(com.android.internal.R.id.day_names);
+            mMonthName = (TextView) content.findViewById(com.android.internal.R.id.month_name);
+
+            setUpHeader();
+            setUpListView();
+            setUpAdapter();
+
+            // go to today or whichever is close to today min or max date
+            mTempDate.setTimeInMillis(System.currentTimeMillis());
+            if (mTempDate.before(mMinDate)) {
+                goTo(mMinDate, false, true, true);
+            } else if (mMaxDate.before(mTempDate)) {
+                goTo(mMaxDate, false, true, true);
+            } else {
+                goTo(mTempDate, false, true, true);
+            }
+
+            mDelegator.invalidate();
         }
 
-        mCurrentLocale = locale;
-
-        mTempDate = getCalendarForLocale(mTempDate, locale);
-        mFirstDayOfMonth = getCalendarForLocale(mFirstDayOfMonth, locale);
-        mMinDate = getCalendarForLocale(mMinDate, locale);
-        mMaxDate = getCalendarForLocale(mMaxDate, locale);
-    }
-
-    /**
-     * Gets a calendar for locale bootstrapped with the value of a given calendar.
-     *
-     * @param oldCalendar The old calendar.
-     * @param locale The locale.
-     */
-    private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
-        if (oldCalendar == null) {
-            return Calendar.getInstance(locale);
-        } else {
-            final long currentTimeMillis = oldCalendar.getTimeInMillis();
-            Calendar newCalendar = Calendar.getInstance(locale);
-            newCalendar.setTimeInMillis(currentTimeMillis);
-            return newCalendar;
+        @Override
+        public void setShownWeekCount(int count) {
+            if (mShownWeekCount != count) {
+                mShownWeekCount = count;
+                mDelegator.invalidate();
+            }
         }
-    }
 
-    /**
-     * @return True if the <code>firstDate</code> is the same as the <code>
-     * secondDate</code>.
-     */
-    private boolean isSameDate(Calendar firstDate, Calendar secondDate) {
-        return (firstDate.get(Calendar.DAY_OF_YEAR) == secondDate.get(Calendar.DAY_OF_YEAR)
-                && firstDate.get(Calendar.YEAR) == secondDate.get(Calendar.YEAR));
-    }
+        @Override
+        public int getShownWeekCount() {
+            return mShownWeekCount;
+        }
 
-    /**
-     * Creates a new adapter if necessary and sets up its parameters.
-     */
-    private void setUpAdapter() {
-        if (mAdapter == null) {
-            mAdapter = new WeeksAdapter();
-            mAdapter.registerDataSetObserver(new DataSetObserver() {
-                @Override
-                public void onChanged() {
-                    if (mOnDateChangeListener != null) {
-                        Calendar selectedDay = mAdapter.getSelectedDay();
-                        mOnDateChangeListener.onSelectedDayChange(CalendarView.this,
-                                selectedDay.get(Calendar.YEAR),
-                                selectedDay.get(Calendar.MONTH),
-                                selectedDay.get(Calendar.DAY_OF_MONTH));
+        @Override
+        public void setSelectedWeekBackgroundColor(int color) {
+            if (mSelectedWeekBackgroundColor != color) {
+                mSelectedWeekBackgroundColor = color;
+                final int childCount = mListView.getChildCount();
+                for (int i = 0; i < childCount; i++) {
+                    WeekView weekView = (WeekView) mListView.getChildAt(i);
+                    if (weekView.mHasSelectedDay) {
+                        weekView.invalidate();
                     }
                 }
-            });
-            mListView.setAdapter(mAdapter);
-        }
-
-        // refresh the view with the new parameters
-        mAdapter.notifyDataSetChanged();
-    }
-
-    /**
-     * Sets up the strings to be used by the header.
-     */
-    private void setUpHeader() {
-        final String[] tinyWeekdayNames = LocaleData.get(Locale.getDefault()).tinyWeekdayNames;
-        mDayLabels = new String[mDaysPerWeek];
-        for (int i = 0; i < mDaysPerWeek; i++) {
-            final int j = i + mFirstDayOfWeek;
-            final int calendarDay = (j > Calendar.SATURDAY) ? j - Calendar.SATURDAY : j;
-            mDayLabels[i] = tinyWeekdayNames[calendarDay];
-        }
-        // Deal with week number
-        TextView label = (TextView) mDayNamesHeader.getChildAt(0);
-        if (mShowWeekNumber) {
-            label.setVisibility(View.VISIBLE);
-        } else {
-            label.setVisibility(View.GONE);
-        }
-        // Deal with day labels
-        final int count = mDayNamesHeader.getChildCount();
-        for (int i = 0; i < count - 1; i++) {
-            label = (TextView) mDayNamesHeader.getChildAt(i + 1);
-            if (mWeekDayTextAppearanceResId > -1) {
-                label.setTextAppearance(mContext, mWeekDayTextAppearanceResId);
             }
-            if (i < mDaysPerWeek) {
-                label.setText(mDayLabels[i]);
+        }
+
+        @Override
+        public int getSelectedWeekBackgroundColor() {
+            return mSelectedWeekBackgroundColor;
+        }
+
+        @Override
+        public void setFocusedMonthDateColor(int color) {
+            if (mFocusedMonthDateColor != color) {
+                mFocusedMonthDateColor = color;
+                final int childCount = mListView.getChildCount();
+                for (int i = 0; i < childCount; i++) {
+                    WeekView weekView = (WeekView) mListView.getChildAt(i);
+                    if (weekView.mHasFocusedDay) {
+                        weekView.invalidate();
+                    }
+                }
+            }
+        }
+
+        @Override
+        public int getFocusedMonthDateColor() {
+            return mFocusedMonthDateColor;
+        }
+
+        @Override
+        public void setUnfocusedMonthDateColor(int color) {
+            if (mUnfocusedMonthDateColor != color) {
+                mUnfocusedMonthDateColor = color;
+                final int childCount = mListView.getChildCount();
+                for (int i = 0; i < childCount; i++) {
+                    WeekView weekView = (WeekView) mListView.getChildAt(i);
+                    if (weekView.mHasUnfocusedDay) {
+                        weekView.invalidate();
+                    }
+                }
+            }
+        }
+
+        @Override
+        public int getUnfocusedMonthDateColor() {
+            return mFocusedMonthDateColor;
+        }
+
+        @Override
+        public void setWeekNumberColor(int color) {
+            if (mWeekNumberColor != color) {
+                mWeekNumberColor = color;
+                if (mShowWeekNumber) {
+                    invalidateAllWeekViews();
+                }
+            }
+        }
+
+        @Override
+        public int getWeekNumberColor() {
+            return mWeekNumberColor;
+        }
+
+        @Override
+        public void setWeekSeparatorLineColor(int color) {
+            if (mWeekSeparatorLineColor != color) {
+                mWeekSeparatorLineColor = color;
+                invalidateAllWeekViews();
+            }
+        }
+
+        @Override
+        public int getWeekSeparatorLineColor() {
+            return mWeekSeparatorLineColor;
+        }
+
+        @Override
+        public void setSelectedDateVerticalBar(int resourceId) {
+            Drawable drawable = mDelegator.getResources().getDrawable(resourceId);
+            setSelectedDateVerticalBar(drawable);
+        }
+
+        @Override
+        public void setSelectedDateVerticalBar(Drawable drawable) {
+            if (mSelectedDateVerticalBar != drawable) {
+                mSelectedDateVerticalBar = drawable;
+                final int childCount = mListView.getChildCount();
+                for (int i = 0; i < childCount; i++) {
+                    WeekView weekView = (WeekView) mListView.getChildAt(i);
+                    if (weekView.mHasSelectedDay) {
+                        weekView.invalidate();
+                    }
+                }
+            }
+        }
+
+        @Override
+        public Drawable getSelectedDateVerticalBar() {
+            return mSelectedDateVerticalBar;
+        }
+
+        @Override
+        public void setWeekDayTextAppearance(int resourceId) {
+            if (mWeekDayTextAppearanceResId != resourceId) {
+                mWeekDayTextAppearanceResId = resourceId;
+                setUpHeader();
+            }
+        }
+
+        @Override
+        public int getWeekDayTextAppearance() {
+            return mWeekDayTextAppearanceResId;
+        }
+
+        @Override
+        public void setDateTextAppearance(int resourceId) {
+            if (mDateTextAppearanceResId != resourceId) {
+                mDateTextAppearanceResId = resourceId;
+                updateDateTextSize();
+                invalidateAllWeekViews();
+            }
+        }
+
+        @Override
+        public int getDateTextAppearance() {
+            return mDateTextAppearanceResId;
+        }
+
+        @Override
+        public void setEnabled(boolean enabled) {
+            mListView.setEnabled(enabled);
+        }
+
+        @Override
+        public boolean isEnabled() {
+            return mListView.isEnabled();
+        }
+
+        @Override
+        public void setMinDate(long minDate) {
+            mTempDate.setTimeInMillis(minDate);
+            if (isSameDate(mTempDate, mMinDate)) {
+                return;
+            }
+            mMinDate.setTimeInMillis(minDate);
+            // make sure the current date is not earlier than
+            // the new min date since the latter is used for
+            // calculating the indices in the adapter thus
+            // avoiding out of bounds error
+            Calendar date = mAdapter.mSelectedDate;
+            if (date.before(mMinDate)) {
+                mAdapter.setSelectedDay(mMinDate);
+            }
+            // reinitialize the adapter since its range depends on min date
+            mAdapter.init();
+            if (date.before(mMinDate)) {
+                setDate(mTempDate.getTimeInMillis());
+            } else {
+                // we go to the current date to force the ListView to query its
+                // adapter for the shown views since we have changed the adapter
+                // range and the base from which the later calculates item indices
+                // note that calling setDate will not work since the date is the same
+                goTo(date, false, true, false);
+            }
+        }
+
+        @Override
+        public long getMinDate() {
+            return mMinDate.getTimeInMillis();
+        }
+
+        @Override
+        public void setMaxDate(long maxDate) {
+            mTempDate.setTimeInMillis(maxDate);
+            if (isSameDate(mTempDate, mMaxDate)) {
+                return;
+            }
+            mMaxDate.setTimeInMillis(maxDate);
+            // reinitialize the adapter since its range depends on max date
+            mAdapter.init();
+            Calendar date = mAdapter.mSelectedDate;
+            if (date.after(mMaxDate)) {
+                setDate(mMaxDate.getTimeInMillis());
+            } else {
+                // we go to the current date to force the ListView to query its
+                // adapter for the shown views since we have changed the adapter
+                // range and the base from which the later calculates item indices
+                // note that calling setDate will not work since the date is the same
+                goTo(date, false, true, false);
+            }
+        }
+
+        @Override
+        public long getMaxDate() {
+            return mMaxDate.getTimeInMillis();
+        }
+
+        @Override
+        public void setShowWeekNumber(boolean showWeekNumber) {
+            if (mShowWeekNumber == showWeekNumber) {
+                return;
+            }
+            mShowWeekNumber = showWeekNumber;
+            mAdapter.notifyDataSetChanged();
+            setUpHeader();
+        }
+
+        @Override
+        public boolean getShowWeekNumber() {
+            return mShowWeekNumber;
+        }
+
+        @Override
+        public void setFirstDayOfWeek(int firstDayOfWeek) {
+            if (mFirstDayOfWeek == firstDayOfWeek) {
+                return;
+            }
+            mFirstDayOfWeek = firstDayOfWeek;
+            mAdapter.init();
+            mAdapter.notifyDataSetChanged();
+            setUpHeader();
+        }
+
+        @Override
+        public int getFirstDayOfWeek() {
+            return mFirstDayOfWeek;
+        }
+
+        @Override
+        public void setDate(long date) {
+            setDate(date, false, false);
+        }
+
+        @Override
+        public void setDate(long date, boolean animate, boolean center) {
+            mTempDate.setTimeInMillis(date);
+            if (isSameDate(mTempDate, mAdapter.mSelectedDate)) {
+                return;
+            }
+            goTo(mTempDate, animate, true, center);
+        }
+
+        @Override
+        public long getDate() {
+            return mAdapter.mSelectedDate.getTimeInMillis();
+        }
+
+        @Override
+        public void setOnDateChangeListener(OnDateChangeListener listener) {
+            mOnDateChangeListener = listener;
+        }
+
+        @Override
+        public void onConfigurationChanged(Configuration newConfig) {
+            setCurrentLocale(newConfig.locale);
+        }
+
+        @Override
+        public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+            event.setClassName(CalendarView.class.getName());
+        }
+
+        @Override
+        public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+            info.setClassName(CalendarView.class.getName());
+        }
+
+        /**
+         * Sets the current locale.
+         *
+         * @param locale The current locale.
+         */
+        @Override
+        protected void setCurrentLocale(Locale locale) {
+            super.setCurrentLocale(locale);
+
+            mTempDate = getCalendarForLocale(mTempDate, locale);
+            mFirstDayOfMonth = getCalendarForLocale(mFirstDayOfMonth, locale);
+            mMinDate = getCalendarForLocale(mMinDate, locale);
+            mMaxDate = getCalendarForLocale(mMaxDate, locale);
+        }
+        private void updateDateTextSize() {
+            TypedArray dateTextAppearance = mDelegator.getContext().obtainStyledAttributes(
+                    mDateTextAppearanceResId, R.styleable.TextAppearance);
+            mDateTextSize = dateTextAppearance.getDimensionPixelSize(
+                    R.styleable.TextAppearance_textSize, DEFAULT_DATE_TEXT_SIZE);
+            dateTextAppearance.recycle();
+        }
+
+        /**
+         * Invalidates all week views.
+         */
+        private void invalidateAllWeekViews() {
+            final int childCount = mListView.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                View view = mListView.getChildAt(i);
+                view.invalidate();
+            }
+        }
+
+        /**
+         * Gets a calendar for locale bootstrapped with the value of a given calendar.
+         *
+         * @param oldCalendar The old calendar.
+         * @param locale The locale.
+         */
+        private static Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
+            if (oldCalendar == null) {
+                return Calendar.getInstance(locale);
+            } else {
+                final long currentTimeMillis = oldCalendar.getTimeInMillis();
+                Calendar newCalendar = Calendar.getInstance(locale);
+                newCalendar.setTimeInMillis(currentTimeMillis);
+                return newCalendar;
+            }
+        }
+
+        /**
+         * @return True if the <code>firstDate</code> is the same as the <code>
+         * secondDate</code>.
+         */
+        private static boolean isSameDate(Calendar firstDate, Calendar secondDate) {
+            return (firstDate.get(Calendar.DAY_OF_YEAR) == secondDate.get(Calendar.DAY_OF_YEAR)
+                    && firstDate.get(Calendar.YEAR) == secondDate.get(Calendar.YEAR));
+        }
+
+        /**
+         * Creates a new adapter if necessary and sets up its parameters.
+         */
+        private void setUpAdapter() {
+            if (mAdapter == null) {
+                mAdapter = new WeeksAdapter(mContext);
+                mAdapter.registerDataSetObserver(new DataSetObserver() {
+                    @Override
+                    public void onChanged() {
+                        if (mOnDateChangeListener != null) {
+                            Calendar selectedDay = mAdapter.getSelectedDay();
+                            mOnDateChangeListener.onSelectedDayChange(mDelegator,
+                                    selectedDay.get(Calendar.YEAR),
+                                    selectedDay.get(Calendar.MONTH),
+                                    selectedDay.get(Calendar.DAY_OF_MONTH));
+                        }
+                    }
+                });
+                mListView.setAdapter(mAdapter);
+            }
+
+            // refresh the view with the new parameters
+            mAdapter.notifyDataSetChanged();
+        }
+
+        /**
+         * Sets up the strings to be used by the header.
+         */
+        private void setUpHeader() {
+            mDayLabels = new String[mDaysPerWeek];
+            for (int i = mFirstDayOfWeek, count = mFirstDayOfWeek + mDaysPerWeek; i < count; i++) {
+                int calendarDay = (i > Calendar.SATURDAY) ? i - Calendar.SATURDAY : i;
+                mDayLabels[i - mFirstDayOfWeek] = DateUtils.getDayOfWeekString(calendarDay,
+                        DateUtils.LENGTH_SHORTEST);
+            }
+
+            TextView label = (TextView) mDayNamesHeader.getChildAt(0);
+            if (mShowWeekNumber) {
                 label.setVisibility(View.VISIBLE);
             } else {
                 label.setVisibility(View.GONE);
             }
-        }
-        mDayNamesHeader.invalidate();
-    }
-
-    /**
-     * Sets all the required fields for the list view.
-     */
-    private void setUpListView() {
-        // Configure the listview
-        mListView.setDivider(null);
-        mListView.setItemsCanFocus(true);
-        mListView.setVerticalScrollBarEnabled(false);
-        mListView.setOnScrollListener(new OnScrollListener() {
-            public void onScrollStateChanged(AbsListView view, int scrollState) {
-                CalendarView.this.onScrollStateChanged(view, scrollState);
+            for (int i = 1, count = mDayNamesHeader.getChildCount(); i < count; i++) {
+                label = (TextView) mDayNamesHeader.getChildAt(i);
+                if (mWeekDayTextAppearanceResId > -1) {
+                    label.setTextAppearance(mContext, mWeekDayTextAppearanceResId);
+                }
+                if (i < mDaysPerWeek + 1) {
+                    label.setText(mDayLabels[i - 1]);
+                    label.setVisibility(View.VISIBLE);
+                } else {
+                    label.setVisibility(View.GONE);
+                }
             }
-
-            public void onScroll(
-                    AbsListView view, int firstVisibleItem, int visibleItemCount,
-                    int totalItemCount) {
-                CalendarView.this.onScroll(view, firstVisibleItem, visibleItemCount,
-                        totalItemCount);
-            }
-        });
-        // Make the scrolling behavior nicer
-        mListView.setFriction(mFriction);
-        mListView.setVelocityScale(mVelocityScale);
-    }
-
-    /**
-     * This moves to the specified time in the view. If the time is not already
-     * in range it will move the list so that the first of the month containing
-     * the time is at the top of the view. If the new time is already in view
-     * the list will not be scrolled unless forceScroll is true. This time may
-     * optionally be highlighted as selected as well.
-     *
-     * @param date The time to move to.
-     * @param animate Whether to scroll to the given time or just redraw at the
-     *            new location.
-     * @param setSelected Whether to set the given time as selected.
-     * @param forceScroll Whether to recenter even if the time is already
-     *            visible.
-     *
-     * @throws IllegalArgumentException of the provided date is before the
-     *        range start of after the range end.
-     */
-    private void goTo(Calendar date, boolean animate, boolean setSelected, boolean forceScroll) {
-        if (date.before(mMinDate) || date.after(mMaxDate)) {
-            throw new IllegalArgumentException("Time not between " + mMinDate.getTime()
-                    + " and " + mMaxDate.getTime());
+            mDayNamesHeader.invalidate();
         }
-        // Find the first and last entirely visible weeks
-        int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
-        View firstChild = mListView.getChildAt(0);
-        if (firstChild != null && firstChild.getTop() < 0) {
-            firstFullyVisiblePosition++;
-        }
-        int lastFullyVisiblePosition = firstFullyVisiblePosition + mShownWeekCount - 1;
-        if (firstChild != null && firstChild.getTop() > mBottomBuffer) {
-            lastFullyVisiblePosition--;
-        }
-        if (setSelected) {
-            mAdapter.setSelectedDay(date);
-        }
-        // Get the week we're going to
-        int position = getWeeksSinceMinDate(date);
-
-        // Check if the selected day is now outside of our visible range
-        // and if so scroll to the month that contains it
-        if (position < firstFullyVisiblePosition || position > lastFullyVisiblePosition
-                || forceScroll) {
-            mFirstDayOfMonth.setTimeInMillis(date.getTimeInMillis());
-            mFirstDayOfMonth.set(Calendar.DAY_OF_MONTH, 1);
-
-            setMonthDisplayed(mFirstDayOfMonth);
-
-            // the earliest time we can scroll to is the min date
-            if (mFirstDayOfMonth.before(mMinDate)) {
-                position = 0;
-            } else {
-                position = getWeeksSinceMinDate(mFirstDayOfMonth);
-            }
-
-            mPreviousScrollState = OnScrollListener.SCROLL_STATE_FLING;
-            if (animate) {
-                mListView.smoothScrollToPositionFromTop(position, mListScrollTopOffset,
-                        GOTO_SCROLL_DURATION);
-            } else {
-                mListView.setSelectionFromTop(position, mListScrollTopOffset);
-                // Perform any after scroll operations that are needed
-                onScrollStateChanged(mListView, OnScrollListener.SCROLL_STATE_IDLE);
-            }
-        } else if (setSelected) {
-            // Otherwise just set the selection
-            setMonthDisplayed(date);
-        }
-    }
-
-    /**
-     * Parses the given <code>date</code> and in case of success sets
-     * the result to the <code>outDate</code>.
-     *
-     * @return True if the date was parsed.
-     */
-    private boolean parseDate(String date, Calendar outDate) {
-        try {
-            outDate.setTime(mDateFormat.parse(date));
-            return true;
-        } catch (ParseException e) {
-            Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
-            return false;
-        }
-    }
-
-    /**
-     * Called when a <code>view</code> transitions to a new <code>scrollState
-     * </code>.
-     */
-    private void onScrollStateChanged(AbsListView view, int scrollState) {
-        mScrollStateChangedRunnable.doScrollStateChange(view, scrollState);
-    }
-
-    /**
-     * Updates the title and selected month if the <code>view</code> has moved to a new
-     * month.
-     */
-    private void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
-            int totalItemCount) {
-        WeekView child = (WeekView) view.getChildAt(0);
-        if (child == null) {
-            return;
-        }
-
-        // Figure out where we are
-        long currScroll = view.getFirstVisiblePosition() * child.getHeight() - child.getBottom();
-
-        // If we have moved since our last call update the direction
-        if (currScroll < mPreviousScrollPosition) {
-            mIsScrollingUp = true;
-        } else if (currScroll > mPreviousScrollPosition) {
-            mIsScrollingUp = false;
-        } else {
-            return;
-        }
-
-        // Use some hysteresis for checking which month to highlight. This
-        // causes the month to transition when two full weeks of a month are
-        // visible when scrolling up, and when the first day in a month reaches
-        // the top of the screen when scrolling down.
-        int offset = child.getBottom() < mWeekMinVisibleHeight ? 1 : 0;
-        if (mIsScrollingUp) {
-            child = (WeekView) view.getChildAt(SCROLL_HYST_WEEKS + offset);
-        } else if (offset != 0) {
-            child = (WeekView) view.getChildAt(offset);
-        }
-
-        // Find out which month we're moving into
-        int month;
-        if (mIsScrollingUp) {
-            month = child.getMonthOfFirstWeekDay();
-        } else {
-            month = child.getMonthOfLastWeekDay();
-        }
-
-        // And how it relates to our current highlighted month
-        int monthDiff;
-        if (mCurrentMonthDisplayed == 11 && month == 0) {
-            monthDiff = 1;
-        } else if (mCurrentMonthDisplayed == 0 && month == 11) {
-            monthDiff = -1;
-        } else {
-            monthDiff = month - mCurrentMonthDisplayed;
-        }
-
-        // Only switch months if we're scrolling away from the currently
-        // selected month
-        if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) {
-            Calendar firstDay = child.getFirstDay();
-            if (mIsScrollingUp) {
-                firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK);
-            } else {
-                firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK);
-            }
-            setMonthDisplayed(firstDay);
-        }
-        mPreviousScrollPosition = currScroll;
-        mPreviousScrollState = mCurrentScrollState;
-    }
-
-    /**
-     * Sets the month displayed at the top of this view based on time. Override
-     * to add custom events when the title is changed.
-     *
-     * @param calendar A day in the new focus month.
-     */
-    private void setMonthDisplayed(Calendar calendar) {
-        mCurrentMonthDisplayed = calendar.get(Calendar.MONTH);
-        mAdapter.setFocusMonth(mCurrentMonthDisplayed);
-        final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY
-                | DateUtils.FORMAT_SHOW_YEAR;
-        final long millis = calendar.getTimeInMillis();
-        String newMonthName = DateUtils.formatDateRange(mContext, millis, millis, flags);
-        mMonthName.setText(newMonthName);
-        mMonthName.invalidate();
-    }
-
-    /**
-     * @return Returns the number of weeks between the current <code>date</code>
-     *         and the <code>mMinDate</code>.
-     */
-    private int getWeeksSinceMinDate(Calendar date) {
-        if (date.before(mMinDate)) {
-            throw new IllegalArgumentException("fromDate: " + mMinDate.getTime()
-                    + " does not precede toDate: " + date.getTime());
-        }
-        long endTimeMillis = date.getTimeInMillis()
-                + date.getTimeZone().getOffset(date.getTimeInMillis());
-        long startTimeMillis = mMinDate.getTimeInMillis()
-                + mMinDate.getTimeZone().getOffset(mMinDate.getTimeInMillis());
-        long dayOffsetMillis = (mMinDate.get(Calendar.DAY_OF_WEEK) - mFirstDayOfWeek)
-                * MILLIS_IN_DAY;
-        return (int) ((endTimeMillis - startTimeMillis + dayOffsetMillis) / MILLIS_IN_WEEK);
-    }
-
-    /**
-     * Command responsible for acting upon scroll state changes.
-     */
-    private class ScrollStateRunnable implements Runnable {
-        private AbsListView mView;
-
-        private int mNewState;
 
         /**
-         * Sets up the runnable with a short delay in case the scroll state
-         * immediately changes again.
-         *
-         * @param view The list view that changed state
-         * @param scrollState The new state it changed to
+         * Sets all the required fields for the list view.
          */
-        public void doScrollStateChange(AbsListView view, int scrollState) {
-            mView = view;
-            mNewState = scrollState;
-            removeCallbacks(this);
-            postDelayed(this, SCROLL_CHANGE_DELAY);
+        private void setUpListView() {
+            // Configure the listview
+            mListView.setDivider(null);
+            mListView.setItemsCanFocus(true);
+            mListView.setVerticalScrollBarEnabled(false);
+            mListView.setOnScrollListener(new OnScrollListener() {
+                public void onScrollStateChanged(AbsListView view, int scrollState) {
+                    LegacyCalendarViewDelegate.this.onScrollStateChanged(view, scrollState);
+                }
+
+                public void onScroll(
+                        AbsListView view, int firstVisibleItem, int visibleItemCount,
+                        int totalItemCount) {
+                    LegacyCalendarViewDelegate.this.onScroll(view, firstVisibleItem,
+                            visibleItemCount, totalItemCount);
+                }
+            });
+            // Make the scrolling behavior nicer
+            mListView.setFriction(mFriction);
+            mListView.setVelocityScale(mVelocityScale);
         }
 
-        public void run() {
-            mCurrentScrollState = mNewState;
-            // Fix the position after a scroll or a fling ends
-            if (mNewState == OnScrollListener.SCROLL_STATE_IDLE
-                    && mPreviousScrollState != OnScrollListener.SCROLL_STATE_IDLE) {
-                View child = mView.getChildAt(0);
-                if (child == null) {
-                    // The view is no longer visible, just return
-                    return;
+        /**
+         * This moves to the specified time in the view. If the time is not already
+         * in range it will move the list so that the first of the month containing
+         * the time is at the top of the view. If the new time is already in view
+         * the list will not be scrolled unless forceScroll is true. This time may
+         * optionally be highlighted as selected as well.
+         *
+         * @param date The time to move to.
+         * @param animate Whether to scroll to the given time or just redraw at the
+         *            new location.
+         * @param setSelected Whether to set the given time as selected.
+         * @param forceScroll Whether to recenter even if the time is already
+         *            visible.
+         *
+         * @throws IllegalArgumentException of the provided date is before the
+         *        range start of after the range end.
+         */
+        private void goTo(Calendar date, boolean animate, boolean setSelected,
+                boolean forceScroll) {
+            if (date.before(mMinDate) || date.after(mMaxDate)) {
+                throw new IllegalArgumentException("Time not between " + mMinDate.getTime()
+                        + " and " + mMaxDate.getTime());
+            }
+            // Find the first and last entirely visible weeks
+            int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
+            View firstChild = mListView.getChildAt(0);
+            if (firstChild != null && firstChild.getTop() < 0) {
+                firstFullyVisiblePosition++;
+            }
+            int lastFullyVisiblePosition = firstFullyVisiblePosition + mShownWeekCount - 1;
+            if (firstChild != null && firstChild.getTop() > mBottomBuffer) {
+                lastFullyVisiblePosition--;
+            }
+            if (setSelected) {
+                mAdapter.setSelectedDay(date);
+            }
+            // Get the week we're going to
+            int position = getWeeksSinceMinDate(date);
+
+            // Check if the selected day is now outside of our visible range
+            // and if so scroll to the month that contains it
+            if (position < firstFullyVisiblePosition || position > lastFullyVisiblePosition
+                    || forceScroll) {
+                mFirstDayOfMonth.setTimeInMillis(date.getTimeInMillis());
+                mFirstDayOfMonth.set(Calendar.DAY_OF_MONTH, 1);
+
+                setMonthDisplayed(mFirstDayOfMonth);
+
+                // the earliest time we can scroll to is the min date
+                if (mFirstDayOfMonth.before(mMinDate)) {
+                    position = 0;
+                } else {
+                    position = getWeeksSinceMinDate(mFirstDayOfMonth);
                 }
-                int dist = child.getBottom() - mListScrollTopOffset;
-                if (dist > mListScrollTopOffset) {
-                    if (mIsScrollingUp) {
-                        mView.smoothScrollBy(dist - child.getHeight(), ADJUSTMENT_SCROLL_DURATION);
-                    } else {
-                        mView.smoothScrollBy(dist, ADJUSTMENT_SCROLL_DURATION);
+
+                mPreviousScrollState = OnScrollListener.SCROLL_STATE_FLING;
+                if (animate) {
+                    mListView.smoothScrollToPositionFromTop(position, mListScrollTopOffset,
+                            GOTO_SCROLL_DURATION);
+                } else {
+                    mListView.setSelectionFromTop(position, mListScrollTopOffset);
+                    // Perform any after scroll operations that are needed
+                    onScrollStateChanged(mListView, OnScrollListener.SCROLL_STATE_IDLE);
+                }
+            } else if (setSelected) {
+                // Otherwise just set the selection
+                setMonthDisplayed(date);
+            }
+        }
+
+        /**
+         * Parses the given <code>date</code> and in case of success sets
+         * the result to the <code>outDate</code>.
+         *
+         * @return True if the date was parsed.
+         */
+        private boolean parseDate(String date, Calendar outDate) {
+            try {
+                outDate.setTime(mDateFormat.parse(date));
+                return true;
+            } catch (ParseException e) {
+                Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
+                return false;
+            }
+        }
+
+        /**
+         * Called when a <code>view</code> transitions to a new <code>scrollState
+         * </code>.
+         */
+        private void onScrollStateChanged(AbsListView view, int scrollState) {
+            mScrollStateChangedRunnable.doScrollStateChange(view, scrollState);
+        }
+
+        /**
+         * Updates the title and selected month if the <code>view</code> has moved to a new
+         * month.
+         */
+        private void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+                              int totalItemCount) {
+            WeekView child = (WeekView) view.getChildAt(0);
+            if (child == null) {
+                return;
+            }
+
+            // Figure out where we are
+            long currScroll =
+                    view.getFirstVisiblePosition() * child.getHeight() - child.getBottom();
+
+            // If we have moved since our last call update the direction
+            if (currScroll < mPreviousScrollPosition) {
+                mIsScrollingUp = true;
+            } else if (currScroll > mPreviousScrollPosition) {
+                mIsScrollingUp = false;
+            } else {
+                return;
+            }
+
+            // Use some hysteresis for checking which month to highlight. This
+            // causes the month to transition when two full weeks of a month are
+            // visible when scrolling up, and when the first day in a month reaches
+            // the top of the screen when scrolling down.
+            int offset = child.getBottom() < mWeekMinVisibleHeight ? 1 : 0;
+            if (mIsScrollingUp) {
+                child = (WeekView) view.getChildAt(SCROLL_HYST_WEEKS + offset);
+            } else if (offset != 0) {
+                child = (WeekView) view.getChildAt(offset);
+            }
+
+            // Find out which month we're moving into
+            int month;
+            if (mIsScrollingUp) {
+                month = child.getMonthOfFirstWeekDay();
+            } else {
+                month = child.getMonthOfLastWeekDay();
+            }
+
+            // And how it relates to our current highlighted month
+            int monthDiff;
+            if (mCurrentMonthDisplayed == 11 && month == 0) {
+                monthDiff = 1;
+            } else if (mCurrentMonthDisplayed == 0 && month == 11) {
+                monthDiff = -1;
+            } else {
+                monthDiff = month - mCurrentMonthDisplayed;
+            }
+
+            // Only switch months if we're scrolling away from the currently
+            // selected month
+            if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) {
+                Calendar firstDay = child.getFirstDay();
+                if (mIsScrollingUp) {
+                    firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK);
+                } else {
+                    firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK);
+                }
+                setMonthDisplayed(firstDay);
+            }
+            mPreviousScrollPosition = currScroll;
+            mPreviousScrollState = mCurrentScrollState;
+        }
+
+        /**
+         * Sets the month displayed at the top of this view based on time. Override
+         * to add custom events when the title is changed.
+         *
+         * @param calendar A day in the new focus month.
+         */
+        private void setMonthDisplayed(Calendar calendar) {
+            mCurrentMonthDisplayed = calendar.get(Calendar.MONTH);
+            mAdapter.setFocusMonth(mCurrentMonthDisplayed);
+            final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY
+                    | DateUtils.FORMAT_SHOW_YEAR;
+            final long millis = calendar.getTimeInMillis();
+            String newMonthName = DateUtils.formatDateRange(mContext, millis, millis, flags);
+            mMonthName.setText(newMonthName);
+            mMonthName.invalidate();
+        }
+
+        /**
+         * @return Returns the number of weeks between the current <code>date</code>
+         *         and the <code>mMinDate</code>.
+         */
+        private int getWeeksSinceMinDate(Calendar date) {
+            if (date.before(mMinDate)) {
+                throw new IllegalArgumentException("fromDate: " + mMinDate.getTime()
+                        + " does not precede toDate: " + date.getTime());
+            }
+            long endTimeMillis = date.getTimeInMillis()
+                    + date.getTimeZone().getOffset(date.getTimeInMillis());
+            long startTimeMillis = mMinDate.getTimeInMillis()
+                    + mMinDate.getTimeZone().getOffset(mMinDate.getTimeInMillis());
+            long dayOffsetMillis = (mMinDate.get(Calendar.DAY_OF_WEEK) - mFirstDayOfWeek)
+                    * MILLIS_IN_DAY;
+            return (int) ((endTimeMillis - startTimeMillis + dayOffsetMillis) / MILLIS_IN_WEEK);
+        }
+
+        /**
+         * Command responsible for acting upon scroll state changes.
+         */
+        private class ScrollStateRunnable implements Runnable {
+            private AbsListView mView;
+
+            private int mNewState;
+
+            /**
+             * Sets up the runnable with a short delay in case the scroll state
+             * immediately changes again.
+             *
+             * @param view The list view that changed state
+             * @param scrollState The new state it changed to
+             */
+            public void doScrollStateChange(AbsListView view, int scrollState) {
+                mView = view;
+                mNewState = scrollState;
+                mDelegator.removeCallbacks(this);
+                mDelegator.postDelayed(this, SCROLL_CHANGE_DELAY);
+            }
+
+            public void run() {
+                mCurrentScrollState = mNewState;
+                // Fix the position after a scroll or a fling ends
+                if (mNewState == OnScrollListener.SCROLL_STATE_IDLE
+                        && mPreviousScrollState != OnScrollListener.SCROLL_STATE_IDLE) {
+                    View child = mView.getChildAt(0);
+                    if (child == null) {
+                        // The view is no longer visible, just return
+                        return;
+                    }
+                    int dist = child.getBottom() - mListScrollTopOffset;
+                    if (dist > mListScrollTopOffset) {
+                        if (mIsScrollingUp) {
+                            mView.smoothScrollBy(dist - child.getHeight(),
+                                    ADJUSTMENT_SCROLL_DURATION);
+                        } else {
+                            mView.smoothScrollBy(dist, ADJUSTMENT_SCROLL_DURATION);
+                        }
                     }
                 }
+                mPreviousScrollState = mNewState;
             }
-            mPreviousScrollState = mNewState;
-        }
-    }
-
-    /**
-     * <p>
-     * This is a specialized adapter for creating a list of weeks with
-     * selectable days. It can be configured to display the week number, start
-     * the week on a given day, show a reduced number of days, or display an
-     * arbitrary number of weeks at a time.
-     * </p>
-     */
-    private class WeeksAdapter extends BaseAdapter implements OnTouchListener {
-        private final Calendar mSelectedDate = Calendar.getInstance();
-        private final GestureDetector mGestureDetector;
-
-        private int mSelectedWeek;
-
-        private int mFocusedMonth;
-
-        private int mTotalWeekCount;
-
-        public WeeksAdapter() {
-            mGestureDetector = new GestureDetector(mContext, new CalendarGestureListener());
-            init();
         }
 
         /**
-         * Set up the gesture detector and selected time
+         * <p>
+         * This is a specialized adapter for creating a list of weeks with
+         * selectable days. It can be configured to display the week number, start
+         * the week on a given day, show a reduced number of days, or display an
+         * arbitrary number of weeks at a time.
+         * </p>
          */
-        private void init() {
-            mSelectedWeek = getWeeksSinceMinDate(mSelectedDate);
-            mTotalWeekCount = getWeeksSinceMinDate(mMaxDate);
-            if (mMinDate.get(Calendar.DAY_OF_WEEK) != mFirstDayOfWeek
-                || mMaxDate.get(Calendar.DAY_OF_WEEK) != mFirstDayOfWeek) {
-                mTotalWeekCount++;
-            }
-            notifyDataSetChanged();
-        }
+        private class WeeksAdapter extends BaseAdapter implements OnTouchListener {
 
-        /**
-         * Updates the selected day and related parameters.
-         *
-         * @param selectedDay The time to highlight
-         */
-        public void setSelectedDay(Calendar selectedDay) {
-            if (selectedDay.get(Calendar.DAY_OF_YEAR) == mSelectedDate.get(Calendar.DAY_OF_YEAR)
-                    && selectedDay.get(Calendar.YEAR) == mSelectedDate.get(Calendar.YEAR)) {
-                return;
-            }
-            mSelectedDate.setTimeInMillis(selectedDay.getTimeInMillis());
-            mSelectedWeek = getWeeksSinceMinDate(mSelectedDate);
-            mFocusedMonth = mSelectedDate.get(Calendar.MONTH);
-            notifyDataSetChanged();
-        }
+            private int mSelectedWeek;
 
-        /**
-         * @return The selected day of month.
-         */
-        public Calendar getSelectedDay() {
-            return mSelectedDate;
-        }
+            private GestureDetector mGestureDetector;
 
-        @Override
-        public int getCount() {
-            return mTotalWeekCount;
-        }
+            private int mFocusedMonth;
 
-        @Override
-        public Object getItem(int position) {
-            return null;
-        }
+            private final Calendar mSelectedDate = Calendar.getInstance();
 
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
+            private int mTotalWeekCount;
 
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            WeekView weekView = null;
-            if (convertView != null) {
-                weekView = (WeekView) convertView;
-            } else {
-                weekView = new WeekView(mContext);
-                android.widget.AbsListView.LayoutParams params =
-                    new android.widget.AbsListView.LayoutParams(LayoutParams.WRAP_CONTENT,
-                            LayoutParams.WRAP_CONTENT);
-                weekView.setLayoutParams(params);
-                weekView.setClickable(true);
-                weekView.setOnTouchListener(this);
+            public WeeksAdapter(Context context) {
+                mContext = context;
+                mGestureDetector = new GestureDetector(mContext, new CalendarGestureListener());
+                init();
             }
 
-            int selectedWeekDay = (mSelectedWeek == position) ? mSelectedDate.get(
-                    Calendar.DAY_OF_WEEK) : -1;
-            weekView.init(position, selectedWeekDay, mFocusedMonth);
-
-            return weekView;
-        }
-
-        /**
-         * Changes which month is in focus and updates the view.
-         *
-         * @param month The month to show as in focus [0-11]
-         */
-        public void setFocusMonth(int month) {
-            if (mFocusedMonth == month) {
-                return;
-            }
-            mFocusedMonth = month;
-            notifyDataSetChanged();
-        }
-
-        @Override
-        public boolean onTouch(View v, MotionEvent event) {
-            if (mListView.isEnabled() && mGestureDetector.onTouchEvent(event)) {
-                WeekView weekView = (WeekView) v;
-                // if we cannot find a day for the given location we are done
-                if (!weekView.getDayFromLocation(event.getX(), mTempDate)) {
-                    return true;
+            /**
+             * Set up the gesture detector and selected time
+             */
+            private void init() {
+                mSelectedWeek = getWeeksSinceMinDate(mSelectedDate);
+                mTotalWeekCount = getWeeksSinceMinDate(mMaxDate);
+                if (mMinDate.get(Calendar.DAY_OF_WEEK) != mFirstDayOfWeek
+                        || mMaxDate.get(Calendar.DAY_OF_WEEK) != mFirstDayOfWeek) {
+                    mTotalWeekCount++;
                 }
-                // it is possible that the touched day is outside the valid range
-                // we draw whole weeks but range end can fall not on the week end
-                if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
-                    return true;
-                }
-                onDateTapped(mTempDate);
-                return true;
             }
-            return false;
-        }
 
-        /**
-         * Maintains the same hour/min/sec but moves the day to the tapped day.
-         *
-         * @param day The day that was tapped
-         */
-        private void onDateTapped(Calendar day) {
-            setSelectedDay(day);
-            setMonthDisplayed(day);
-        }
+            /**
+             * Updates the selected day and related parameters.
+             *
+             * @param selectedDay The time to highlight
+             */
+            public void setSelectedDay(Calendar selectedDay) {
+                if (selectedDay.get(Calendar.DAY_OF_YEAR) == mSelectedDate.get(Calendar.DAY_OF_YEAR)
+                        && selectedDay.get(Calendar.YEAR) == mSelectedDate.get(Calendar.YEAR)) {
+                    return;
+                }
+                mSelectedDate.setTimeInMillis(selectedDay.getTimeInMillis());
+                mSelectedWeek = getWeeksSinceMinDate(mSelectedDate);
+                mFocusedMonth = mSelectedDate.get(Calendar.MONTH);
+                notifyDataSetChanged();
+            }
 
-        /**
-         * This is here so we can identify single tap events and set the
-         * selected day correctly
-         */
-        class CalendarGestureListener extends GestureDetector.SimpleOnGestureListener {
+            /**
+             * @return The selected day of month.
+             */
+            public Calendar getSelectedDay() {
+                return mSelectedDate;
+            }
+
             @Override
-            public boolean onSingleTapUp(MotionEvent e) {
-                return true;
-            }
-        }
-    }
-
-    /**
-     * <p>
-     * This is a dynamic view for drawing a single week. It can be configured to
-     * display the week number, start the week on a given day, or show a reduced
-     * number of days. It is intended for use as a single view within a
-     * ListView. See {@link WeeksAdapter} for usage.
-     * </p>
-     */
-    private class WeekView extends View {
-
-        private final Rect mTempRect = new Rect();
-
-        private final Paint mDrawPaint = new Paint();
-
-        private final Paint mMonthNumDrawPaint = new Paint();
-
-        // Cache the number strings so we don't have to recompute them each time
-        private String[] mDayNumbers;
-
-        // Quick lookup for checking which days are in the focus month
-        private boolean[] mFocusDay;
-
-        // Whether this view has a focused day.
-        private boolean mHasFocusedDay;
-
-        // Whether this view has only focused days.
-        private boolean mHasUnfocusedDay;
-
-        // The first day displayed by this item
-        private Calendar mFirstDay;
-
-        // The month of the first day in this week
-        private int mMonthOfFirstWeekDay = -1;
-
-        // The month of the last day in this week
-        private int mLastWeekDayMonth = -1;
-
-        // The position of this week, equivalent to weeks since the week of Jan
-        // 1st, 1900
-        private int mWeek = -1;
-
-        // Quick reference to the width of this view, matches parent
-        private int mWidth;
-
-        // The height this view should draw at in pixels, set by height param
-        private int mHeight;
-
-        // If this view contains the selected day
-        private boolean mHasSelectedDay = false;
-
-        // Which day is selected [0-6] or -1 if no day is selected
-        private int mSelectedDay = -1;
-
-        // The number of days + a spot for week number if it is displayed
-        private int mNumCells;
-
-        // The left edge of the selected day
-        private int mSelectedLeft = -1;
-
-        // The right edge of the selected day
-        private int mSelectedRight = -1;
-
-        public WeekView(Context context) {
-            super(context);
-
-            // Sets up any standard paints that will be used
-            initilaizePaints();
-        }
-
-        /**
-         * Initializes this week view.
-         *
-         * @param weekNumber The number of the week this view represents. The
-         *            week number is a zero based index of the weeks since
-         *            {@link CalendarView#getMinDate()}.
-         * @param selectedWeekDay The selected day of the week from 0 to 6, -1 if no
-         *            selected day.
-         * @param focusedMonth The month that is currently in focus i.e.
-         *            highlighted.
-         */
-        public void init(int weekNumber, int selectedWeekDay, int focusedMonth) {
-            mSelectedDay = selectedWeekDay;
-            mHasSelectedDay = mSelectedDay != -1;
-            mNumCells = mShowWeekNumber ? mDaysPerWeek + 1 : mDaysPerWeek;
-            mWeek = weekNumber;
-            mTempDate.setTimeInMillis(mMinDate.getTimeInMillis());
-
-            mTempDate.add(Calendar.WEEK_OF_YEAR, mWeek);
-            mTempDate.setFirstDayOfWeek(mFirstDayOfWeek);
-
-            // Allocate space for caching the day numbers and focus values
-            mDayNumbers = new String[mNumCells];
-            mFocusDay = new boolean[mNumCells];
-
-            // If we're showing the week number calculate it based on Monday
-            int i = 0;
-            if (mShowWeekNumber) {
-                mDayNumbers[0] = String.format(Locale.getDefault(), "%d",
-                        mTempDate.get(Calendar.WEEK_OF_YEAR));
-                i++;
+            public int getCount() {
+                return mTotalWeekCount;
             }
 
-            // Now adjust our starting day based on the start day of the week
-            int diff = mFirstDayOfWeek - mTempDate.get(Calendar.DAY_OF_WEEK);
-            mTempDate.add(Calendar.DAY_OF_MONTH, diff);
+            @Override
+            public Object getItem(int position) {
+                return null;
+            }
 
-            mFirstDay = (Calendar) mTempDate.clone();
-            mMonthOfFirstWeekDay = mTempDate.get(Calendar.MONTH);
+            @Override
+            public long getItemId(int position) {
+                return position;
+            }
 
-            mHasUnfocusedDay = true;
-            for (; i < mNumCells; i++) {
-                final boolean isFocusedDay = (mTempDate.get(Calendar.MONTH) == focusedMonth);
-                mFocusDay[i] = isFocusedDay;
-                mHasFocusedDay |= isFocusedDay;
-                mHasUnfocusedDay &= !isFocusedDay;
-                // do not draw dates outside the valid range to avoid user confusion
-                if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
-                    mDayNumbers[i] = "";
+            @Override
+            public View getView(int position, View convertView, ViewGroup parent) {
+                WeekView weekView = null;
+                if (convertView != null) {
+                    weekView = (WeekView) convertView;
                 } else {
-                    mDayNumbers[i] = String.format(Locale.getDefault(), "%d",
-                            mTempDate.get(Calendar.DAY_OF_MONTH));
+                    weekView = new WeekView(mContext);
+                    android.widget.AbsListView.LayoutParams params =
+                            new android.widget.AbsListView.LayoutParams(LayoutParams.WRAP_CONTENT,
+                                    LayoutParams.WRAP_CONTENT);
+                    weekView.setLayoutParams(params);
+                    weekView.setClickable(true);
+                    weekView.setOnTouchListener(this);
                 }
-                mTempDate.add(Calendar.DAY_OF_MONTH, 1);
-            }
-            // We do one extra add at the end of the loop, if that pushed us to
-            // new month undo it
-            if (mTempDate.get(Calendar.DAY_OF_MONTH) == 1) {
-                mTempDate.add(Calendar.DAY_OF_MONTH, -1);
-            }
-            mLastWeekDayMonth = mTempDate.get(Calendar.MONTH);
 
-            updateSelectionPositions();
-        }
+                int selectedWeekDay = (mSelectedWeek == position) ? mSelectedDate.get(
+                        Calendar.DAY_OF_WEEK) : -1;
+                weekView.init(position, selectedWeekDay, mFocusedMonth);
 
-        /**
-         * Initialize the paint instances.
-         */
-        private void initilaizePaints() {
-            mDrawPaint.setFakeBoldText(false);
-            mDrawPaint.setAntiAlias(true);
-            mDrawPaint.setStyle(Style.FILL);
-
-            mMonthNumDrawPaint.setFakeBoldText(true);
-            mMonthNumDrawPaint.setAntiAlias(true);
-            mMonthNumDrawPaint.setStyle(Style.FILL);
-            mMonthNumDrawPaint.setTextAlign(Align.CENTER);
-            mMonthNumDrawPaint.setTextSize(mDateTextSize);
-        }
-
-        /**
-         * Returns the month of the first day in this week.
-         *
-         * @return The month the first day of this view is in.
-         */
-        public int getMonthOfFirstWeekDay() {
-            return mMonthOfFirstWeekDay;
-        }
-
-        /**
-         * Returns the month of the last day in this week
-         *
-         * @return The month the last day of this view is in
-         */
-        public int getMonthOfLastWeekDay() {
-            return mLastWeekDayMonth;
-        }
-
-        /**
-         * Returns the first day in this view.
-         *
-         * @return The first day in the view.
-         */
-        public Calendar getFirstDay() {
-            return mFirstDay;
-        }
-
-        /**
-         * Calculates the day that the given x position is in, accounting for
-         * week number.
-         *
-         * @param x The x position of the touch event.
-         * @return True if a day was found for the given location.
-         */
-        public boolean getDayFromLocation(float x, Calendar outCalendar) {
-            final boolean isLayoutRtl = isLayoutRtl();
-
-            int start;
-            int end;
-
-            if (isLayoutRtl) {
-                start = 0;
-                end = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
-            } else {
-                start = mShowWeekNumber ? mWidth / mNumCells : 0;
-                end = mWidth;
+                return weekView;
             }
 
-            if (x < start || x > end) {
-                outCalendar.clear();
+            /**
+             * Changes which month is in focus and updates the view.
+             *
+             * @param month The month to show as in focus [0-11]
+             */
+            public void setFocusMonth(int month) {
+                if (mFocusedMonth == month) {
+                    return;
+                }
+                mFocusedMonth = month;
+                notifyDataSetChanged();
+            }
+
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                if (mListView.isEnabled() && mGestureDetector.onTouchEvent(event)) {
+                    WeekView weekView = (WeekView) v;
+                    // if we cannot find a day for the given location we are done
+                    if (!weekView.getDayFromLocation(event.getX(), mTempDate)) {
+                        return true;
+                    }
+                    // it is possible that the touched day is outside the valid range
+                    // we draw whole weeks but range end can fall not on the week end
+                    if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
+                        return true;
+                    }
+                    onDateTapped(mTempDate);
+                    return true;
+                }
                 return false;
             }
 
-            // Selection is (x - start) / (pixels/day) which is (x - start) * day / pixels
-            int dayPosition = (int) ((x - start) * mDaysPerWeek / (end - start));
-
-            if (isLayoutRtl) {
-                dayPosition = mDaysPerWeek - 1 - dayPosition;
+            /**
+             * Maintains the same hour/min/sec but moves the day to the tapped day.
+             *
+             * @param day The day that was tapped
+             */
+            private void onDateTapped(Calendar day) {
+                setSelectedDay(day);
+                setMonthDisplayed(day);
             }
 
-            outCalendar.setTimeInMillis(mFirstDay.getTimeInMillis());
-            outCalendar.add(Calendar.DAY_OF_MONTH, dayPosition);
-
-            return true;
-        }
-
-        @Override
-        protected void onDraw(Canvas canvas) {
-            drawBackground(canvas);
-            drawWeekNumbersAndDates(canvas);
-            drawWeekSeparators(canvas);
-            drawSelectedDateVerticalBars(canvas);
+            /**
+             * This is here so we can identify single tap events and set the
+             * selected day correctly
+             */
+            class CalendarGestureListener extends GestureDetector.SimpleOnGestureListener {
+                @Override
+                public boolean onSingleTapUp(MotionEvent e) {
+                    return true;
+                }
+            }
         }
 
         /**
-         * This draws the selection highlight if a day is selected in this week.
-         *
-         * @param canvas The canvas to draw on
+         * <p>
+         * This is a dynamic view for drawing a single week. It can be configured to
+         * display the week number, start the week on a given day, or show a reduced
+         * number of days. It is intended for use as a single view within a
+         * ListView. See {@link WeeksAdapter} for usage.
+         * </p>
          */
-        private void drawBackground(Canvas canvas) {
-            if (!mHasSelectedDay) {
-                return;
+        private class WeekView extends View {
+
+            private final Rect mTempRect = new Rect();
+
+            private final Paint mDrawPaint = new Paint();
+
+            private final Paint mMonthNumDrawPaint = new Paint();
+
+            // Cache the number strings so we don't have to recompute them each time
+            private String[] mDayNumbers;
+
+            // Quick lookup for checking which days are in the focus month
+            private boolean[] mFocusDay;
+
+            // Whether this view has a focused day.
+            private boolean mHasFocusedDay;
+
+            // Whether this view has only focused days.
+            private boolean mHasUnfocusedDay;
+
+            // The first day displayed by this item
+            private Calendar mFirstDay;
+
+            // The month of the first day in this week
+            private int mMonthOfFirstWeekDay = -1;
+
+            // The month of the last day in this week
+            private int mLastWeekDayMonth = -1;
+
+            // The position of this week, equivalent to weeks since the week of Jan
+            // 1st, 1900
+            private int mWeek = -1;
+
+            // Quick reference to the width of this view, matches parent
+            private int mWidth;
+
+            // The height this view should draw at in pixels, set by height param
+            private int mHeight;
+
+            // If this view contains the selected day
+            private boolean mHasSelectedDay = false;
+
+            // Which day is selected [0-6] or -1 if no day is selected
+            private int mSelectedDay = -1;
+
+            // The number of days + a spot for week number if it is displayed
+            private int mNumCells;
+
+            // The left edge of the selected day
+            private int mSelectedLeft = -1;
+
+            // The right edge of the selected day
+            private int mSelectedRight = -1;
+
+            public WeekView(Context context) {
+                super(context);
+
+                // Sets up any standard paints that will be used
+                initilaizePaints();
             }
-            mDrawPaint.setColor(mSelectedWeekBackgroundColor);
 
-            mTempRect.top = mWeekSeperatorLineWidth;
-            mTempRect.bottom = mHeight;
+            /**
+             * Initializes this week view.
+             *
+             * @param weekNumber The number of the week this view represents. The
+             *            week number is a zero based index of the weeks since
+             *            {@link CalendarView#getMinDate()}.
+             * @param selectedWeekDay The selected day of the week from 0 to 6, -1 if no
+             *            selected day.
+             * @param focusedMonth The month that is currently in focus i.e.
+             *            highlighted.
+             */
+            public void init(int weekNumber, int selectedWeekDay, int focusedMonth) {
+                mSelectedDay = selectedWeekDay;
+                mHasSelectedDay = mSelectedDay != -1;
+                mNumCells = mShowWeekNumber ? mDaysPerWeek + 1 : mDaysPerWeek;
+                mWeek = weekNumber;
+                mTempDate.setTimeInMillis(mMinDate.getTimeInMillis());
 
-            final boolean isLayoutRtl = isLayoutRtl();
+                mTempDate.add(Calendar.WEEK_OF_YEAR, mWeek);
+                mTempDate.setFirstDayOfWeek(mFirstDayOfWeek);
 
-            if (isLayoutRtl) {
-                mTempRect.left = 0;
-                mTempRect.right = mSelectedLeft - 2;
-            } else {
-                mTempRect.left = mShowWeekNumber ? mWidth / mNumCells : 0;
-                mTempRect.right = mSelectedLeft - 2;
-            }
-            canvas.drawRect(mTempRect, mDrawPaint);
+                // Allocate space for caching the day numbers and focus values
+                mDayNumbers = new String[mNumCells];
+                mFocusDay = new boolean[mNumCells];
 
-            if (isLayoutRtl) {
-                mTempRect.left = mSelectedRight + 3;
-                mTempRect.right = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
-            } else {
-                mTempRect.left = mSelectedRight + 3;
-                mTempRect.right = mWidth;
-            }
-            canvas.drawRect(mTempRect, mDrawPaint);
-        }
-
-        /**
-         * Draws the week and month day numbers for this week.
-         *
-         * @param canvas The canvas to draw on
-         */
-        private void drawWeekNumbersAndDates(Canvas canvas) {
-            final float textHeight = mDrawPaint.getTextSize();
-            final int y = (int) ((mHeight + textHeight) / 2) - mWeekSeperatorLineWidth;
-            final int nDays = mNumCells;
-            final int divisor = 2 * nDays;
-
-            mDrawPaint.setTextAlign(Align.CENTER);
-            mDrawPaint.setTextSize(mDateTextSize);
-
-            int i = 0;
-
-            if (isLayoutRtl()) {
-                for (; i < nDays - 1; i++) {
-                    mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
-                            : mUnfocusedMonthDateColor);
-                    int x = (2 * i + 1) * mWidth / divisor;
-                    canvas.drawText(mDayNumbers[nDays - 1 - i], x, y, mMonthNumDrawPaint);
-                }
+                // If we're showing the week number calculate it based on Monday
+                int i = 0;
                 if (mShowWeekNumber) {
-                    mDrawPaint.setColor(mWeekNumberColor);
-                    int x = mWidth - mWidth / divisor;
-                    canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
-                }
-            } else {
-                if (mShowWeekNumber) {
-                    mDrawPaint.setColor(mWeekNumberColor);
-                    int x = mWidth / divisor;
-                    canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
+                    mDayNumbers[0] = String.format(Locale.getDefault(), "%d",
+                            mTempDate.get(Calendar.WEEK_OF_YEAR));
                     i++;
                 }
-                for (; i < nDays; i++) {
-                    mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
-                            : mUnfocusedMonthDateColor);
-                    int x = (2 * i + 1) * mWidth / divisor;
-                    canvas.drawText(mDayNumbers[i], x, y, mMonthNumDrawPaint);
+
+                // Now adjust our starting day based on the start day of the week
+                int diff = mFirstDayOfWeek - mTempDate.get(Calendar.DAY_OF_WEEK);
+                mTempDate.add(Calendar.DAY_OF_MONTH, diff);
+
+                mFirstDay = (Calendar) mTempDate.clone();
+                mMonthOfFirstWeekDay = mTempDate.get(Calendar.MONTH);
+
+                mHasUnfocusedDay = true;
+                for (; i < mNumCells; i++) {
+                    final boolean isFocusedDay = (mTempDate.get(Calendar.MONTH) == focusedMonth);
+                    mFocusDay[i] = isFocusedDay;
+                    mHasFocusedDay |= isFocusedDay;
+                    mHasUnfocusedDay &= !isFocusedDay;
+                    // do not draw dates outside the valid range to avoid user confusion
+                    if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
+                        mDayNumbers[i] = "";
+                    } else {
+                        mDayNumbers[i] = String.format(Locale.getDefault(), "%d",
+                                mTempDate.get(Calendar.DAY_OF_MONTH));
+                    }
+                    mTempDate.add(Calendar.DAY_OF_MONTH, 1);
                 }
-            }
-        }
+                // We do one extra add at the end of the loop, if that pushed us to
+                // new month undo it
+                if (mTempDate.get(Calendar.DAY_OF_MONTH) == 1) {
+                    mTempDate.add(Calendar.DAY_OF_MONTH, -1);
+                }
+                mLastWeekDayMonth = mTempDate.get(Calendar.MONTH);
 
-        /**
-         * Draws a horizontal line for separating the weeks.
-         *
-         * @param canvas The canvas to draw on.
-         */
-        private void drawWeekSeparators(Canvas canvas) {
-            // If it is the topmost fully visible child do not draw separator line
-            int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
-            if (mListView.getChildAt(0).getTop() < 0) {
-                firstFullyVisiblePosition++;
+                updateSelectionPositions();
             }
-            if (firstFullyVisiblePosition == mWeek) {
-                return;
-            }
-            mDrawPaint.setColor(mWeekSeparatorLineColor);
-            mDrawPaint.setStrokeWidth(mWeekSeperatorLineWidth);
-            float startX;
-            float stopX;
-            if (isLayoutRtl()) {
-                startX = 0;
-                stopX = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
-            } else {
-                startX = mShowWeekNumber ? mWidth / mNumCells : 0;
-                stopX = mWidth;
-            }
-            canvas.drawLine(startX, 0, stopX, 0, mDrawPaint);
-        }
 
-        /**
-         * Draws the selected date bars if this week has a selected day.
-         *
-         * @param canvas The canvas to draw on
-         */
-        private void drawSelectedDateVerticalBars(Canvas canvas) {
-            if (!mHasSelectedDay) {
-                return;
+            /**
+             * Initialize the paint instances.
+             */
+            private void initilaizePaints() {
+                mDrawPaint.setFakeBoldText(false);
+                mDrawPaint.setAntiAlias(true);
+                mDrawPaint.setStyle(Style.FILL);
+
+                mMonthNumDrawPaint.setFakeBoldText(true);
+                mMonthNumDrawPaint.setAntiAlias(true);
+                mMonthNumDrawPaint.setStyle(Style.FILL);
+                mMonthNumDrawPaint.setTextAlign(Align.CENTER);
+                mMonthNumDrawPaint.setTextSize(mDateTextSize);
             }
-            mSelectedDateVerticalBar.setBounds(mSelectedLeft - mSelectedDateVerticalBarWidth / 2,
-                    mWeekSeperatorLineWidth,
-                    mSelectedLeft + mSelectedDateVerticalBarWidth / 2, mHeight);
-            mSelectedDateVerticalBar.draw(canvas);
-            mSelectedDateVerticalBar.setBounds(mSelectedRight - mSelectedDateVerticalBarWidth / 2,
-                    mWeekSeperatorLineWidth,
-                    mSelectedRight + mSelectedDateVerticalBarWidth / 2, mHeight);
-            mSelectedDateVerticalBar.draw(canvas);
-        }
 
-        @Override
-        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-            mWidth = w;
-            updateSelectionPositions();
-        }
+            /**
+             * Returns the month of the first day in this week.
+             *
+             * @return The month the first day of this view is in.
+             */
+            public int getMonthOfFirstWeekDay() {
+                return mMonthOfFirstWeekDay;
+            }
 
-        /**
-         * This calculates the positions for the selected day lines.
-         */
-        private void updateSelectionPositions() {
-            if (mHasSelectedDay) {
+            /**
+             * Returns the month of the last day in this week
+             *
+             * @return The month the last day of this view is in
+             */
+            public int getMonthOfLastWeekDay() {
+                return mLastWeekDayMonth;
+            }
+
+            /**
+             * Returns the first day in this view.
+             *
+             * @return The first day in the view.
+             */
+            public Calendar getFirstDay() {
+                return mFirstDay;
+            }
+
+            /**
+             * Calculates the day that the given x position is in, accounting for
+             * week number.
+             *
+             * @param x The x position of the touch event.
+             * @return True if a day was found for the given location.
+             */
+            public boolean getDayFromLocation(float x, Calendar outCalendar) {
                 final boolean isLayoutRtl = isLayoutRtl();
-                int selectedPosition = mSelectedDay - mFirstDayOfWeek;
-                if (selectedPosition < 0) {
-                    selectedPosition += 7;
-                }
-                if (mShowWeekNumber && !isLayoutRtl) {
-                    selectedPosition++;
-                }
-                if (isLayoutRtl) {
-                    mSelectedLeft = (mDaysPerWeek - 1 - selectedPosition) * mWidth / mNumCells;
 
+                int start;
+                int end;
+
+                if (isLayoutRtl) {
+                    start = 0;
+                    end = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
                 } else {
-                    mSelectedLeft = selectedPosition * mWidth / mNumCells;
+                    start = mShowWeekNumber ? mWidth / mNumCells : 0;
+                    end = mWidth;
                 }
-                mSelectedRight = mSelectedLeft + mWidth / mNumCells;
+
+                if (x < start || x > end) {
+                    outCalendar.clear();
+                    return false;
+                }
+
+                // Selection is (x - start) / (pixels/day) which is (x - start) * day / pixels
+                int dayPosition = (int) ((x - start) * mDaysPerWeek / (end - start));
+
+                if (isLayoutRtl) {
+                    dayPosition = mDaysPerWeek - 1 - dayPosition;
+                }
+
+                outCalendar.setTimeInMillis(mFirstDay.getTimeInMillis());
+                outCalendar.add(Calendar.DAY_OF_MONTH, dayPosition);
+
+                return true;
+            }
+
+            @Override
+            protected void onDraw(Canvas canvas) {
+                drawBackground(canvas);
+                drawWeekNumbersAndDates(canvas);
+                drawWeekSeparators(canvas);
+                drawSelectedDateVerticalBars(canvas);
+            }
+
+            /**
+             * This draws the selection highlight if a day is selected in this week.
+             *
+             * @param canvas The canvas to draw on
+             */
+            private void drawBackground(Canvas canvas) {
+                if (!mHasSelectedDay) {
+                    return;
+                }
+                mDrawPaint.setColor(mSelectedWeekBackgroundColor);
+
+                mTempRect.top = mWeekSeperatorLineWidth;
+                mTempRect.bottom = mHeight;
+
+                final boolean isLayoutRtl = isLayoutRtl();
+
+                if (isLayoutRtl) {
+                    mTempRect.left = 0;
+                    mTempRect.right = mSelectedLeft - 2;
+                } else {
+                    mTempRect.left = mShowWeekNumber ? mWidth / mNumCells : 0;
+                    mTempRect.right = mSelectedLeft - 2;
+                }
+                canvas.drawRect(mTempRect, mDrawPaint);
+
+                if (isLayoutRtl) {
+                    mTempRect.left = mSelectedRight + 3;
+                    mTempRect.right = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
+                } else {
+                    mTempRect.left = mSelectedRight + 3;
+                    mTempRect.right = mWidth;
+                }
+                canvas.drawRect(mTempRect, mDrawPaint);
+            }
+
+            /**
+             * Draws the week and month day numbers for this week.
+             *
+             * @param canvas The canvas to draw on
+             */
+            private void drawWeekNumbersAndDates(Canvas canvas) {
+                final float textHeight = mDrawPaint.getTextSize();
+                final int y = (int) ((mHeight + textHeight) / 2) - mWeekSeperatorLineWidth;
+                final int nDays = mNumCells;
+                final int divisor = 2 * nDays;
+
+                mDrawPaint.setTextAlign(Align.CENTER);
+                mDrawPaint.setTextSize(mDateTextSize);
+
+                int i = 0;
+
+                if (isLayoutRtl()) {
+                    for (; i < nDays - 1; i++) {
+                        mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
+                                : mUnfocusedMonthDateColor);
+                        int x = (2 * i + 1) * mWidth / divisor;
+                        canvas.drawText(mDayNumbers[nDays - 1 - i], x, y, mMonthNumDrawPaint);
+                    }
+                    if (mShowWeekNumber) {
+                        mDrawPaint.setColor(mWeekNumberColor);
+                        int x = mWidth - mWidth / divisor;
+                        canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
+                    }
+                } else {
+                    if (mShowWeekNumber) {
+                        mDrawPaint.setColor(mWeekNumberColor);
+                        int x = mWidth / divisor;
+                        canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
+                        i++;
+                    }
+                    for (; i < nDays; i++) {
+                        mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
+                                : mUnfocusedMonthDateColor);
+                        int x = (2 * i + 1) * mWidth / divisor;
+                        canvas.drawText(mDayNumbers[i], x, y, mMonthNumDrawPaint);
+                    }
+                }
+            }
+
+            /**
+             * Draws a horizontal line for separating the weeks.
+             *
+             * @param canvas The canvas to draw on.
+             */
+            private void drawWeekSeparators(Canvas canvas) {
+                // If it is the topmost fully visible child do not draw separator line
+                int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
+                if (mListView.getChildAt(0).getTop() < 0) {
+                    firstFullyVisiblePosition++;
+                }
+                if (firstFullyVisiblePosition == mWeek) {
+                    return;
+                }
+                mDrawPaint.setColor(mWeekSeparatorLineColor);
+                mDrawPaint.setStrokeWidth(mWeekSeperatorLineWidth);
+                float startX;
+                float stopX;
+                if (isLayoutRtl()) {
+                    startX = 0;
+                    stopX = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
+                } else {
+                    startX = mShowWeekNumber ? mWidth / mNumCells : 0;
+                    stopX = mWidth;
+                }
+                canvas.drawLine(startX, 0, stopX, 0, mDrawPaint);
+            }
+
+            /**
+             * Draws the selected date bars if this week has a selected day.
+             *
+             * @param canvas The canvas to draw on
+             */
+            private void drawSelectedDateVerticalBars(Canvas canvas) {
+                if (!mHasSelectedDay) {
+                    return;
+                }
+                mSelectedDateVerticalBar.setBounds(
+                        mSelectedLeft - mSelectedDateVerticalBarWidth / 2,
+                        mWeekSeperatorLineWidth,
+                        mSelectedLeft + mSelectedDateVerticalBarWidth / 2,
+                        mHeight);
+                mSelectedDateVerticalBar.draw(canvas);
+                mSelectedDateVerticalBar.setBounds(
+                        mSelectedRight - mSelectedDateVerticalBarWidth / 2,
+                        mWeekSeperatorLineWidth,
+                        mSelectedRight + mSelectedDateVerticalBarWidth / 2,
+                        mHeight);
+                mSelectedDateVerticalBar.draw(canvas);
+            }
+
+            @Override
+            protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+                mWidth = w;
+                updateSelectionPositions();
+            }
+
+            /**
+             * This calculates the positions for the selected day lines.
+             */
+            private void updateSelectionPositions() {
+                if (mHasSelectedDay) {
+                    final boolean isLayoutRtl = isLayoutRtl();
+                    int selectedPosition = mSelectedDay - mFirstDayOfWeek;
+                    if (selectedPosition < 0) {
+                        selectedPosition += 7;
+                    }
+                    if (mShowWeekNumber && !isLayoutRtl) {
+                        selectedPosition++;
+                    }
+                    if (isLayoutRtl) {
+                        mSelectedLeft = (mDaysPerWeek - 1 - selectedPosition) * mWidth / mNumCells;
+
+                    } else {
+                        mSelectedLeft = selectedPosition * mWidth / mNumCells;
+                    }
+                    mSelectedRight = mSelectedLeft + mWidth / mNumCells;
+                }
+            }
+
+            @Override
+            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+                mHeight = (mListView.getHeight() - mListView.getPaddingTop() - mListView
+                        .getPaddingBottom()) / mShownWeekCount;
+                setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mHeight);
             }
         }
 
-        @Override
-        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-            mHeight = (mListView.getHeight() - mListView.getPaddingTop() - mListView
-                    .getPaddingBottom()) / mShownWeekCount;
-            setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mHeight);
-        }
     }
+
 }
diff --git a/core/java/android/widget/CheckBox.java b/core/java/android/widget/CheckBox.java
index f1804f8..71438c9 100644
--- a/core/java/android/widget/CheckBox.java
+++ b/core/java/android/widget/CheckBox.java
@@ -64,8 +64,12 @@
         this(context, attrs, com.android.internal.R.attr.checkboxStyle);
     }
 
-    public CheckBox(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public CheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public CheckBox(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 5c10a77..78b1b75 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -58,11 +58,15 @@
         this(context, attrs, R.attr.checkedTextViewStyle);
     }
 
-    public CheckedTextView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public CheckedTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                R.styleable.CheckedTextView, defStyle, 0);
+    public CheckedTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.CheckedTextView, defStyleAttr, defStyleRes);
 
         Drawable d = a.getDrawable(R.styleable.CheckedTextView_checkMark);
         if (d != null) {
diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java
index b7a126e..f94789d 100644
--- a/core/java/android/widget/Chronometer.java
+++ b/core/java/android/widget/Chronometer.java
@@ -18,14 +18,12 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.graphics.Canvas;
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemClock;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.util.Slog;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.RemoteViews.RemoteView;
@@ -96,12 +94,15 @@
      * Initialize with standard view layout information and style.
      * Sets the base to the current time.
      */
-    public Chronometer(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public Chronometer(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(
-                attrs,
-                com.android.internal.R.styleable.Chronometer, defStyle, 0);
+    public Chronometer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.Chronometer, defStyleAttr, defStyleRes);
         setFormat(a.getString(com.android.internal.R.styleable.Chronometer_format));
         a.recycle();
 
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 082ff3d..bdb5046 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -64,12 +64,15 @@
         this(context, attrs, 0);
     }
 
-    public CompoundButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public CompoundButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a =
-                context.obtainStyledAttributes(
-                        attrs, com.android.internal.R.styleable.CompoundButton, defStyle, 0);
+    public CompoundButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.CompoundButton, defStyleAttr, defStyleRes);
 
         Drawable d = a.getDrawable(com.android.internal.R.styleable.CompoundButton_button);
         if (d != null) {
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index d03161e..265dbcd 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -24,7 +24,6 @@
 import android.os.Parcelable;
 import android.text.TextUtils;
 import android.text.InputType;
-import android.text.format.DateFormat;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -76,53 +75,7 @@
 
     private static final String LOG_TAG = DatePicker.class.getSimpleName();
 
-    private static final String DATE_FORMAT = "MM/dd/yyyy";
-
-    private static final int DEFAULT_START_YEAR = 1900;
-
-    private static final int DEFAULT_END_YEAR = 2100;
-
-    private static final boolean DEFAULT_CALENDAR_VIEW_SHOWN = true;
-
-    private static final boolean DEFAULT_SPINNERS_SHOWN = true;
-
-    private static final boolean DEFAULT_ENABLED_STATE = true;
-
-    private final LinearLayout mSpinners;
-
-    private final NumberPicker mDaySpinner;
-
-    private final NumberPicker mMonthSpinner;
-
-    private final NumberPicker mYearSpinner;
-
-    private final EditText mDaySpinnerInput;
-
-    private final EditText mMonthSpinnerInput;
-
-    private final EditText mYearSpinnerInput;
-
-    private final CalendarView mCalendarView;
-
-    private Locale mCurrentLocale;
-
-    private OnDateChangedListener mOnDateChangedListener;
-
-    private String[] mShortMonths;
-
-    private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
-
-    private int mNumberOfMonths;
-
-    private Calendar mTempDate;
-
-    private Calendar mMinDate;
-
-    private Calendar mMaxDate;
-
-    private Calendar mCurrentDate;
-
-    private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
+    private DatePickerDelegate mDelegate;
 
     /**
      * The callback used to indicate the user changes\d the date.
@@ -149,443 +102,14 @@
         this(context, attrs, R.attr.datePickerStyle);
     }
 
-    public DatePicker(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        // initialization based on locale
-        setCurrentLocale(Locale.getDefault());
-
-        TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
-                defStyle, 0);
-        boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown,
-                DEFAULT_SPINNERS_SHOWN);
-        boolean calendarViewShown = attributesArray.getBoolean(
-                R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN);
-        int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear,
-                DEFAULT_START_YEAR);
-        int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
-        String minDate = attributesArray.getString(R.styleable.DatePicker_minDate);
-        String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate);
-        int layoutResourceId = attributesArray.getResourceId(R.styleable.DatePicker_internalLayout,
-                R.layout.date_picker);
-        attributesArray.recycle();
-
-        LayoutInflater inflater = (LayoutInflater) context
-                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(layoutResourceId, this, true);
-
-        OnValueChangeListener onChangeListener = new OnValueChangeListener() {
-            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
-                updateInputState();
-                mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
-                // take care of wrapping of days and months to update greater fields
-                if (picker == mDaySpinner) {
-                    int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH);
-                    if (oldVal == maxDayOfMonth && newVal == 1) {
-                        mTempDate.add(Calendar.DAY_OF_MONTH, 1);
-                    } else if (oldVal == 1 && newVal == maxDayOfMonth) {
-                        mTempDate.add(Calendar.DAY_OF_MONTH, -1);
-                    } else {
-                        mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);
-                    }
-                } else if (picker == mMonthSpinner) {
-                    if (oldVal == 11 && newVal == 0) {
-                        mTempDate.add(Calendar.MONTH, 1);
-                    } else if (oldVal == 0 && newVal == 11) {
-                        mTempDate.add(Calendar.MONTH, -1);
-                    } else {
-                        mTempDate.add(Calendar.MONTH, newVal - oldVal);
-                    }
-                } else if (picker == mYearSpinner) {
-                    mTempDate.set(Calendar.YEAR, newVal);
-                } else {
-                    throw new IllegalArgumentException();
-                }
-                // now set the date to the adjusted one
-                setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH),
-                        mTempDate.get(Calendar.DAY_OF_MONTH));
-                updateSpinners();
-                updateCalendarView();
-                notifyDateChanged();
-            }
-        };
-
-        mSpinners = (LinearLayout) findViewById(R.id.pickers);
-
-        // calendar view day-picker
-        mCalendarView = (CalendarView) findViewById(R.id.calendar_view);
-        mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
-            public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) {
-                setDate(year, month, monthDay);
-                updateSpinners();
-                notifyDateChanged();
-            }
-        });
-
-        // day
-        mDaySpinner = (NumberPicker) findViewById(R.id.day);
-        mDaySpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
-        mDaySpinner.setOnLongPressUpdateInterval(100);
-        mDaySpinner.setOnValueChangedListener(onChangeListener);
-        mDaySpinnerInput = (EditText) mDaySpinner.findViewById(R.id.numberpicker_input);
-
-        // month
-        mMonthSpinner = (NumberPicker) findViewById(R.id.month);
-        mMonthSpinner.setMinValue(0);
-        mMonthSpinner.setMaxValue(mNumberOfMonths - 1);
-        mMonthSpinner.setDisplayedValues(mShortMonths);
-        mMonthSpinner.setOnLongPressUpdateInterval(200);
-        mMonthSpinner.setOnValueChangedListener(onChangeListener);
-        mMonthSpinnerInput = (EditText) mMonthSpinner.findViewById(R.id.numberpicker_input);
-
-        // year
-        mYearSpinner = (NumberPicker) findViewById(R.id.year);
-        mYearSpinner.setOnLongPressUpdateInterval(100);
-        mYearSpinner.setOnValueChangedListener(onChangeListener);
-        mYearSpinnerInput = (EditText) mYearSpinner.findViewById(R.id.numberpicker_input);
-
-        // show only what the user required but make sure we
-        // show something and the spinners have higher priority
-        if (!spinnersShown && !calendarViewShown) {
-            setSpinnersShown(true);
-        } else {
-            setSpinnersShown(spinnersShown);
-            setCalendarViewShown(calendarViewShown);
-        }
-
-        // set the min date giving priority of the minDate over startYear
-        mTempDate.clear();
-        if (!TextUtils.isEmpty(minDate)) {
-            if (!parseDate(minDate, mTempDate)) {
-                mTempDate.set(startYear, 0, 1);
-            }
-        } else {
-            mTempDate.set(startYear, 0, 1);
-        }
-        setMinDate(mTempDate.getTimeInMillis());
-
-        // set the max date giving priority of the maxDate over endYear
-        mTempDate.clear();
-        if (!TextUtils.isEmpty(maxDate)) {
-            if (!parseDate(maxDate, mTempDate)) {
-                mTempDate.set(endYear, 11, 31);
-            }
-        } else {
-            mTempDate.set(endYear, 11, 31);
-        }
-        setMaxDate(mTempDate.getTimeInMillis());
-
-        // initialize to current date
-        mCurrentDate.setTimeInMillis(System.currentTimeMillis());
-        init(mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), mCurrentDate
-                .get(Calendar.DAY_OF_MONTH), null);
-
-        // re-order the number spinners to match the current date format
-        reorderSpinners();
-
-        // accessibility
-        setContentDescriptions();
-
-        // If not explicitly specified this view is important for accessibility.
-        if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
-            setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
-        }
+    public DatePicker(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
-    /**
-     * Gets the minimal date supported by this {@link DatePicker} in
-     * milliseconds since January 1, 1970 00:00:00 in
-     * {@link TimeZone#getDefault()} time zone.
-     * <p>
-     * Note: The default minimal date is 01/01/1900.
-     * <p>
-     *
-     * @return The minimal supported date.
-     */
-    public long getMinDate() {
-        return mCalendarView.getMinDate();
-    }
+    public DatePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
-    /**
-     * Sets the minimal date supported by this {@link NumberPicker} in
-     * milliseconds since January 1, 1970 00:00:00 in
-     * {@link TimeZone#getDefault()} time zone.
-     *
-     * @param minDate The minimal supported date.
-     */
-    public void setMinDate(long minDate) {
-        mTempDate.setTimeInMillis(minDate);
-        if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
-                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
-            return;
-        }
-        mMinDate.setTimeInMillis(minDate);
-        mCalendarView.setMinDate(minDate);
-        if (mCurrentDate.before(mMinDate)) {
-            mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
-            updateCalendarView();
-        }
-        updateSpinners();
-    }
-
-    /**
-     * Gets the maximal date supported by this {@link DatePicker} in
-     * milliseconds since January 1, 1970 00:00:00 in
-     * {@link TimeZone#getDefault()} time zone.
-     * <p>
-     * Note: The default maximal date is 12/31/2100.
-     * <p>
-     *
-     * @return The maximal supported date.
-     */
-    public long getMaxDate() {
-        return mCalendarView.getMaxDate();
-    }
-
-    /**
-     * Sets the maximal date supported by this {@link DatePicker} in
-     * milliseconds since January 1, 1970 00:00:00 in
-     * {@link TimeZone#getDefault()} time zone.
-     *
-     * @param maxDate The maximal supported date.
-     */
-    public void setMaxDate(long maxDate) {
-        mTempDate.setTimeInMillis(maxDate);
-        if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
-                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
-            return;
-        }
-        mMaxDate.setTimeInMillis(maxDate);
-        mCalendarView.setMaxDate(maxDate);
-        if (mCurrentDate.after(mMaxDate)) {
-            mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
-            updateCalendarView();
-        }
-        updateSpinners();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        if (mIsEnabled == enabled) {
-            return;
-        }
-        super.setEnabled(enabled);
-        mDaySpinner.setEnabled(enabled);
-        mMonthSpinner.setEnabled(enabled);
-        mYearSpinner.setEnabled(enabled);
-        mCalendarView.setEnabled(enabled);
-        mIsEnabled = enabled;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return mIsEnabled;
-    }
-
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        onPopulateAccessibilityEvent(event);
-        return true;
-    }
-
-    @Override
-    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
-        super.onPopulateAccessibilityEvent(event);
-
-        final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
-        String selectedDateUtterance = DateUtils.formatDateTime(mContext,
-                mCurrentDate.getTimeInMillis(), flags);
-        event.getText().add(selectedDateUtterance);
-    }
-
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        event.setClassName(DatePicker.class.getName());
-    }
-
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setClassName(DatePicker.class.getName());
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        setCurrentLocale(newConfig.locale);
-    }
-
-    /**
-     * Gets whether the {@link CalendarView} is shown.
-     *
-     * @return True if the calendar view is shown.
-     * @see #getCalendarView()
-     */
-    public boolean getCalendarViewShown() {
-        return (mCalendarView.getVisibility() == View.VISIBLE);
-    }
-
-    /**
-     * Gets the {@link CalendarView}.
-     *
-     * @return The calendar view.
-     * @see #getCalendarViewShown()
-     */
-    public CalendarView getCalendarView () {
-        return mCalendarView;
-    }
-
-    /**
-     * Sets whether the {@link CalendarView} is shown.
-     *
-     * @param shown True if the calendar view is to be shown.
-     */
-    public void setCalendarViewShown(boolean shown) {
-        mCalendarView.setVisibility(shown ? VISIBLE : GONE);
-    }
-
-    /**
-     * Gets whether the spinners are shown.
-     *
-     * @return True if the spinners are shown.
-     */
-    public boolean getSpinnersShown() {
-        return mSpinners.isShown();
-    }
-
-    /**
-     * Sets whether the spinners are shown.
-     *
-     * @param shown True if the spinners are to be shown.
-     */
-    public void setSpinnersShown(boolean shown) {
-        mSpinners.setVisibility(shown ? VISIBLE : GONE);
-    }
-
-    /**
-     * Sets the current locale.
-     *
-     * @param locale The current locale.
-     */
-    private void setCurrentLocale(Locale locale) {
-        if (locale.equals(mCurrentLocale)) {
-            return;
-        }
-
-        mCurrentLocale = locale;
-
-        mTempDate = getCalendarForLocale(mTempDate, locale);
-        mMinDate = getCalendarForLocale(mMinDate, locale);
-        mMaxDate = getCalendarForLocale(mMaxDate, locale);
-        mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
-
-        mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
-        mShortMonths = new DateFormatSymbols().getShortMonths();
-
-        if (usingNumericMonths()) {
-            // We're in a locale where a date should either be all-numeric, or all-text.
-            // All-text would require custom NumberPicker formatters for day and year.
-            mShortMonths = new String[mNumberOfMonths];
-            for (int i = 0; i < mNumberOfMonths; ++i) {
-                mShortMonths[i] = String.format("%d", i + 1);
-            }
-        }
-    }
-
-    /**
-     * Tests whether the current locale is one where there are no real month names,
-     * such as Chinese, Japanese, or Korean locales.
-     */
-    private boolean usingNumericMonths() {
-        return Character.isDigit(mShortMonths[Calendar.JANUARY].charAt(0));
-    }
-
-    /**
-     * Gets a calendar for locale bootstrapped with the value of a given calendar.
-     *
-     * @param oldCalendar The old calendar.
-     * @param locale The locale.
-     */
-    private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
-        if (oldCalendar == null) {
-            return Calendar.getInstance(locale);
-        } else {
-            final long currentTimeMillis = oldCalendar.getTimeInMillis();
-            Calendar newCalendar = Calendar.getInstance(locale);
-            newCalendar.setTimeInMillis(currentTimeMillis);
-            return newCalendar;
-        }
-    }
-
-    /**
-     * Reorders the spinners according to the date format that is
-     * explicitly set by the user and if no such is set fall back
-     * to the current locale's default format.
-     */
-    private void reorderSpinners() {
-        mSpinners.removeAllViews();
-        // We use numeric spinners for year and day, but textual months. Ask icu4c what
-        // order the user's locale uses for that combination. http://b/7207103.
-        String pattern = ICU.getBestDateTimePattern("yyyyMMMdd", Locale.getDefault().toString());
-        char[] order = ICU.getDateFormatOrder(pattern);
-        final int spinnerCount = order.length;
-        for (int i = 0; i < spinnerCount; i++) {
-            switch (order[i]) {
-                case 'd':
-                    mSpinners.addView(mDaySpinner);
-                    setImeOptions(mDaySpinner, spinnerCount, i);
-                    break;
-                case 'M':
-                    mSpinners.addView(mMonthSpinner);
-                    setImeOptions(mMonthSpinner, spinnerCount, i);
-                    break;
-                case 'y':
-                    mSpinners.addView(mYearSpinner);
-                    setImeOptions(mYearSpinner, spinnerCount, i);
-                    break;
-                default:
-                    throw new IllegalArgumentException(Arrays.toString(order));
-            }
-        }
-    }
-
-    /**
-     * Updates the current date.
-     *
-     * @param year The year.
-     * @param month The month which is <strong>starting from zero</strong>.
-     * @param dayOfMonth The day of the month.
-     */
-    public void updateDate(int year, int month, int dayOfMonth) {
-        if (!isNewDate(year, month, dayOfMonth)) {
-            return;
-        }
-        setDate(year, month, dayOfMonth);
-        updateSpinners();
-        updateCalendarView();
-        notifyDateChanged();
-    }
-
-    // Override so we are in complete control of save / restore for this widget.
-    @Override
-    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
-        dispatchThawSelfOnly(container);
-    }
-
-    @Override
-    protected Parcelable onSaveInstanceState() {
-        Parcelable superState = super.onSaveInstanceState();
-        return new SavedState(superState, getYear(), getMonth(), getDayOfMonth());
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Parcelable state) {
-        SavedState ss = (SavedState) state;
-        super.onRestoreInstanceState(ss.getSuperState());
-        setDate(ss.mYear, ss.mMonth, ss.mDay);
-        updateSpinners();
-        updateCalendarView();
+        mDelegate = new LegacyDatePickerDelegate(this, context, attrs, defStyleAttr, defStyleRes);
     }
 
     /**
@@ -599,191 +123,881 @@
      *            user, can be null.
      */
     public void init(int year, int monthOfYear, int dayOfMonth,
-            OnDateChangedListener onDateChangedListener) {
-        setDate(year, monthOfYear, dayOfMonth);
-        updateSpinners();
-        updateCalendarView();
-        mOnDateChangedListener = onDateChangedListener;
+                     OnDateChangedListener onDateChangedListener) {
+        mDelegate.init(year, monthOfYear, dayOfMonth, onDateChangedListener);
     }
 
     /**
-     * Parses the given <code>date</code> and in case of success sets the result
-     * to the <code>outDate</code>.
+     * Updates the current date.
      *
-     * @return True if the date was parsed.
+     * @param year The year.
+     * @param month The month which is <strong>starting from zero</strong>.
+     * @param dayOfMonth The day of the month.
      */
-    private boolean parseDate(String date, Calendar outDate) {
-        try {
-            outDate.setTime(mDateFormat.parse(date));
-            return true;
-        } catch (ParseException e) {
-            Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
-            return false;
-        }
-    }
-
-    private boolean isNewDate(int year, int month, int dayOfMonth) {
-        return (mCurrentDate.get(Calendar.YEAR) != year
-                || mCurrentDate.get(Calendar.MONTH) != dayOfMonth
-                || mCurrentDate.get(Calendar.DAY_OF_MONTH) != month);
-    }
-
-    private void setDate(int year, int month, int dayOfMonth) {
-        mCurrentDate.set(year, month, dayOfMonth);
-        if (mCurrentDate.before(mMinDate)) {
-            mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
-        } else if (mCurrentDate.after(mMaxDate)) {
-            mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
-        }
-    }
-
-    private void updateSpinners() {
-        // set the spinner ranges respecting the min and max dates
-        if (mCurrentDate.equals(mMinDate)) {
-            mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
-            mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
-            mDaySpinner.setWrapSelectorWheel(false);
-            mMonthSpinner.setDisplayedValues(null);
-            mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH));
-            mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH));
-            mMonthSpinner.setWrapSelectorWheel(false);
-        } else if (mCurrentDate.equals(mMaxDate)) {
-            mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH));
-            mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
-            mDaySpinner.setWrapSelectorWheel(false);
-            mMonthSpinner.setDisplayedValues(null);
-            mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH));
-            mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH));
-            mMonthSpinner.setWrapSelectorWheel(false);
-        } else {
-            mDaySpinner.setMinValue(1);
-            mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
-            mDaySpinner.setWrapSelectorWheel(true);
-            mMonthSpinner.setDisplayedValues(null);
-            mMonthSpinner.setMinValue(0);
-            mMonthSpinner.setMaxValue(11);
-            mMonthSpinner.setWrapSelectorWheel(true);
-        }
-
-        // make sure the month names are a zero based array
-        // with the months in the month spinner
-        String[] displayedValues = Arrays.copyOfRange(mShortMonths,
-                mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);
-        mMonthSpinner.setDisplayedValues(displayedValues);
-
-        // year spinner range does not change based on the current date
-        mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
-        mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));
-        mYearSpinner.setWrapSelectorWheel(false);
-
-        // set the spinner values
-        mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
-        mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
-        mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
-
-        if (usingNumericMonths()) {
-            mMonthSpinnerInput.setRawInputType(InputType.TYPE_CLASS_NUMBER);
-        }
-    }
-
-    /**
-     * Updates the calendar view with the current date.
-     */
-    private void updateCalendarView() {
-         mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false);
+    public void updateDate(int year, int month, int dayOfMonth) {
+        mDelegate.updateDate(year, month, dayOfMonth);
     }
 
     /**
      * @return The selected year.
      */
     public int getYear() {
-        return mCurrentDate.get(Calendar.YEAR);
+        return mDelegate.getYear();
     }
 
     /**
      * @return The selected month.
      */
     public int getMonth() {
-        return mCurrentDate.get(Calendar.MONTH);
+        return mDelegate.getMonth();
     }
 
     /**
      * @return The selected day of month.
      */
     public int getDayOfMonth() {
-        return mCurrentDate.get(Calendar.DAY_OF_MONTH);
+        return mDelegate.getDayOfMonth();
     }
 
     /**
-     * Notifies the listener, if such, for a change in the selected date.
-     */
-    private void notifyDateChanged() {
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
-        if (mOnDateChangedListener != null) {
-            mOnDateChangedListener.onDateChanged(this, getYear(), getMonth(), getDayOfMonth());
-        }
-    }
-
-    /**
-     * Sets the IME options for a spinner based on its ordering.
+     * Gets the minimal date supported by this {@link DatePicker} in
+     * milliseconds since January 1, 1970 00:00:00 in
+     * {@link TimeZone#getDefault()} time zone.
+     * <p>
+     * Note: The default minimal date is 01/01/1900.
+     * <p>
      *
-     * @param spinner The spinner.
-     * @param spinnerCount The total spinner count.
-     * @param spinnerIndex The index of the given spinner.
+     * @return The minimal supported date.
      */
-    private void setImeOptions(NumberPicker spinner, int spinnerCount, int spinnerIndex) {
-        final int imeOptions;
-        if (spinnerIndex < spinnerCount - 1) {
-            imeOptions = EditorInfo.IME_ACTION_NEXT;
-        } else {
-            imeOptions = EditorInfo.IME_ACTION_DONE;
+    public long getMinDate() {
+        return mDelegate.getMinDate();
+    }
+
+    /**
+     * Sets the minimal date supported by this {@link NumberPicker} in
+     * milliseconds since January 1, 1970 00:00:00 in
+     * {@link TimeZone#getDefault()} time zone.
+     *
+     * @param minDate The minimal supported date.
+     */
+    public void setMinDate(long minDate) {
+        mDelegate.setMinDate(minDate);
+    }
+
+    /**
+     * Gets the maximal date supported by this {@link DatePicker} in
+     * milliseconds since January 1, 1970 00:00:00 in
+     * {@link TimeZone#getDefault()} time zone.
+     * <p>
+     * Note: The default maximal date is 12/31/2100.
+     * <p>
+     *
+     * @return The maximal supported date.
+     */
+    public long getMaxDate() {
+        return mDelegate.getMaxDate();
+    }
+
+    /**
+     * Sets the maximal date supported by this {@link DatePicker} in
+     * milliseconds since January 1, 1970 00:00:00 in
+     * {@link TimeZone#getDefault()} time zone.
+     *
+     * @param maxDate The maximal supported date.
+     */
+    public void setMaxDate(long maxDate) {
+        mDelegate.setMaxDate(maxDate);
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        if (mDelegate.isEnabled() == enabled) {
+            return;
         }
-        TextView input = (TextView) spinner.findViewById(R.id.numberpicker_input);
-        input.setImeOptions(imeOptions);
+        super.setEnabled(enabled);
+        mDelegate.setEnabled(enabled);
     }
 
-    private void setContentDescriptions() {
-        // Day
-        trySetContentDescription(mDaySpinner, R.id.increment,
-                R.string.date_picker_increment_day_button);
-        trySetContentDescription(mDaySpinner, R.id.decrement,
-                R.string.date_picker_decrement_day_button);
-        // Month
-        trySetContentDescription(mMonthSpinner, R.id.increment,
-                R.string.date_picker_increment_month_button);
-        trySetContentDescription(mMonthSpinner, R.id.decrement,
-                R.string.date_picker_decrement_month_button);
-        // Year
-        trySetContentDescription(mYearSpinner, R.id.increment,
-                R.string.date_picker_increment_year_button);
-        trySetContentDescription(mYearSpinner, R.id.decrement,
-                R.string.date_picker_decrement_year_button);
+    @Override
+    public boolean isEnabled() {
+        return mDelegate.isEnabled();
     }
 
-    private void trySetContentDescription(View root, int viewId, int contDescResId) {
-        View target = root.findViewById(viewId);
-        if (target != null) {
-            target.setContentDescription(mContext.getString(contDescResId));
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        return mDelegate.dispatchPopulateAccessibilityEvent(event);
+    }
+
+    @Override
+    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        super.onPopulateAccessibilityEvent(event);
+        mDelegate.onPopulateAccessibilityEvent(event);
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        mDelegate.onInitializeAccessibilityEvent(event);
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        mDelegate.onInitializeAccessibilityNodeInfo(info);
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mDelegate.onConfigurationChanged(newConfig);
+    }
+
+    /**
+     * Gets whether the {@link CalendarView} is shown.
+     *
+     * @return True if the calendar view is shown.
+     * @see #getCalendarView()
+     */
+    public boolean getCalendarViewShown() {
+        return mDelegate.getCalendarViewShown();
+    }
+
+    /**
+     * Gets the {@link CalendarView}.
+     *
+     * @return The calendar view.
+     * @see #getCalendarViewShown()
+     */
+    public CalendarView getCalendarView () {
+        return mDelegate.getCalendarView();
+    }
+
+    /**
+     * Sets whether the {@link CalendarView} is shown.
+     *
+     * @param shown True if the calendar view is to be shown.
+     */
+    public void setCalendarViewShown(boolean shown) {
+        mDelegate.setCalendarViewShown(shown);
+    }
+
+    /**
+     * Gets whether the spinners are shown.
+     *
+     * @return True if the spinners are shown.
+     */
+    public boolean getSpinnersShown() {
+        return mDelegate.getSpinnersShown();
+    }
+
+    /**
+     * Sets whether the spinners are shown.
+     *
+     * @param shown True if the spinners are to be shown.
+     */
+    public void setSpinnersShown(boolean shown) {
+        mDelegate.setSpinnersShown(shown);
+    }
+
+    // Override so we are in complete control of save / restore for this widget.
+    @Override
+    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+        mDelegate.dispatchRestoreInstanceState(container);
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        Parcelable superState = super.onSaveInstanceState();
+        return mDelegate.onSaveInstanceState(superState);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        mDelegate.onRestoreInstanceState(ss);
+    }
+
+    /**
+     * A delegate interface that defined the public API of the DatePicker. Allows different
+     * DatePicker implementations. This would need to be implemented by the DatePicker delegates
+     * for the real behavior.
+     */
+    interface DatePickerDelegate {
+        void init(int year, int monthOfYear, int dayOfMonth,
+                  OnDateChangedListener onDateChangedListener);
+
+        void updateDate(int year, int month, int dayOfMonth);
+
+        int getYear();
+        int getMonth();
+        int getDayOfMonth();
+
+        void setMinDate(long minDate);
+        long getMinDate();
+
+        void setMaxDate(long maxDate);
+        long getMaxDate();
+
+        void setEnabled(boolean enabled);
+        boolean isEnabled();
+
+        CalendarView getCalendarView ();
+
+        void setCalendarViewShown(boolean shown);
+        boolean getCalendarViewShown();
+
+        void setSpinnersShown(boolean shown);
+        boolean getSpinnersShown();
+
+        void onConfigurationChanged(Configuration newConfig);
+
+        void dispatchRestoreInstanceState(SparseArray<Parcelable> container);
+        Parcelable onSaveInstanceState(Parcelable superState);
+        void onRestoreInstanceState(Parcelable state);
+
+        boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
+        void onPopulateAccessibilityEvent(AccessibilityEvent event);
+        void onInitializeAccessibilityEvent(AccessibilityEvent event);
+        void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
+    }
+
+    /**
+     * An abstract class which can be used as a start for DatePicker implementations
+     */
+    abstract static class AbstractTimePickerDelegate implements DatePickerDelegate {
+        // The delegator
+        protected DatePicker mDelegator;
+
+        // The context
+        protected Context mContext;
+
+        // The current locale
+        protected Locale mCurrentLocale;
+
+        // Callbacks
+        protected  OnDateChangedListener mOnDateChangedListener;
+
+        public AbstractTimePickerDelegate(DatePicker delegator, Context context) {
+            mDelegator = delegator;
+            mContext = context;
+
+            // initialization based on locale
+            setCurrentLocale(Locale.getDefault());
+        }
+
+        protected void setCurrentLocale(Locale locale) {
+            if (locale.equals(mCurrentLocale)) {
+                return;
+            }
+            mCurrentLocale = locale;
         }
     }
 
-    private void updateInputState() {
-        // Make sure that if the user changes the value and the IME is active
-        // for one of the inputs if this widget, the IME is closed. If the user
-        // changed the value via the IME and there is a next input the IME will
-        // be shown, otherwise the user chose another means of changing the
-        // value and having the IME up makes no sense.
-        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
-        if (inputMethodManager != null) {
-            if (inputMethodManager.isActive(mYearSpinnerInput)) {
-                mYearSpinnerInput.clearFocus();
-                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-            } else if (inputMethodManager.isActive(mMonthSpinnerInput)) {
-                mMonthSpinnerInput.clearFocus();
-                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-            } else if (inputMethodManager.isActive(mDaySpinnerInput)) {
-                mDaySpinnerInput.clearFocus();
-                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+    /**
+     * A delegate implementing the basic DatePicker
+     */
+    private static class LegacyDatePickerDelegate extends AbstractTimePickerDelegate {
+
+        private static final String DATE_FORMAT = "MM/dd/yyyy";
+
+        private static final int DEFAULT_START_YEAR = 1900;
+
+        private static final int DEFAULT_END_YEAR = 2100;
+
+        private static final boolean DEFAULT_CALENDAR_VIEW_SHOWN = true;
+
+        private static final boolean DEFAULT_SPINNERS_SHOWN = true;
+
+        private static final boolean DEFAULT_ENABLED_STATE = true;
+
+        private final LinearLayout mSpinners;
+
+        private final NumberPicker mDaySpinner;
+
+        private final NumberPicker mMonthSpinner;
+
+        private final NumberPicker mYearSpinner;
+
+        private final EditText mDaySpinnerInput;
+
+        private final EditText mMonthSpinnerInput;
+
+        private final EditText mYearSpinnerInput;
+
+        private final CalendarView mCalendarView;
+
+        private String[] mShortMonths;
+
+        private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
+
+        private int mNumberOfMonths;
+
+        private Calendar mTempDate;
+
+        private Calendar mMinDate;
+
+        private Calendar mMaxDate;
+
+        private Calendar mCurrentDate;
+
+        private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
+
+        LegacyDatePickerDelegate(DatePicker delegator, Context context, AttributeSet attrs,
+                int defStyleAttr, int defStyleRes) {
+            super(delegator, context);
+
+            mDelegator = delegator;
+            mContext = context;
+
+            // initialization based on locale
+            setCurrentLocale(Locale.getDefault());
+
+            final TypedArray attributesArray = context.obtainStyledAttributes(attrs,
+                    R.styleable.DatePicker, defStyleAttr, defStyleRes);
+            boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown,
+                    DEFAULT_SPINNERS_SHOWN);
+            boolean calendarViewShown = attributesArray.getBoolean(
+                    R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN);
+            int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear,
+                    DEFAULT_START_YEAR);
+            int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
+            String minDate = attributesArray.getString(R.styleable.DatePicker_minDate);
+            String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate);
+            int layoutResourceId = attributesArray.getResourceId(
+                    R.styleable.DatePicker_internalLayout, R.layout.date_picker);
+            attributesArray.recycle();
+
+            LayoutInflater inflater = (LayoutInflater) context
+                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            inflater.inflate(layoutResourceId, mDelegator, true);
+
+            OnValueChangeListener onChangeListener = new OnValueChangeListener() {
+                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+                    updateInputState();
+                    mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
+                    // take care of wrapping of days and months to update greater fields
+                    if (picker == mDaySpinner) {
+                        int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH);
+                        if (oldVal == maxDayOfMonth && newVal == 1) {
+                            mTempDate.add(Calendar.DAY_OF_MONTH, 1);
+                        } else if (oldVal == 1 && newVal == maxDayOfMonth) {
+                            mTempDate.add(Calendar.DAY_OF_MONTH, -1);
+                        } else {
+                            mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);
+                        }
+                    } else if (picker == mMonthSpinner) {
+                        if (oldVal == 11 && newVal == 0) {
+                            mTempDate.add(Calendar.MONTH, 1);
+                        } else if (oldVal == 0 && newVal == 11) {
+                            mTempDate.add(Calendar.MONTH, -1);
+                        } else {
+                            mTempDate.add(Calendar.MONTH, newVal - oldVal);
+                        }
+                    } else if (picker == mYearSpinner) {
+                        mTempDate.set(Calendar.YEAR, newVal);
+                    } else {
+                        throw new IllegalArgumentException();
+                    }
+                    // now set the date to the adjusted one
+                    setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH),
+                            mTempDate.get(Calendar.DAY_OF_MONTH));
+                    updateSpinners();
+                    updateCalendarView();
+                    notifyDateChanged();
+                }
+            };
+
+            mSpinners = (LinearLayout) mDelegator.findViewById(R.id.pickers);
+
+            // calendar view day-picker
+            mCalendarView = (CalendarView) mDelegator.findViewById(R.id.calendar_view);
+            mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
+                public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) {
+                    setDate(year, month, monthDay);
+                    updateSpinners();
+                    notifyDateChanged();
+                }
+            });
+
+            // day
+            mDaySpinner = (NumberPicker) mDelegator.findViewById(R.id.day);
+            mDaySpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
+            mDaySpinner.setOnLongPressUpdateInterval(100);
+            mDaySpinner.setOnValueChangedListener(onChangeListener);
+            mDaySpinnerInput = (EditText) mDaySpinner.findViewById(R.id.numberpicker_input);
+
+            // month
+            mMonthSpinner = (NumberPicker) mDelegator.findViewById(R.id.month);
+            mMonthSpinner.setMinValue(0);
+            mMonthSpinner.setMaxValue(mNumberOfMonths - 1);
+            mMonthSpinner.setDisplayedValues(mShortMonths);
+            mMonthSpinner.setOnLongPressUpdateInterval(200);
+            mMonthSpinner.setOnValueChangedListener(onChangeListener);
+            mMonthSpinnerInput = (EditText) mMonthSpinner.findViewById(R.id.numberpicker_input);
+
+            // year
+            mYearSpinner = (NumberPicker) mDelegator.findViewById(R.id.year);
+            mYearSpinner.setOnLongPressUpdateInterval(100);
+            mYearSpinner.setOnValueChangedListener(onChangeListener);
+            mYearSpinnerInput = (EditText) mYearSpinner.findViewById(R.id.numberpicker_input);
+
+            // show only what the user required but make sure we
+            // show something and the spinners have higher priority
+            if (!spinnersShown && !calendarViewShown) {
+                setSpinnersShown(true);
+            } else {
+                setSpinnersShown(spinnersShown);
+                setCalendarViewShown(calendarViewShown);
+            }
+
+            // set the min date giving priority of the minDate over startYear
+            mTempDate.clear();
+            if (!TextUtils.isEmpty(minDate)) {
+                if (!parseDate(minDate, mTempDate)) {
+                    mTempDate.set(startYear, 0, 1);
+                }
+            } else {
+                mTempDate.set(startYear, 0, 1);
+            }
+            setMinDate(mTempDate.getTimeInMillis());
+
+            // set the max date giving priority of the maxDate over endYear
+            mTempDate.clear();
+            if (!TextUtils.isEmpty(maxDate)) {
+                if (!parseDate(maxDate, mTempDate)) {
+                    mTempDate.set(endYear, 11, 31);
+                }
+            } else {
+                mTempDate.set(endYear, 11, 31);
+            }
+            setMaxDate(mTempDate.getTimeInMillis());
+
+            // initialize to current date
+            mCurrentDate.setTimeInMillis(System.currentTimeMillis());
+            init(mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), mCurrentDate
+                    .get(Calendar.DAY_OF_MONTH), null);
+
+            // re-order the number spinners to match the current date format
+            reorderSpinners();
+
+            // accessibility
+            setContentDescriptions();
+
+            // If not explicitly specified this view is important for accessibility.
+            if (mDelegator.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+                mDelegator.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+            }
+        }
+
+        @Override
+        public void init(int year, int monthOfYear, int dayOfMonth,
+                         OnDateChangedListener onDateChangedListener) {
+            setDate(year, monthOfYear, dayOfMonth);
+            updateSpinners();
+            updateCalendarView();
+            mOnDateChangedListener = onDateChangedListener;
+        }
+
+        @Override
+        public void updateDate(int year, int month, int dayOfMonth) {
+            if (!isNewDate(year, month, dayOfMonth)) {
+                return;
+            }
+            setDate(year, month, dayOfMonth);
+            updateSpinners();
+            updateCalendarView();
+            notifyDateChanged();
+        }
+
+        @Override
+        public int getYear() {
+            return mCurrentDate.get(Calendar.YEAR);
+        }
+
+        @Override
+        public int getMonth() {
+            return mCurrentDate.get(Calendar.MONTH);
+        }
+
+        @Override
+        public int getDayOfMonth() {
+            return mCurrentDate.get(Calendar.DAY_OF_MONTH);
+        }
+
+        @Override
+        public void setMinDate(long minDate) {
+            mTempDate.setTimeInMillis(minDate);
+            if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
+                    && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
+                return;
+            }
+            mMinDate.setTimeInMillis(minDate);
+            mCalendarView.setMinDate(minDate);
+            if (mCurrentDate.before(mMinDate)) {
+                mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
+                updateCalendarView();
+            }
+            updateSpinners();
+        }
+
+        @Override
+        public long getMinDate() {
+            return mCalendarView.getMinDate();
+        }
+
+        @Override
+        public void setMaxDate(long maxDate) {
+            mTempDate.setTimeInMillis(maxDate);
+            if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
+                    && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
+                return;
+            }
+            mMaxDate.setTimeInMillis(maxDate);
+            mCalendarView.setMaxDate(maxDate);
+            if (mCurrentDate.after(mMaxDate)) {
+                mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
+                updateCalendarView();
+            }
+            updateSpinners();
+        }
+
+        @Override
+        public long getMaxDate() {
+            return mCalendarView.getMaxDate();
+        }
+
+        @Override
+        public void setEnabled(boolean enabled) {
+            mDaySpinner.setEnabled(enabled);
+            mMonthSpinner.setEnabled(enabled);
+            mYearSpinner.setEnabled(enabled);
+            mCalendarView.setEnabled(enabled);
+            mIsEnabled = enabled;
+        }
+
+        @Override
+        public boolean isEnabled() {
+            return mIsEnabled;
+        }
+
+        @Override
+        public CalendarView getCalendarView() {
+            return mCalendarView;
+        }
+
+        @Override
+        public void setCalendarViewShown(boolean shown) {
+            mCalendarView.setVisibility(shown ? VISIBLE : GONE);
+        }
+
+        @Override
+        public boolean getCalendarViewShown() {
+            return (mCalendarView.getVisibility() == View.VISIBLE);
+        }
+
+        @Override
+        public void setSpinnersShown(boolean shown) {
+            mSpinners.setVisibility(shown ? VISIBLE : GONE);
+        }
+
+        @Override
+        public boolean getSpinnersShown() {
+            return mSpinners.isShown();
+        }
+
+        @Override
+        public void onConfigurationChanged(Configuration newConfig) {
+            setCurrentLocale(newConfig.locale);
+        }
+
+        @Override
+        public void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+            mDelegator.dispatchThawSelfOnly(container);
+        }
+
+        @Override
+        public Parcelable onSaveInstanceState(Parcelable superState) {
+            return new SavedState(superState, getYear(), getMonth(), getDayOfMonth());
+        }
+
+        @Override
+        public void onRestoreInstanceState(Parcelable state) {
+            SavedState ss = (SavedState) state;
+            setDate(ss.mYear, ss.mMonth, ss.mDay);
+            updateSpinners();
+            updateCalendarView();
+        }
+
+        @Override
+        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+            onPopulateAccessibilityEvent(event);
+            return true;
+        }
+
+        @Override
+        public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+            final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
+            String selectedDateUtterance = DateUtils.formatDateTime(mContext,
+                    mCurrentDate.getTimeInMillis(), flags);
+            event.getText().add(selectedDateUtterance);
+        }
+
+        @Override
+        public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+            event.setClassName(DatePicker.class.getName());
+        }
+
+        @Override
+        public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+            info.setClassName(DatePicker.class.getName());
+        }
+
+        /**
+         * Sets the current locale.
+         *
+         * @param locale The current locale.
+         */
+        @Override
+        protected void setCurrentLocale(Locale locale) {
+            super.setCurrentLocale(locale);
+
+            mTempDate = getCalendarForLocale(mTempDate, locale);
+            mMinDate = getCalendarForLocale(mMinDate, locale);
+            mMaxDate = getCalendarForLocale(mMaxDate, locale);
+            mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
+
+            mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
+            mShortMonths = new DateFormatSymbols().getShortMonths();
+
+            if (usingNumericMonths()) {
+                // We're in a locale where a date should either be all-numeric, or all-text.
+                // All-text would require custom NumberPicker formatters for day and year.
+                mShortMonths = new String[mNumberOfMonths];
+                for (int i = 0; i < mNumberOfMonths; ++i) {
+                    mShortMonths[i] = String.format("%d", i + 1);
+                }
+            }
+        }
+
+        /**
+         * Tests whether the current locale is one where there are no real month names,
+         * such as Chinese, Japanese, or Korean locales.
+         */
+        private boolean usingNumericMonths() {
+            return Character.isDigit(mShortMonths[Calendar.JANUARY].charAt(0));
+        }
+
+        /**
+         * Gets a calendar for locale bootstrapped with the value of a given calendar.
+         *
+         * @param oldCalendar The old calendar.
+         * @param locale The locale.
+         */
+        private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
+            if (oldCalendar == null) {
+                return Calendar.getInstance(locale);
+            } else {
+                final long currentTimeMillis = oldCalendar.getTimeInMillis();
+                Calendar newCalendar = Calendar.getInstance(locale);
+                newCalendar.setTimeInMillis(currentTimeMillis);
+                return newCalendar;
+            }
+        }
+
+        /**
+         * Reorders the spinners according to the date format that is
+         * explicitly set by the user and if no such is set fall back
+         * to the current locale's default format.
+         */
+        private void reorderSpinners() {
+            mSpinners.removeAllViews();
+            // We use numeric spinners for year and day, but textual months. Ask icu4c what
+            // order the user's locale uses for that combination. http://b/7207103.
+            String pattern = ICU.getBestDateTimePattern("yyyyMMMdd",
+                    Locale.getDefault().toString());
+            char[] order = ICU.getDateFormatOrder(pattern);
+            final int spinnerCount = order.length;
+            for (int i = 0; i < spinnerCount; i++) {
+                switch (order[i]) {
+                    case 'd':
+                        mSpinners.addView(mDaySpinner);
+                        setImeOptions(mDaySpinner, spinnerCount, i);
+                        break;
+                    case 'M':
+                        mSpinners.addView(mMonthSpinner);
+                        setImeOptions(mMonthSpinner, spinnerCount, i);
+                        break;
+                    case 'y':
+                        mSpinners.addView(mYearSpinner);
+                        setImeOptions(mYearSpinner, spinnerCount, i);
+                        break;
+                    default:
+                        throw new IllegalArgumentException(Arrays.toString(order));
+                }
+            }
+        }
+
+        /**
+         * Parses the given <code>date</code> and in case of success sets the result
+         * to the <code>outDate</code>.
+         *
+         * @return True if the date was parsed.
+         */
+        private boolean parseDate(String date, Calendar outDate) {
+            try {
+                outDate.setTime(mDateFormat.parse(date));
+                return true;
+            } catch (ParseException e) {
+                Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
+                return false;
+            }
+        }
+
+        private boolean isNewDate(int year, int month, int dayOfMonth) {
+            return (mCurrentDate.get(Calendar.YEAR) != year
+                    || mCurrentDate.get(Calendar.MONTH) != dayOfMonth
+                    || mCurrentDate.get(Calendar.DAY_OF_MONTH) != month);
+        }
+
+        private void setDate(int year, int month, int dayOfMonth) {
+            mCurrentDate.set(year, month, dayOfMonth);
+            if (mCurrentDate.before(mMinDate)) {
+                mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
+            } else if (mCurrentDate.after(mMaxDate)) {
+                mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
+            }
+        }
+
+        private void updateSpinners() {
+            // set the spinner ranges respecting the min and max dates
+            if (mCurrentDate.equals(mMinDate)) {
+                mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
+                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
+                mDaySpinner.setWrapSelectorWheel(false);
+                mMonthSpinner.setDisplayedValues(null);
+                mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH));
+                mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH));
+                mMonthSpinner.setWrapSelectorWheel(false);
+            } else if (mCurrentDate.equals(mMaxDate)) {
+                mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH));
+                mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
+                mDaySpinner.setWrapSelectorWheel(false);
+                mMonthSpinner.setDisplayedValues(null);
+                mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH));
+                mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH));
+                mMonthSpinner.setWrapSelectorWheel(false);
+            } else {
+                mDaySpinner.setMinValue(1);
+                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
+                mDaySpinner.setWrapSelectorWheel(true);
+                mMonthSpinner.setDisplayedValues(null);
+                mMonthSpinner.setMinValue(0);
+                mMonthSpinner.setMaxValue(11);
+                mMonthSpinner.setWrapSelectorWheel(true);
+            }
+
+            // make sure the month names are a zero based array
+            // with the months in the month spinner
+            String[] displayedValues = Arrays.copyOfRange(mShortMonths,
+                    mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);
+            mMonthSpinner.setDisplayedValues(displayedValues);
+
+            // year spinner range does not change based on the current date
+            mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
+            mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));
+            mYearSpinner.setWrapSelectorWheel(false);
+
+            // set the spinner values
+            mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
+            mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
+            mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
+
+            if (usingNumericMonths()) {
+                mMonthSpinnerInput.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+            }
+        }
+
+        /**
+         * Updates the calendar view with the current date.
+         */
+        private void updateCalendarView() {
+            mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false);
+        }
+
+
+        /**
+         * Notifies the listener, if such, for a change in the selected date.
+         */
+        private void notifyDateChanged() {
+            mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+            if (mOnDateChangedListener != null) {
+                mOnDateChangedListener.onDateChanged(mDelegator, getYear(), getMonth(),
+                        getDayOfMonth());
+            }
+        }
+
+        /**
+         * Sets the IME options for a spinner based on its ordering.
+         *
+         * @param spinner The spinner.
+         * @param spinnerCount The total spinner count.
+         * @param spinnerIndex The index of the given spinner.
+         */
+        private void setImeOptions(NumberPicker spinner, int spinnerCount, int spinnerIndex) {
+            final int imeOptions;
+            if (spinnerIndex < spinnerCount - 1) {
+                imeOptions = EditorInfo.IME_ACTION_NEXT;
+            } else {
+                imeOptions = EditorInfo.IME_ACTION_DONE;
+            }
+            TextView input = (TextView) spinner.findViewById(R.id.numberpicker_input);
+            input.setImeOptions(imeOptions);
+        }
+
+        private void setContentDescriptions() {
+            // Day
+            trySetContentDescription(mDaySpinner, R.id.increment,
+                    R.string.date_picker_increment_day_button);
+            trySetContentDescription(mDaySpinner, R.id.decrement,
+                    R.string.date_picker_decrement_day_button);
+            // Month
+            trySetContentDescription(mMonthSpinner, R.id.increment,
+                    R.string.date_picker_increment_month_button);
+            trySetContentDescription(mMonthSpinner, R.id.decrement,
+                    R.string.date_picker_decrement_month_button);
+            // Year
+            trySetContentDescription(mYearSpinner, R.id.increment,
+                    R.string.date_picker_increment_year_button);
+            trySetContentDescription(mYearSpinner, R.id.decrement,
+                    R.string.date_picker_decrement_year_button);
+        }
+
+        private void trySetContentDescription(View root, int viewId, int contDescResId) {
+            View target = root.findViewById(viewId);
+            if (target != null) {
+                target.setContentDescription(mContext.getString(contDescResId));
+            }
+        }
+
+        private void updateInputState() {
+            // Make sure that if the user changes the value and the IME is active
+            // for one of the inputs if this widget, the IME is closed. If the user
+            // changed the value via the IME and there is a next input the IME will
+            // be shown, otherwise the user chose another means of changing the
+            // value and having the IME up makes no sense.
+            InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
+            if (inputMethodManager != null) {
+                if (inputMethodManager.isActive(mYearSpinnerInput)) {
+                    mYearSpinnerInput.clearFocus();
+                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
+                } else if (inputMethodManager.isActive(mMonthSpinnerInput)) {
+                    mMonthSpinnerInput.clearFocus();
+                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
+                } else if (inputMethodManager.isActive(mDaySpinnerInput)) {
+                    mDaySpinnerInput.clearFocus();
+                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
+                }
             }
         }
     }
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index af6bbcb..45d1403 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -27,12 +27,9 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
 import android.widget.TextView;
 import android.widget.RemoteViews.RemoteView;
 
-import com.android.internal.R;
-
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
diff --git a/core/java/android/widget/DialerFilter.java b/core/java/android/widget/DialerFilter.java
index 20bc114..78786e1 100644
--- a/core/java/android/widget/DialerFilter.java
+++ b/core/java/android/widget/DialerFilter.java
@@ -28,8 +28,6 @@
 import android.text.method.KeyListener;
 import android.text.method.TextKeyListener;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.view.KeyCharacterMap;
 import android.view.View;
 import android.graphics.Rect;
 
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index 57e51c2..3a7cc87 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -56,8 +56,12 @@
         this(context, attrs, com.android.internal.R.attr.editTextStyle);
     }
 
-    public EditText(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public EditText(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public EditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 9dab7b4..8ea35ff 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -45,8 +45,6 @@
 import android.inputmethodservice.ExtractEditText;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.text.DynamicLayout;
@@ -1346,7 +1344,7 @@
                 DisplayList blockDisplayList = mTextDisplayLists[blockIndex];
                 if (blockDisplayList == null) {
                     blockDisplayList = mTextDisplayLists[blockIndex] =
-                            mTextView.getHardwareRenderer().createDisplayList("Text " + blockIndex);
+                            DisplayList.create("Text " + blockIndex);
                 } else {
                     if (blockIsInvalid) blockDisplayList.clear();
                 }
@@ -2321,8 +2319,8 @@
         private final HashMap<SuggestionSpan, Integer> mSpansLengths;
 
         private class CustomPopupWindow extends PopupWindow {
-            public CustomPopupWindow(Context context, int defStyle) {
-                super(context, null, defStyle);
+            public CustomPopupWindow(Context context, int defStyleAttr) {
+                super(context, null, defStyleAttr);
             }
 
             @Override
diff --git a/core/java/android/widget/ExpandableListView.java b/core/java/android/widget/ExpandableListView.java
index 7b81aa8..70089e0 100644
--- a/core/java/android/widget/ExpandableListView.java
+++ b/core/java/android/widget/ExpandableListView.java
@@ -227,12 +227,16 @@
         this(context, attrs, com.android.internal.R.attr.expandableListViewStyle);
     }
 
-    public ExpandableListView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ExpandableListView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a =
-            context.obtainStyledAttributes(attrs,
-                    com.android.internal.R.styleable.ExpandableListView, defStyle, 0);
+    public ExpandableListView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.ExpandableListView, defStyleAttr, defStyleRes);
 
         mGroupIndicator = a.getDrawable(
                 com.android.internal.R.styleable.ExpandableListView_groupIndicator);
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 01ac8fd..2d42fa1 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -24,11 +24,11 @@
 import android.animation.PropertyValuesHolder;
 import android.content.Context;
 import android.content.res.ColorStateList;
-import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.os.SystemClock;
 import android.text.TextUtils;
 import android.text.TextUtils.TruncateAt;
 import android.util.IntProperty;
@@ -43,7 +43,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewGroupOverlay;
 import android.widget.AbsListView.OnScrollListener;
-import com.android.internal.R;
+import android.widget.ImageView.ScaleType;
 
 /**
  * Helper class for AbsListView to draw and control the Fast Scroll thumb
@@ -76,24 +76,6 @@
     /** Scroll thumb and preview being dragged by user. */
     private static final int STATE_DRAGGING = 2;
 
-    /** Styleable attributes. */
-    private static final int[] ATTRS = new int[] {
-        android.R.attr.fastScrollTextColor,
-        android.R.attr.fastScrollThumbDrawable,
-        android.R.attr.fastScrollTrackDrawable,
-        android.R.attr.fastScrollPreviewBackgroundLeft,
-        android.R.attr.fastScrollPreviewBackgroundRight,
-        android.R.attr.fastScrollOverlayPosition
-    };
-
-    // Styleable attribute indices.
-    private static final int TEXT_COLOR = 0;
-    private static final int THUMB_DRAWABLE = 1;
-    private static final int TRACK_DRAWABLE = 2;
-    private static final int PREVIEW_BACKGROUND_LEFT = 3;
-    private static final int PREVIEW_BACKGROUND_RIGHT = 4;
-    private static final int OVERLAY_POSITION = 5;
-
     // Positions for preview image and text.
     private static final int OVERLAY_FLOATING = 0;
     private static final int OVERLAY_AT_THUMB = 1;
@@ -115,7 +97,7 @@
     private final TextView mSecondaryText;
     private final ImageView mThumbImage;
     private final ImageView mTrackImage;
-    private final ImageView mPreviewImage;
+    private final View mPreviewImage;
 
     /**
      * Preview image resource IDs for left- and right-aligned layouts. See
@@ -127,13 +109,25 @@
      * Padding in pixels around the preview text. Applied as layout margins to
      * the preview text and padding to the preview image.
      */
-    private final int mPreviewPadding;
+    private int mPreviewPadding;
 
-    /** Whether there is a track image to display. */
-    private final boolean mHasTrackImage;
+    private int mPreviewMinWidth;
+    private int mPreviewMinHeight;
+    private int mThumbMinWidth;
+    private int mThumbMinHeight;
+
+    /** Theme-specified text size. Used only if text appearance is not set. */
+    private float mTextSize;
+
+    /** Theme-specified text color. Used only if text appearance is not set. */
+    private ColorStateList mTextColor;
+
+    private Drawable mThumbDrawable;
+    private Drawable mTrackDrawable;
+    private int mTextAppearance;
 
     /** Total width of decorations. */
-    private final int mWidth;
+    private int mWidth;
 
     /** Set containing decoration transition animations. */
     private AnimatorSet mDecorAnimation;
@@ -208,23 +202,9 @@
     private boolean mMatchDragPosition;
 
     private float mInitialTouchY;
-    private boolean mHasPendingDrag;
+    private long mPendingDrag = -1;
     private int mScaledTouchSlop;
 
-    private final Runnable mDeferStartDrag = new Runnable() {
-        @Override
-        public void run() {
-            if (mList.isAttachedToWindow()) {
-                beginDrag();
-
-                final float pos = getPosFromMotionEvent(mInitialTouchY);
-                scrollTo(pos);
-            }
-
-            mHasPendingDrag = false;
-        }
-    };
-
     /**
      * Used to delay hiding fast scroll decorations.
      */
@@ -245,89 +225,143 @@
         }
     };
 
-    public FastScroller(AbsListView listView) {
+    public FastScroller(AbsListView listView, int styleResId) {
         mList = listView;
-        mOverlay = listView.getOverlay();
 
         final Context context = listView.getContext();
         mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+        mScrollBarStyle = listView.getScrollBarStyle();
 
-        final Resources res = context.getResources();
-        final TypedArray ta = context.getTheme().obtainStyledAttributes(ATTRS);
+        mScrollCompleted = true;
+        mState = STATE_VISIBLE;
+        mMatchDragPosition =
+                context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB;
 
-        final ImageView trackImage = new ImageView(context);
-        mTrackImage = trackImage;
+        mTrackImage = new ImageView(context);
+        mTrackImage.setScaleType(ScaleType.FIT_XY);
+        mThumbImage = new ImageView(context);
+        mThumbImage.setScaleType(ScaleType.FIT_XY);
+        mPreviewImage = new View(context);
+        mPreviewImage.setAlpha(0f);
 
+        mPrimaryText = createPreviewTextView(context);
+        mSecondaryText = createPreviewTextView(context);
+
+        setStyle(styleResId);
+
+        final ViewGroupOverlay overlay = listView.getOverlay();
+        mOverlay = overlay;
+        overlay.add(mTrackImage);
+        overlay.add(mThumbImage);
+        overlay.add(mPreviewImage);
+        overlay.add(mPrimaryText);
+        overlay.add(mSecondaryText);
+
+        getSectionsFromIndexer();
+        updateLongList(listView.getChildCount(), listView.getCount());
+        setScrollbarPosition(listView.getVerticalScrollbarPosition());
+        postAutoHide();
+    }
+
+    private void updateAppearance() {
+        final Context context = mList.getContext();
         int width = 0;
 
         // Add track to overlay if it has an image.
-        final Drawable trackDrawable = ta.getDrawable(TRACK_DRAWABLE);
-        if (trackDrawable != null) {
-            mHasTrackImage = true;
-            trackImage.setBackground(trackDrawable);
-            mOverlay.add(trackImage);
-            width = Math.max(width, trackDrawable.getIntrinsicWidth());
-        } else {
-            mHasTrackImage = false;
+        mTrackImage.setImageDrawable(mTrackDrawable);
+        if (mTrackDrawable != null) {
+            width = Math.max(width, mTrackDrawable.getIntrinsicWidth());
         }
 
-        final ImageView thumbImage = new ImageView(context);
-        mThumbImage = thumbImage;
-
         // Add thumb to overlay if it has an image.
-        final Drawable thumbDrawable = ta.getDrawable(THUMB_DRAWABLE);
-        if (thumbDrawable != null) {
-            thumbImage.setImageDrawable(thumbDrawable);
-            mOverlay.add(thumbImage);
-            width = Math.max(width, thumbDrawable.getIntrinsicWidth());
+        mThumbImage.setImageDrawable(mThumbDrawable);
+        mThumbImage.setMinimumWidth(mThumbMinWidth);
+        mThumbImage.setMinimumHeight(mThumbMinHeight);
+        if (mThumbDrawable != null) {
+            width = Math.max(width, mThumbDrawable.getIntrinsicWidth());
         }
 
-        // If necessary, apply minimum thumb width and height.
-        if (thumbDrawable.getIntrinsicWidth() <= 0 || thumbDrawable.getIntrinsicHeight() <= 0) {
-            final int minWidth = res.getDimensionPixelSize(R.dimen.fastscroll_thumb_width);
-            thumbImage.setMinimumWidth(minWidth);
-            thumbImage.setMinimumHeight(
-                    res.getDimensionPixelSize(R.dimen.fastscroll_thumb_height));
-            width = Math.max(width, minWidth);
+        // Account for minimum thumb width.
+        mWidth = Math.max(width, mThumbMinWidth);
+
+        mPreviewImage.setMinimumWidth(mPreviewMinWidth);
+        mPreviewImage.setMinimumHeight(mPreviewMinHeight);
+
+        if (mTextAppearance != 0) {
+            mPrimaryText.setTextAppearance(context, mTextAppearance);
+            mSecondaryText.setTextAppearance(context, mTextAppearance);
         }
 
-        mWidth = width;
+        if (mTextColor != null) {
+            mPrimaryText.setTextColor(mTextColor);
+            mSecondaryText.setTextColor(mTextColor);
+        }
 
-        final int previewSize = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_size);
-        mPreviewImage = new ImageView(context);
-        mPreviewImage.setMinimumWidth(previewSize);
-        mPreviewImage.setMinimumHeight(previewSize);
-        mPreviewImage.setAlpha(0f);
-        mOverlay.add(mPreviewImage);
+        if (mTextSize > 0) {
+            mPrimaryText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
+            mSecondaryText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
+        }
 
-        mPreviewPadding = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_padding);
-
-        final int textMinSize = Math.max(0, previewSize - mPreviewPadding);
-        mPrimaryText = createPreviewTextView(context, ta);
+        final int textMinSize = Math.max(0, mPreviewMinHeight);
         mPrimaryText.setMinimumWidth(textMinSize);
         mPrimaryText.setMinimumHeight(textMinSize);
-        mOverlay.add(mPrimaryText);
-        mSecondaryText = createPreviewTextView(context, ta);
         mSecondaryText.setMinimumWidth(textMinSize);
         mSecondaryText.setMinimumHeight(textMinSize);
-        mOverlay.add(mSecondaryText);
 
-        mPreviewResId[PREVIEW_LEFT] = ta.getResourceId(PREVIEW_BACKGROUND_LEFT, 0);
-        mPreviewResId[PREVIEW_RIGHT] = ta.getResourceId(PREVIEW_BACKGROUND_RIGHT, 0);
-        mOverlayPosition = ta.getInt(OVERLAY_POSITION, OVERLAY_FLOATING);
-        ta.recycle();
-
-        mScrollBarStyle = listView.getScrollBarStyle();
-        mScrollCompleted = true;
-        mState = STATE_VISIBLE;
-        mMatchDragPosition = context.getApplicationInfo().targetSdkVersion
-                >= Build.VERSION_CODES.HONEYCOMB;
-
-        getSectionsFromIndexer();
         refreshDrawablePressedState();
-        updateLongList(listView.getChildCount(), listView.getCount());
-        setScrollbarPosition(mList.getVerticalScrollbarPosition());
-        postAutoHide();
+    }
+
+    public void setStyle(int resId) {
+        final Context context = mList.getContext();
+        final TypedArray ta = context.obtainStyledAttributes(null,
+                com.android.internal.R.styleable.FastScroll, android.R.attr.fastScrollStyle, resId);
+        final int N = ta.getIndexCount();
+        for (int i = 0; i < N; i++) {
+            final int index = ta.getIndex(i);
+            switch (index) {
+                case com.android.internal.R.styleable.FastScroll_position:
+                    mOverlayPosition = ta.getInt(index, OVERLAY_FLOATING);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_backgroundLeft:
+                    mPreviewResId[PREVIEW_LEFT] = ta.getResourceId(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_backgroundRight:
+                    mPreviewResId[PREVIEW_RIGHT] = ta.getResourceId(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_thumbDrawable:
+                    mThumbDrawable = ta.getDrawable(index);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_trackDrawable:
+                    mTrackDrawable = ta.getDrawable(index);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_textAppearance:
+                    mTextAppearance = ta.getResourceId(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_textColor:
+                    mTextColor = ta.getColorStateList(index);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_textSize:
+                    mTextSize = ta.getDimensionPixelSize(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_minWidth:
+                    mPreviewMinWidth = ta.getDimensionPixelSize(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_minHeight:
+                    mPreviewMinHeight = ta.getDimensionPixelSize(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_thumbMinWidth:
+                    mThumbMinWidth = ta.getDimensionPixelSize(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_thumbMinHeight:
+                    mThumbMinHeight = ta.getDimensionPixelSize(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_padding:
+                    mPreviewPadding = ta.getDimensionPixelSize(index, 0);
+                    break;
+            }
+        }
+
+        updateAppearance();
     }
 
     /**
@@ -469,17 +503,11 @@
     /**
      * Creates a view into which preview text can be placed.
      */
-    private TextView createPreviewTextView(Context context, TypedArray ta) {
+    private TextView createPreviewTextView(Context context) {
         final LayoutParams params = new LayoutParams(
                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
-        final Resources res = context.getResources();
-        final int minSize = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_size);
-        final ColorStateList textColor = ta.getColorStateList(TEXT_COLOR);
-        final float textSize = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_text_size);
         final TextView textView = new TextView(context);
         textView.setLayoutParams(params);
-        textView.setTextColor(textColor);
-        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
         textView.setSingleLine(true);
         textView.setEllipsize(TruncateAt.MIDDLE);
         textView.setGravity(Gravity.CENTER);
@@ -603,7 +631,7 @@
         view.measure(widthMeasureSpec, heightMeasureSpec);
 
         // Align to the left or right.
-        final int width = view.getMeasuredWidth();
+        final int width = Math.min(adjMaxWidth, view.getMeasuredWidth());
         final int left;
         final int right;
         if (mLayoutFromRight) {
@@ -1020,7 +1048,7 @@
         }
 
         final Rect bounds = mTempBounds;
-        final ImageView preview = mPreviewImage;
+        final View preview = mPreviewImage;
         final TextView showing;
         final TextView target;
         if (mShowingPrimary) {
@@ -1046,10 +1074,10 @@
         hideShowing.addListener(mSwitchPrimaryListener);
 
         // Apply preview image padding and animate bounds, if necessary.
-        bounds.left -= mPreviewImage.getPaddingLeft();
-        bounds.top -= mPreviewImage.getPaddingTop();
-        bounds.right += mPreviewImage.getPaddingRight();
-        bounds.bottom += mPreviewImage.getPaddingBottom();
+        bounds.left -= preview.getPaddingLeft();
+        bounds.top -= preview.getPaddingTop();
+        bounds.right += preview.getPaddingRight();
+        bounds.bottom += preview.getPaddingBottom();
         final Animator resizePreview = animateBounds(preview, bounds);
         resizePreview.setDuration(DURATION_RESIZE);
 
@@ -1097,8 +1125,8 @@
         final int top = container.top;
         final int bottom = container.bottom;
 
-        final ImageView trackImage = mTrackImage;
-        final ImageView thumbImage = mThumbImage;
+        final View trackImage = mTrackImage;
+        final View thumbImage = mThumbImage;
         final float min = trackImage.getTop();
         final float max = trackImage.getBottom();
         final float offset = min;
@@ -1109,7 +1137,7 @@
         final float previewPos = mOverlayPosition == OVERLAY_AT_THUMB ? thumbMiddle : 0;
 
         // Center the preview on the thumb, constrained to the list bounds.
-        final ImageView previewImage = mPreviewImage;
+        final View previewImage = mPreviewImage;
         final float previewHalfHeight = previewImage.getHeight() / 2f;
         final float minP = top + previewHalfHeight;
         final float maxP = bottom - previewHalfHeight;
@@ -1122,11 +1150,7 @@
     }
 
     private float getPosFromMotionEvent(float y) {
-        final Rect container = mContainerRect;
-        final int top = container.top;
-        final int bottom = container.bottom;
-
-        final ImageView trackImage = mTrackImage;
+        final View trackImage = mTrackImage;
         final float min = trackImage.getTop();
         final float max = trackImage.getBottom();
         final float offset = min;
@@ -1227,8 +1251,7 @@
      * @see #startPendingDrag()
      */
     private void cancelPendingDrag() {
-        mList.removeCallbacks(mDeferStartDrag);
-        mHasPendingDrag = false;
+        mPendingDrag = -1;
     }
 
     /**
@@ -1236,11 +1259,12 @@
      * scrolling, rather than tapping.
      */
     private void startPendingDrag() {
-        mHasPendingDrag = true;
-        mList.postDelayed(mDeferStartDrag, TAP_TIMEOUT);
+        mPendingDrag = SystemClock.uptimeMillis() + TAP_TIMEOUT;
     }
 
     private void beginDrag() {
+        mPendingDrag = -1;
+
         setState(STATE_DRAGGING);
 
         if (mListAdapter == null && mList != null) {
@@ -1280,6 +1304,13 @@
             case MotionEvent.ACTION_MOVE:
                 if (!isPointInside(ev.getX(), ev.getY())) {
                     cancelPendingDrag();
+                } else if (mPendingDrag >= 0 && mPendingDrag <= SystemClock.uptimeMillis()) {
+                    beginDrag();
+
+                    final float pos = getPosFromMotionEvent(mInitialTouchY);
+                    scrollTo(pos);
+
+                    return onTouchEvent(ev);
                 }
                 break;
             case MotionEvent.ACTION_UP:
@@ -1314,7 +1345,7 @@
 
         switch (me.getActionMasked()) {
             case MotionEvent.ACTION_UP: {
-                if (mHasPendingDrag) {
+                if (mPendingDrag >= 0) {
                     // Allow a tap to scroll.
                     beginDrag();
 
@@ -1322,7 +1353,6 @@
                     setThumbPos(pos);
                     scrollTo(pos);
 
-                    cancelPendingDrag();
                     // Will hit the STATE_DRAGGING check below
                 }
 
@@ -1343,20 +1373,9 @@
             } break;
 
             case MotionEvent.ACTION_MOVE: {
-                if (mHasPendingDrag && Math.abs(me.getY() - mInitialTouchY) > mScaledTouchSlop) {
-                    setState(STATE_DRAGGING);
+                if (mPendingDrag >= 0 && Math.abs(me.getY() - mInitialTouchY) > mScaledTouchSlop) {
+                    beginDrag();
 
-                    if (mListAdapter == null && mList != null) {
-                        getSectionsFromIndexer();
-                    }
-
-                    if (mList != null) {
-                        mList.requestDisallowInterceptTouchEvent(true);
-                        mList.reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
-                    }
-
-                    cancelFling();
-                    cancelPendingDrag();
                     // Will hit the STATE_DRAGGING check below
                 }
 
@@ -1393,7 +1412,7 @@
      * @return Whether the coordinate is inside the scroller's activation area.
      */
     private boolean isPointInside(float x, float y) {
-        return isPointInsideX(x) && (mHasTrackImage || isPointInsideY(y));
+        return isPointInsideX(x) && (mTrackDrawable != null || isPointInsideY(y));
     }
 
     private boolean isPointInsideX(float x) {
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index d9d4ad7..b029328 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -97,11 +97,15 @@
         this(context, attrs, 0);
     }
 
-    public FrameLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public FrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.FrameLayout,
-                    defStyle, 0);
+    public FrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.FrameLayout, defStyleAttr, defStyleRes);
 
         mForegroundGravity = a.getInt(
                 com.android.internal.R.styleable.FrameLayout_foregroundGravity, mForegroundGravity);
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index 78ba6e0..f7c839f 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -196,14 +196,18 @@
         this(context, attrs, R.attr.galleryStyle);
     }
 
-    public Gallery(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public Gallery(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public Gallery(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         
         mGestureDetector = new GestureDetector(context, this);
         mGestureDetector.setIsLongpressEnabled(true);
-        
-        TypedArray a = context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.Gallery, defStyle, 0);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.Gallery, defStyleAttr, defStyleRes);
 
         int index = a.getInt(com.android.internal.R.styleable.Gallery_gravity, -1);
         if (index >= 0) {
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 54cc3f4..8511601 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -35,6 +36,8 @@
 import android.widget.RemoteViews.RemoteView;
 import com.android.internal.R;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -165,6 +168,11 @@
 
     // Public constants
 
+    /** @hide */
+    @IntDef({HORIZONTAL, VERTICAL})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Orientation {}
+
     /**
      * The horizontal orientation.
      */
@@ -186,6 +194,11 @@
      */
     public static final int UNDEFINED = Integer.MIN_VALUE;
 
+    /** @hide */
+    @IntDef({ALIGN_BOUNDS, ALIGN_MARGINS})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AlignmentMode {}
+
     /**
      * This constant is an {@link #setAlignmentMode(int) alignmentMode}.
      * When the {@code alignmentMode} is set to {@link #ALIGN_BOUNDS}, alignment
@@ -262,13 +275,23 @@
 
     // Constructors
 
-    /**
-     * {@inheritDoc}
-     */
-    public GridLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public GridLayout(Context context) {
+        this(context, null);
+    }
+
+    public GridLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public GridLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public GridLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         mDefaultGap = context.getResources().getDimensionPixelOffset(R.dimen.default_gap);
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridLayout);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.GridLayout, defStyleAttr, defStyleRes);
         try {
             setRowCount(a.getInt(ROW_COUNT, DEFAULT_COUNT));
             setColumnCount(a.getInt(COLUMN_COUNT, DEFAULT_COUNT));
@@ -282,21 +305,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    public GridLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public GridLayout(Context context) {
-        //noinspection NullableProblems
-        this(context, null);
-    }
-
     // Implementation
 
     /**
@@ -308,6 +316,7 @@
      *
      * @attr ref android.R.styleable#GridLayout_orientation
      */
+    @Orientation
     public int getOrientation() {
         return mOrientation;
     }
@@ -348,7 +357,7 @@
      *
      * @attr ref android.R.styleable#GridLayout_orientation
      */
-    public void setOrientation(int orientation) {
+    public void setOrientation(@Orientation int orientation) {
         if (this.mOrientation != orientation) {
             this.mOrientation = orientation;
             invalidateStructure();
@@ -479,6 +488,7 @@
      *
      * @attr ref android.R.styleable#GridLayout_alignmentMode
      */
+    @AlignmentMode
     public int getAlignmentMode() {
         return mAlignmentMode;
     }
@@ -498,7 +508,7 @@
      *
      * @attr ref android.R.styleable#GridLayout_alignmentMode
      */
-    public void setAlignmentMode(int alignmentMode) {
+    public void setAlignmentMode(@AlignmentMode int alignmentMode) {
         this.mAlignmentMode = alignmentMode;
         requestLayout();
     }
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 15daf83..acd711d 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -16,12 +16,14 @@
 
 package android.widget;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.os.Trace;
 import android.util.AttributeSet;
+import android.util.MathUtils;
 import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.SoundEffectConstants;
@@ -33,9 +35,11 @@
 import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
 import android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo;
 import android.view.animation.GridLayoutAnimationController;
-import android.widget.AbsListView.LayoutParams;
 import android.widget.RemoteViews.RemoteView;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 
 /**
  * A view that shows items in two-dimensional scrolling grid. The items in the
@@ -53,6 +57,11 @@
  */
 @RemoteView
 public class GridView extends AbsListView {
+    /** @hide */
+    @IntDef({NO_STRETCH, STRETCH_SPACING, STRETCH_COLUMN_WIDTH, STRETCH_SPACING_UNIFORM})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface StretchMode {}
+
     /**
      * Disables stretching.
      * 
@@ -110,11 +119,15 @@
         this(context, attrs, com.android.internal.R.attr.gridViewStyle);
     }
 
-    public GridView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public GridView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.GridView, defStyle, 0);
+    public GridView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.GridView, defStyleAttr, defStyleRes);
 
         int hSpacing = a.getDimensionPixelOffset(
                 com.android.internal.R.styleable.GridView_horizontalSpacing, 0);
@@ -1202,6 +1215,24 @@
 
             setSelectedPositionInt(mNextSelectedPosition);
 
+            // Remember which child, if any, had accessibility focus.
+            final int accessibilityFocusPosition;
+            final View accessFocusedChild = getAccessibilityFocusedChild();
+            if (accessFocusedChild != null) {
+                accessibilityFocusPosition = getPositionForView(accessFocusedChild);
+                accessFocusedChild.setHasTransientState(true);
+            } else {
+                accessibilityFocusPosition = INVALID_POSITION;
+            }
+
+            // Ensure the child containing focus, if any, has transient state.
+            // If the list data hasn't changed, or if the adapter has stable
+            // IDs, this will maintain focus.
+            final View focusedChild = getFocusedChild();
+            if (focusedChild != null) {
+                focusedChild.setHasTransientState(true);
+            }
+
             // Pull all children into the RecycleBin.
             // These views will be reused if possible
             final int firstPosition = mFirstPosition;
@@ -1216,7 +1247,6 @@
             }
 
             // Clear out old views
-            //removeAllViewsInLayout();
             detachAllViewsFromParent();
             recycleBin.removeSkippedScrap();
 
@@ -1287,6 +1317,27 @@
                 mSelectorRect.setEmpty();
             }
 
+            if (accessFocusedChild != null) {
+                accessFocusedChild.setHasTransientState(false);
+
+                // If we failed to maintain accessibility focus on the previous
+                // view, attempt to restore it to the previous position.
+                if (!accessFocusedChild.isAccessibilityFocused()
+                    && accessibilityFocusPosition != INVALID_POSITION) {
+                    // Bound the position within the visible children.
+                    final int position = MathUtils.constrain(
+                            accessibilityFocusPosition - mFirstPosition, 0, getChildCount() - 1);
+                    final View restoreView = getChildAt(position);
+                    if (restoreView != null) {
+                        restoreView.requestAccessibilityFocus();
+                    }
+                }
+            }
+
+            if (focusedChild != null) {
+                focusedChild.setHasTransientState(false);
+            }
+
             mLayoutMode = LAYOUT_NORMAL;
             mDataChanged = false;
             if (mPositionScrollAfterLayout != null) {
@@ -2056,13 +2107,14 @@
      *
      * @attr ref android.R.styleable#GridView_stretchMode
      */
-    public void setStretchMode(int stretchMode) {
+    public void setStretchMode(@StretchMode int stretchMode) {
         if (stretchMode != mStretchMode) {
             mStretchMode = stretchMode;
             requestLayoutIfNecessary();
         }
     }
 
+    @StretchMode
     public int getStretchMode() {
         return mStretchMode;
     }
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index dab0962..25d4f42 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -146,12 +146,17 @@
         this(context, attrs, com.android.internal.R.attr.horizontalScrollViewStyle);
     }
 
-    public HorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public HorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public HorizontalScrollView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initScrollView();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                android.R.styleable.HorizontalScrollView, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, android.R.styleable.HorizontalScrollView, defStyleAttr, defStyleRes);
 
         setFillViewport(a.getBoolean(android.R.styleable.HorizontalScrollView_fillViewport, false));
 
diff --git a/core/java/android/widget/ImageButton.java b/core/java/android/widget/ImageButton.java
index 379354ca..3a20628 100644
--- a/core/java/android/widget/ImageButton.java
+++ b/core/java/android/widget/ImageButton.java
@@ -17,16 +17,11 @@
 package android.widget;
 
 import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
 import android.util.AttributeSet;
-import android.view.MotionEvent;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.RemoteViews.RemoteView;
 
-import java.util.Map;
-
 /**
  * <p>
  * Displays a button with an image (instead of text) that can be pressed 
@@ -83,8 +78,12 @@
         this(context, attrs, com.android.internal.R.attr.imageButtonStyle);
     }
 
-    public ImageButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ImageButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         setFocusable(true);
     }
 
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 7daf798..79d5e5d 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -119,12 +119,17 @@
         this(context, attrs, 0);
     }
 
-    public ImageView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
         initImageView();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.ImageView, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ImageView, defStyleAttr, defStyleRes);
 
         Drawable d = a.getDrawable(com.android.internal.R.styleable.ImageView_src);
         if (d != null) {
diff --git a/core/java/android/widget/LegacyTimePickerDelegate.java b/core/java/android/widget/LegacyTimePickerDelegate.java
new file mode 100644
index 0000000..1634d5f
--- /dev/null
+++ b/core/java/android/widget/LegacyTimePickerDelegate.java
@@ -0,0 +1,638 @@
+/*
+ * 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.widget;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.format.DateFormat;
+import android.text.format.DateUtils;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import com.android.internal.R;
+
+import java.text.DateFormatSymbols;
+import java.util.Calendar;
+import java.util.Locale;
+
+import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
+import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES;
+
+/**
+ * A delegate implementing the basic TimePicker
+ */
+class LegacyTimePickerDelegate extends TimePicker.AbstractTimePickerDelegate {
+
+    private static final boolean DEFAULT_ENABLED_STATE = true;
+
+    private static final int HOURS_IN_HALF_DAY = 12;
+
+    // state
+    private boolean mIs24HourView;
+
+    private boolean mIsAm;
+
+    // ui components
+    private final NumberPicker mHourSpinner;
+
+    private final NumberPicker mMinuteSpinner;
+
+    private final NumberPicker mAmPmSpinner;
+
+    private final EditText mHourSpinnerInput;
+
+    private final EditText mMinuteSpinnerInput;
+
+    private final EditText mAmPmSpinnerInput;
+
+    private final TextView mDivider;
+
+    // Note that the legacy implementation of the TimePicker is
+    // using a button for toggling between AM/PM while the new
+    // version uses a NumberPicker spinner. Therefore the code
+    // accommodates these two cases to be backwards compatible.
+    private final Button mAmPmButton;
+
+    private final String[] mAmPmStrings;
+
+    private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
+
+    private Calendar mTempCalendar;
+
+    private boolean mHourWithTwoDigit;
+    private char mHourFormat;
+
+    /**
+     * A no-op callback used in the constructor to avoid null checks later in
+     * the code.
+     */
+    private static final TimePicker.OnTimeChangedListener NO_OP_CHANGE_LISTENER =
+            new TimePicker.OnTimeChangedListener() {
+                public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
+                }
+            };
+
+    public LegacyTimePickerDelegate(TimePicker delegator, Context context, AttributeSet attrs,
+                                    int defStyleAttr, int defStyleRes) {
+        super(delegator, context);
+
+        // process style attributes
+        final TypedArray attributesArray = mContext.obtainStyledAttributes(
+                attrs, R.styleable.TimePicker, defStyleAttr, defStyleRes);
+        final int layoutResourceId = attributesArray.getResourceId(
+                R.styleable.TimePicker_legacyLayout, R.layout.time_picker_legacy);
+        attributesArray.recycle();
+
+        final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+        inflater.inflate(layoutResourceId, mDelegator, true);
+
+        // hour
+        mHourSpinner = (NumberPicker) delegator.findViewById(R.id.hour);
+        mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
+            public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
+                updateInputState();
+                if (!is24HourView()) {
+                    if ((oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) ||
+                            (oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1)) {
+                        mIsAm = !mIsAm;
+                        updateAmPmControl();
+                    }
+                }
+                onTimeChanged();
+            }
+        });
+        mHourSpinnerInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input);
+        mHourSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
+
+        // divider (only for the new widget style)
+        mDivider = (TextView) mDelegator.findViewById(R.id.divider);
+        if (mDivider != null) {
+            setDividerText();
+        }
+
+        // minute
+        mMinuteSpinner = (NumberPicker) mDelegator.findViewById(R.id.minute);
+        mMinuteSpinner.setMinValue(0);
+        mMinuteSpinner.setMaxValue(59);
+        mMinuteSpinner.setOnLongPressUpdateInterval(100);
+        mMinuteSpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
+        mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
+            public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
+                updateInputState();
+                int minValue = mMinuteSpinner.getMinValue();
+                int maxValue = mMinuteSpinner.getMaxValue();
+                if (oldVal == maxValue && newVal == minValue) {
+                    int newHour = mHourSpinner.getValue() + 1;
+                    if (!is24HourView() && newHour == HOURS_IN_HALF_DAY) {
+                        mIsAm = !mIsAm;
+                        updateAmPmControl();
+                    }
+                    mHourSpinner.setValue(newHour);
+                } else if (oldVal == minValue && newVal == maxValue) {
+                    int newHour = mHourSpinner.getValue() - 1;
+                    if (!is24HourView() && newHour == HOURS_IN_HALF_DAY - 1) {
+                        mIsAm = !mIsAm;
+                        updateAmPmControl();
+                    }
+                    mHourSpinner.setValue(newHour);
+                }
+                onTimeChanged();
+            }
+        });
+        mMinuteSpinnerInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input);
+        mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
+
+            /* Get the localized am/pm strings and use them in the spinner */
+        mAmPmStrings = new DateFormatSymbols().getAmPmStrings();
+
+        // am/pm
+        View amPmView = mDelegator.findViewById(R.id.amPm);
+        if (amPmView instanceof Button) {
+            mAmPmSpinner = null;
+            mAmPmSpinnerInput = null;
+            mAmPmButton = (Button) amPmView;
+            mAmPmButton.setOnClickListener(new View.OnClickListener() {
+                public void onClick(View button) {
+                    button.requestFocus();
+                    mIsAm = !mIsAm;
+                    updateAmPmControl();
+                    onTimeChanged();
+                }
+            });
+        } else {
+            mAmPmButton = null;
+            mAmPmSpinner = (NumberPicker) amPmView;
+            mAmPmSpinner.setMinValue(0);
+            mAmPmSpinner.setMaxValue(1);
+            mAmPmSpinner.setDisplayedValues(mAmPmStrings);
+            mAmPmSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
+                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+                    updateInputState();
+                    picker.requestFocus();
+                    mIsAm = !mIsAm;
+                    updateAmPmControl();
+                    onTimeChanged();
+                }
+            });
+            mAmPmSpinnerInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input);
+            mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
+        }
+
+        if (isAmPmAtStart()) {
+            // Move the am/pm view to the beginning
+            ViewGroup amPmParent = (ViewGroup) delegator.findViewById(R.id.timePickerLayout);
+            amPmParent.removeView(amPmView);
+            amPmParent.addView(amPmView, 0);
+            // Swap layout margins if needed. They may be not symmetrical (Old Standard Theme
+            // for example and not for Holo Theme)
+            ViewGroup.MarginLayoutParams lp =
+                    (ViewGroup.MarginLayoutParams) amPmView.getLayoutParams();
+            final int startMargin = lp.getMarginStart();
+            final int endMargin = lp.getMarginEnd();
+            if (startMargin != endMargin) {
+                lp.setMarginStart(endMargin);
+                lp.setMarginEnd(startMargin);
+            }
+        }
+
+        getHourFormatData();
+
+        // update controls to initial state
+        updateHourControl();
+        updateMinuteControl();
+        updateAmPmControl();
+
+        setOnTimeChangedListener(NO_OP_CHANGE_LISTENER);
+
+        // set to current time
+        setCurrentHour(mTempCalendar.get(Calendar.HOUR_OF_DAY));
+        setCurrentMinute(mTempCalendar.get(Calendar.MINUTE));
+
+        if (!isEnabled()) {
+            setEnabled(false);
+        }
+
+        // set the content descriptions
+        setContentDescriptions();
+
+        // If not explicitly specified this view is important for accessibility.
+        if (mDelegator.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+            mDelegator.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+        }
+    }
+
+    private void getHourFormatData() {
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+                (mIs24HourView) ? "Hm" : "hm");
+        final int lengthPattern = bestDateTimePattern.length();
+        mHourWithTwoDigit = false;
+        char hourFormat = '\0';
+        // Check if the returned pattern is single or double 'H', 'h', 'K', 'k'. We also save
+        // the hour format that we found.
+        for (int i = 0; i < lengthPattern; i++) {
+            final char c = bestDateTimePattern.charAt(i);
+            if (c == 'H' || c == 'h' || c == 'K' || c == 'k') {
+                mHourFormat = c;
+                if (i + 1 < lengthPattern && c == bestDateTimePattern.charAt(i + 1)) {
+                    mHourWithTwoDigit = true;
+                }
+                break;
+            }
+        }
+    }
+
+    private boolean isAmPmAtStart() {
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+                "hm" /* skeleton */);
+
+        return bestDateTimePattern.startsWith("a");
+    }
+
+    /**
+     * The time separator is defined in the Unicode CLDR and cannot be supposed to be ":".
+     *
+     * See http://unicode.org/cldr/trac/browser/trunk/common/main
+     *
+     * We pass the correct "skeleton" depending on 12 or 24 hours view and then extract the
+     * separator as the character which is just after the hour marker in the returned pattern.
+     */
+    private void setDividerText() {
+        final String skeleton = (mIs24HourView) ? "Hm" : "hm";
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+                skeleton);
+        final String separatorText;
+        int hourIndex = bestDateTimePattern.lastIndexOf('H');
+        if (hourIndex == -1) {
+            hourIndex = bestDateTimePattern.lastIndexOf('h');
+        }
+        if (hourIndex == -1) {
+            // Default case
+            separatorText = ":";
+        } else {
+            int minuteIndex = bestDateTimePattern.indexOf('m', hourIndex + 1);
+            if  (minuteIndex == -1) {
+                separatorText = Character.toString(bestDateTimePattern.charAt(hourIndex + 1));
+            } else {
+                separatorText = bestDateTimePattern.substring(hourIndex + 1, minuteIndex);
+            }
+        }
+        mDivider.setText(separatorText);
+    }
+
+    @Override
+    public void setCurrentHour(Integer currentHour) {
+        setCurrentHour(currentHour, true);
+    }
+
+    private void setCurrentHour(Integer currentHour, boolean notifyTimeChanged) {
+        // why was Integer used in the first place?
+        if (currentHour == null || currentHour == getCurrentHour()) {
+            return;
+        }
+        if (!is24HourView()) {
+            // convert [0,23] ordinal to wall clock display
+            if (currentHour >= HOURS_IN_HALF_DAY) {
+                mIsAm = false;
+                if (currentHour > HOURS_IN_HALF_DAY) {
+                    currentHour = currentHour - HOURS_IN_HALF_DAY;
+                }
+            } else {
+                mIsAm = true;
+                if (currentHour == 0) {
+                    currentHour = HOURS_IN_HALF_DAY;
+                }
+            }
+            updateAmPmControl();
+        }
+        mHourSpinner.setValue(currentHour);
+        if (notifyTimeChanged) {
+            onTimeChanged();
+        }
+    }
+
+    @Override
+    public Integer getCurrentHour() {
+        int currentHour = mHourSpinner.getValue();
+        if (is24HourView()) {
+            return currentHour;
+        } else if (mIsAm) {
+            return currentHour % HOURS_IN_HALF_DAY;
+        } else {
+            return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY;
+        }
+    }
+
+    @Override
+    public void setCurrentMinute(Integer currentMinute) {
+        if (currentMinute == getCurrentMinute()) {
+            return;
+        }
+        mMinuteSpinner.setValue(currentMinute);
+        onTimeChanged();
+    }
+
+    @Override
+    public Integer getCurrentMinute() {
+        return mMinuteSpinner.getValue();
+    }
+
+    @Override
+    public void setIs24HourView(Boolean is24HourView) {
+        if (mIs24HourView == is24HourView) {
+            return;
+        }
+        // cache the current hour since spinner range changes and BEFORE changing mIs24HourView!!
+        int currentHour = getCurrentHour();
+        // Order is important here.
+        mIs24HourView = is24HourView;
+        getHourFormatData();
+        updateHourControl();
+        // set value after spinner range is updated
+        setCurrentHour(currentHour, false);
+        updateMinuteControl();
+        updateAmPmControl();
+    }
+
+    @Override
+    public boolean is24HourView() {
+        return mIs24HourView;
+    }
+
+    @Override
+    public void setOnTimeChangedListener(TimePicker.OnTimeChangedListener onTimeChangedListener) {
+        mOnTimeChangedListener = onTimeChangedListener;
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        mMinuteSpinner.setEnabled(enabled);
+        if (mDivider != null) {
+            mDivider.setEnabled(enabled);
+        }
+        mHourSpinner.setEnabled(enabled);
+        if (mAmPmSpinner != null) {
+            mAmPmSpinner.setEnabled(enabled);
+        } else {
+            mAmPmButton.setEnabled(enabled);
+        }
+        mIsEnabled = enabled;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return mIsEnabled;
+    }
+
+    @Override
+    public void setShowDoneButton(boolean showDoneButton) {
+        // Nothing to do
+    }
+
+    @Override
+    public void setDismissCallback(TimePicker.TimePickerDismissCallback callback) {
+        // Nothing to do
+    }
+
+    @Override
+    public int getBaseline() {
+        return mHourSpinner.getBaseline();
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        setCurrentLocale(newConfig.locale);
+    }
+
+    @Override
+    public Parcelable onSaveInstanceState(Parcelable superState) {
+        return new SavedState(superState, getCurrentHour(), getCurrentMinute());
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+        setCurrentHour(ss.getHour());
+        setCurrentMinute(ss.getMinute());
+    }
+
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        onPopulateAccessibilityEvent(event);
+        return true;
+    }
+
+    @Override
+    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        int flags = DateUtils.FORMAT_SHOW_TIME;
+        if (mIs24HourView) {
+            flags |= DateUtils.FORMAT_24HOUR;
+        } else {
+            flags |= DateUtils.FORMAT_12HOUR;
+        }
+        mTempCalendar.set(Calendar.HOUR_OF_DAY, getCurrentHour());
+        mTempCalendar.set(Calendar.MINUTE, getCurrentMinute());
+        String selectedDateUtterance = DateUtils.formatDateTime(mContext,
+                mTempCalendar.getTimeInMillis(), flags);
+        event.getText().add(selectedDateUtterance);
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        event.setClassName(TimePicker.class.getName());
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        info.setClassName(TimePicker.class.getName());
+    }
+
+    private void updateInputState() {
+        // Make sure that if the user changes the value and the IME is active
+        // for one of the inputs if this widget, the IME is closed. If the user
+        // changed the value via the IME and there is a next input the IME will
+        // be shown, otherwise the user chose another means of changing the
+        // value and having the IME up makes no sense.
+        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
+        if (inputMethodManager != null) {
+            if (inputMethodManager.isActive(mHourSpinnerInput)) {
+                mHourSpinnerInput.clearFocus();
+                inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
+            } else if (inputMethodManager.isActive(mMinuteSpinnerInput)) {
+                mMinuteSpinnerInput.clearFocus();
+                inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
+            } else if (inputMethodManager.isActive(mAmPmSpinnerInput)) {
+                mAmPmSpinnerInput.clearFocus();
+                inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
+            }
+        }
+    }
+
+    private void updateAmPmControl() {
+        if (is24HourView()) {
+            if (mAmPmSpinner != null) {
+                mAmPmSpinner.setVisibility(View.GONE);
+            } else {
+                mAmPmButton.setVisibility(View.GONE);
+            }
+        } else {
+            int index = mIsAm ? Calendar.AM : Calendar.PM;
+            if (mAmPmSpinner != null) {
+                mAmPmSpinner.setValue(index);
+                mAmPmSpinner.setVisibility(View.VISIBLE);
+            } else {
+                mAmPmButton.setText(mAmPmStrings[index]);
+                mAmPmButton.setVisibility(View.VISIBLE);
+            }
+        }
+        mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+    }
+
+    /**
+     * Sets the current locale.
+     *
+     * @param locale The current locale.
+     */
+    @Override
+    public void setCurrentLocale(Locale locale) {
+        super.setCurrentLocale(locale);
+        mTempCalendar = Calendar.getInstance(locale);
+    }
+
+    private void onTimeChanged() {
+        mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+        if (mOnTimeChangedListener != null) {
+            mOnTimeChangedListener.onTimeChanged(mDelegator, getCurrentHour(),
+                    getCurrentMinute());
+        }
+    }
+
+    private void updateHourControl() {
+        if (is24HourView()) {
+            // 'k' means 1-24 hour
+            if (mHourFormat == 'k') {
+                mHourSpinner.setMinValue(1);
+                mHourSpinner.setMaxValue(24);
+            } else {
+                mHourSpinner.setMinValue(0);
+                mHourSpinner.setMaxValue(23);
+            }
+        } else {
+            // 'K' means 0-11 hour
+            if (mHourFormat == 'K') {
+                mHourSpinner.setMinValue(0);
+                mHourSpinner.setMaxValue(11);
+            } else {
+                mHourSpinner.setMinValue(1);
+                mHourSpinner.setMaxValue(12);
+            }
+        }
+        mHourSpinner.setFormatter(mHourWithTwoDigit ? NumberPicker.getTwoDigitFormatter() : null);
+    }
+
+    private void updateMinuteControl() {
+        if (is24HourView()) {
+            mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
+        } else {
+            mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
+        }
+    }
+
+    private void setContentDescriptions() {
+        // Minute
+        trySetContentDescription(mMinuteSpinner, R.id.increment,
+                R.string.time_picker_increment_minute_button);
+        trySetContentDescription(mMinuteSpinner, R.id.decrement,
+                R.string.time_picker_decrement_minute_button);
+        // Hour
+        trySetContentDescription(mHourSpinner, R.id.increment,
+                R.string.time_picker_increment_hour_button);
+        trySetContentDescription(mHourSpinner, R.id.decrement,
+                R.string.time_picker_decrement_hour_button);
+        // AM/PM
+        if (mAmPmSpinner != null) {
+            trySetContentDescription(mAmPmSpinner, R.id.increment,
+                    R.string.time_picker_increment_set_pm_button);
+            trySetContentDescription(mAmPmSpinner, R.id.decrement,
+                    R.string.time_picker_decrement_set_am_button);
+        }
+    }
+
+    private void trySetContentDescription(View root, int viewId, int contDescResId) {
+        View target = root.findViewById(viewId);
+        if (target != null) {
+            target.setContentDescription(mContext.getString(contDescResId));
+        }
+    }
+
+    /**
+     * Used to save / restore state of time picker
+     */
+    private static class SavedState extends View.BaseSavedState {
+
+        private final int mHour;
+
+        private final int mMinute;
+
+        private SavedState(Parcelable superState, int hour, int minute) {
+            super(superState);
+            mHour = hour;
+            mMinute = minute;
+        }
+
+        private SavedState(Parcel in) {
+            super(in);
+            mHour = in.readInt();
+            mMinute = in.readInt();
+        }
+
+        public int getHour() {
+            return mHour;
+        }
+
+        public int getMinute() {
+            return mMinute;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeInt(mHour);
+            dest.writeInt(mMinute);
+        }
+
+        @SuppressWarnings({"unused", "hiding"})
+        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+}
+
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index ad60a95..65f1ab7 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.R;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -31,6 +32,9 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.RemoteViews.RemoteView;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 
 /**
  * A Layout that arranges its children in a single column or a single row. The direction of 
@@ -57,9 +61,25 @@
  */
 @RemoteView
 public class LinearLayout extends ViewGroup {
+    /** @hide */
+    @IntDef({HORIZONTAL, VERTICAL})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface OrientationMode {}
+
     public static final int HORIZONTAL = 0;
     public static final int VERTICAL = 1;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                SHOW_DIVIDER_NONE,
+                SHOW_DIVIDER_BEGINNING,
+                SHOW_DIVIDER_MIDDLE,
+                SHOW_DIVIDER_END
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DividerMode {}
+
     /**
      * Don't show any dividers.
      */
@@ -165,18 +185,22 @@
     private int mDividerPadding;
 
     public LinearLayout(Context context) {
-        super(context);
+        this(context, null);
     }
 
     public LinearLayout(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
     
-    public LinearLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public LinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.LinearLayout, defStyle, 0);
+    public LinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.LinearLayout, defStyleAttr, defStyleRes);
 
         int index = a.getInt(com.android.internal.R.styleable.LinearLayout_orientation, -1);
         if (index >= 0) {
@@ -214,7 +238,7 @@
      *                     {@link #SHOW_DIVIDER_MIDDLE}, or {@link #SHOW_DIVIDER_END},
      *                     or {@link #SHOW_DIVIDER_NONE} to show no dividers.
      */
-    public void setShowDividers(int showDividers) {
+    public void setShowDividers(@DividerMode int showDividers) {
         if (showDividers != mShowDividers) {
             requestLayout();
         }
@@ -230,6 +254,7 @@
      * @return A flag set indicating how dividers should be shown around items.
      * @see #setShowDividers(int)
      */
+    @DividerMode
     public int getShowDividers() {
         return mShowDividers;
     }
@@ -1673,12 +1698,12 @@
     
     /**
      * Should the layout be a column or a row.
-     * @param orientation Pass HORIZONTAL or VERTICAL. Default
-     * value is HORIZONTAL.
+     * @param orientation Pass {@link #HORIZONTAL} or {@link #VERTICAL}. Default
+     * value is {@link #HORIZONTAL}.
      * 
      * @attr ref android.R.styleable#LinearLayout_orientation
      */
-    public void setOrientation(int orientation) {
+    public void setOrientation(@OrientationMode int orientation) {
         if (mOrientation != orientation) {
             mOrientation = orientation;
             requestLayout();
@@ -1690,6 +1715,7 @@
      * 
      * @return either {@link #HORIZONTAL} or {@link #VERTICAL}
      */
+    @OrientationMode
     public int getOrientation() {
         return mOrientation;
     }
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 66fe46f..64953f8 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -33,7 +33,6 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.MeasureSpec;
-import android.view.View.OnAttachStateChangeListener;
 import android.view.View.OnTouchListener;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 78237c3..c461723 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -39,7 +39,6 @@
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.ViewParent;
-import android.view.ViewRootImpl;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
@@ -142,11 +141,15 @@
         this(context, attrs, com.android.internal.R.attr.listViewStyle);
     }
 
-    public ListView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ListView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.ListView, defStyle, 0);
+    public ListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ListView, defStyleAttr, defStyleRes);
 
         CharSequence[] entries = a.getTextArray(
                 com.android.internal.R.styleable.ListView_entries);
@@ -263,6 +266,7 @@
         info.data = data;
         info.isSelectable = isSelectable;
         mHeaderViewInfos.add(info);
+        mAreAllItemsSelectable &= isSelectable;
 
         // Wrap the adapter if it wasn't already wrapped.
         if (mAdapter != null) {
@@ -356,6 +360,7 @@
         info.data = data;
         info.isSelectable = isSelectable;
         mFooterViewInfos.add(info);
+        mAreAllItemsSelectable &= isSelectable;
 
         // Wrap the adapter if it wasn't already wrapped.
         if (mAdapter != null) {
@@ -1729,34 +1734,6 @@
     }
 
     /**
-     * @return the direct child that contains accessibility focus, or null if no
-     *         child contains accessibility focus
-     */
-    private View getAccessibilityFocusedChild() {
-        final ViewRootImpl viewRootImpl = getViewRootImpl();
-        if (viewRootImpl == null) {
-            return null;
-        }
-
-        View focusedView = viewRootImpl.getAccessibilityFocusedHost();
-        if (focusedView == null) {
-            return null;
-        }
-
-        ViewParent viewParent = focusedView.getParent();
-        while ((viewParent instanceof View) && (viewParent != this)) {
-            focusedView = (View) viewParent;
-            viewParent = viewParent.getParent();
-        }
-
-        if (!(viewParent instanceof View)) {
-            return null;
-        }
-
-        return focusedView;
-    }
-
-    /**
      * Obtain the view and add it to our list of children. The view can be made
      * fresh, converted from an unused view, or used as is if it was in the
      * recycle bin.
@@ -3266,14 +3243,13 @@
                         if (drawDividers && (bottom < listBottom)
                                 && !(drawOverscrollFooter && isLastItem)) {
                             final int nextIndex = (itemIndex + 1);
-                            // Draw dividers between enabled items, headers and/or
-                            // footers when enabled, and the end of the list.
-                            if (areAllItemsSelectable || ((adapter.isEnabled(itemIndex)
-                                    || (headerDividers && isHeader)
-                                    || (footerDividers && isFooter)) && (isLastItem
-                                    || adapter.isEnabled(nextIndex)
-                                    || (headerDividers && (nextIndex < headerCount))
-                                    || (footerDividers && (nextIndex >= footerLimit))))) {
+                            // Draw dividers between enabled items, headers
+                            // and/or footers when enabled and requested, and
+                            // after the last enabled item.
+                            if (adapter.isEnabled(itemIndex) && (headerDividers || !isHeader
+                                    && (nextIndex >= headerCount)) && (isLastItem
+                                    || adapter.isEnabled(nextIndex) && (footerDividers || !isFooter
+                                            && (nextIndex < footerLimit)))) {
                                 bounds.top = bottom;
                                 bounds.bottom = bottom + dividerHeight;
                                 drawDivider(canvas, bounds, i);
@@ -3315,14 +3291,13 @@
                         if (drawDividers && (top > effectivePaddingTop)) {
                             final boolean isFirstItem = (i == start);
                             final int previousIndex = (itemIndex - 1);
-                            // Draw dividers between enabled items, headers and/or
-                            // footers when enabled, and the end of the list.
-                            if (areAllItemsSelectable || ((adapter.isEnabled(itemIndex)
-                                    || (headerDividers && isHeader)
-                                    || (footerDividers && isFooter)) && (isFirstItem
-                                    || adapter.isEnabled(previousIndex)
-                                    || (headerDividers && (previousIndex < headerCount))
-                                    || (footerDividers && (previousIndex >= footerLimit))))) {
+                            // Draw dividers between enabled items, headers
+                            // and/or footers when enabled and requested, and
+                            // before the first enabled item.
+                            if (adapter.isEnabled(itemIndex) && (headerDividers || !isHeader
+                                    && (previousIndex >= headerCount)) && (isFirstItem ||
+                                    adapter.isEnabled(previousIndex) && (footerDividers || !isFooter
+                                            && (previousIndex < footerLimit)))) {
                                 bounds.top = top - dividerHeight;
                                 bounds.bottom = top;
                                 // Give the method the child ABOVE the divider,
diff --git a/core/java/android/widget/MultiAutoCompleteTextView.java b/core/java/android/widget/MultiAutoCompleteTextView.java
index 0b30c84..cbd01b0 100644
--- a/core/java/android/widget/MultiAutoCompleteTextView.java
+++ b/core/java/android/widget/MultiAutoCompleteTextView.java
@@ -67,8 +67,13 @@
         this(context, attrs, com.android.internal.R.attr.autoCompleteTextViewStyle);
     }
 
-    public MultiAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public MultiAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public MultiAutoCompleteTextView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     /* package */ void finishInit() { }
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index c0fde2e..44c4987 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.annotation.IntDef;
 import android.annotation.Widget;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -53,6 +54,8 @@
 import com.android.internal.R;
 import libcore.icu.LocaleData;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -493,6 +496,10 @@
      * Interface to listen for the picker scroll state.
      */
     public interface OnScrollListener {
+        /** @hide */
+        @IntDef({SCROLL_STATE_IDLE, SCROLL_STATE_TOUCH_SCROLL, SCROLL_STATE_FLING})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface ScrollState {}
 
         /**
          * The view is not scrolling.
@@ -518,7 +525,7 @@
          *            {@link #SCROLL_STATE_TOUCH_SCROLL} or
          *            {@link #SCROLL_STATE_IDLE}.
          */
-        public void onScrollStateChange(NumberPicker view, int scrollState);
+        public void onScrollStateChange(NumberPicker view, @ScrollState int scrollState);
     }
 
     /**
@@ -559,14 +566,33 @@
      *
      * @param context the application environment.
      * @param attrs a collection of attributes.
-     * @param defStyle The default style to apply to this view.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public NumberPicker(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public NumberPicker(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * Create a new number picker
+     *
+     * @param context the application environment.
+     * @param attrs a collection of attributes.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     */
+    public NumberPicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         // process style attributes
-        TypedArray attributesArray = context.obtainStyledAttributes(
-                attrs, R.styleable.NumberPicker, defStyle, 0);
+        final TypedArray attributesArray = context.obtainStyledAttributes(
+                attrs, R.styleable.NumberPicker, defStyleAttr, defStyleRes);
         final int layoutResId = attributesArray.getResourceId(
                 R.styleable.NumberPicker_internalLayout, DEFAULT_LAYOUT_RESOURCE_ID);
 
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index f218199..7b3dd31 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -70,7 +70,11 @@
      * @hide
      */
     public OverScroller(Context context, Interpolator interpolator, boolean flywheel) {
-        mInterpolator = interpolator;
+        if (interpolator == null) {
+            mInterpolator = new Scroller.ViscousFluidInterpolator();
+        } else {
+            mInterpolator = interpolator;
+        }
         mFlywheel = flywheel;
         mScrollerX = new SplineOverScroller(context);
         mScrollerY = new SplineOverScroller(context);
@@ -112,7 +116,11 @@
     }
 
     void setInterpolator(Interpolator interpolator) {
-        mInterpolator = interpolator;
+        if (interpolator == null) {
+            mInterpolator = new Scroller.ViscousFluidInterpolator();
+        } else {
+            mInterpolator = interpolator;
+        }
     }
 
     /**
@@ -302,14 +310,7 @@
 
                 final int duration = mScrollerX.mDuration;
                 if (elapsedTime < duration) {
-                    float q = (float) (elapsedTime) / duration;
-
-                    if (mInterpolator == null) {
-                        q = Scroller.viscousFluid(q);
-                    } else {
-                        q = mInterpolator.getInterpolation(q);
-                    }
-
+                    final float q = mInterpolator.getInterpolation(elapsedTime / (float) duration);
                     mScrollerX.updateScroll(q);
                     mScrollerY.updateScroll(q);
                 } else {
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 5663959..e77a810 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -170,8 +170,8 @@
      *
      * <p>The popup does provide a background.</p>
      */
-    public PopupWindow(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, 0);
+    public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
     
     /**
@@ -183,8 +183,7 @@
         mContext = context;
         mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
 
-        TypedArray a =
-            context.obtainStyledAttributes(
+        final TypedArray a = context.obtainStyledAttributes(
                 attrs, com.android.internal.R.styleable.PopupWindow, defStyleAttr, defStyleRes);
 
         mBackground = a.getDrawable(R.styleable.PopupWindow_popupBackground);
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 5392a96..1fbcbcf 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -242,29 +242,26 @@
         this(context, attrs, com.android.internal.R.attr.progressBarStyle);
     }
 
-    public ProgressBar(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, 0);
+    public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
-    /**
-     * @hide
-     */
-    public ProgressBar(Context context, AttributeSet attrs, int defStyle, int styleRes) {
-        super(context, attrs, defStyle);
+    public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
         mUiThreadId = Thread.currentThread().getId();
         initProgressBar();
 
-        TypedArray a =
-            context.obtainStyledAttributes(attrs, R.styleable.ProgressBar, defStyle, styleRes);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.ProgressBar, defStyleAttr, defStyleRes);
         
         mNoInvalidate = true;
         
         Drawable drawable = a.getDrawable(R.styleable.ProgressBar_progressDrawable);
         if (drawable != null) {
-            drawable = tileify(drawable, false);
             // Calling this method can set mMaxHeight, make sure the corresponding
             // XML attribute for mMaxHeight is read after calling this method
-            setProgressDrawable(drawable);
+            setProgressDrawableTiled(drawable);
         }
 
 
@@ -293,8 +290,7 @@
 
         drawable = a.getDrawable(R.styleable.ProgressBar_indeterminateDrawable);
         if (drawable != null) {
-            drawable = tileifyIndeterminate(drawable);
-            setIndeterminateDrawable(drawable);
+            setIndeterminateDrawableTiled(drawable);
         }
 
         mOnlyIndeterminate = a.getBoolean(
@@ -467,11 +463,9 @@
     }
 
     /**
-     * <p>Define the drawable used to draw the progress bar in
-     * indeterminate mode.</p>
+     * Define the drawable used to draw the progress bar in indeterminate mode.
      *
      * @param d the new drawable
-     *
      * @see #getIndeterminateDrawable()
      * @see #setIndeterminate(boolean)
      */
@@ -488,6 +482,25 @@
             postInvalidate();
         }
     }
+
+    /**
+     * Define the tileable drawable used to draw the progress bar in
+     * indeterminate mode.
+     * <p>
+     * If the drawable is a BitmapDrawable or contains BitmapDrawables, a
+     * tiled copy will be generated for display as a progress bar.
+     *
+     * @param d the new drawable
+     * @see #getIndeterminateDrawable()
+     * @see #setIndeterminate(boolean)
+     */
+    public void setIndeterminateDrawableTiled(Drawable d) {
+        if (d != null) {
+            d = tileifyIndeterminate(d);
+        }
+
+        setIndeterminateDrawable(d);
+    }
     
     /**
      * <p>Get the drawable used to draw the progress bar in
@@ -503,11 +516,9 @@
     }
 
     /**
-     * <p>Define the drawable used to draw the progress bar in
-     * progress mode.</p>
+     * Define the drawable used to draw the progress bar in progress mode.
      *
      * @param d the new drawable
-     *
      * @see #getProgressDrawable()
      * @see #setIndeterminate(boolean)
      */
@@ -546,6 +557,25 @@
             doRefreshProgress(R.id.secondaryProgress, mSecondaryProgress, false, false);
         }
     }
+
+    /**
+     * Define the tileable drawable used to draw the progress bar in
+     * progress mode.
+     * <p>
+     * If the drawable is a BitmapDrawable or contains BitmapDrawables, a
+     * tiled copy will be generated for display as a progress bar.
+     *
+     * @param d the new drawable
+     * @see #getProgressDrawable()
+     * @see #setIndeterminate(boolean)
+     */
+    public void setProgressDrawableTiled(Drawable d) {
+        if (d != null) {
+            d = tileify(d, false);
+        }
+
+        setProgressDrawable(d);
+    }
     
     /**
      * @return The drawable currently used to draw the progress bar
diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java
index fd2f754..a4f758c 100644
--- a/core/java/android/widget/QuickContactBadge.java
+++ b/core/java/android/widget/QuickContactBadge.java
@@ -84,8 +84,13 @@
         this(context, attrs, 0);
     }
 
-    public QuickContactBadge(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public QuickContactBadge(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public QuickContactBadge(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         TypedArray styledAttributes = mContext.obtainStyledAttributes(R.styleable.Theme);
         mOverlay = styledAttributes.getDrawable(
diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
new file mode 100644
index 0000000..1c9ab61
--- /dev/null
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -0,0 +1,1396 @@
+/*
+ * 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.widget;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.Keyframe;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Typeface;
+import android.graphics.RectF;
+import android.os.Bundle;
+import android.text.format.DateUtils;
+import android.text.format.Time;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.HapticFeedbackConstants;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import com.android.internal.R;
+
+import java.text.DateFormatSymbols;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Locale;
+
+/**
+ * View to show a clock circle picker (with one or two picking circles)
+ *
+ * @hide
+ */
+public class RadialTimePickerView extends View implements View.OnTouchListener {
+    private static final String TAG = "ClockView";
+
+    private static final boolean DEBUG = false;
+
+    private static final int DEBUG_COLOR = 0x20FF0000;
+    private static final int DEBUG_TEXT_COLOR = 0x60FF0000;
+    private static final int DEBUG_STROKE_WIDTH = 2;
+
+    private static final int HOURS = 0;
+    private static final int MINUTES = 1;
+    private static final int HOURS_INNER = 2;
+    private static final int AMPM = 3;
+
+    private static final int SELECTOR_CIRCLE = 0;
+    private static final int SELECTOR_DOT = 1;
+    private static final int SELECTOR_LINE = 2;
+
+    private static final int AM = 0;
+    private static final int PM = 1;
+
+    // Opaque alpha level
+    private static final int ALPHA_OPAQUE = 255;
+
+    // Transparent alpha level
+    private static final int ALPHA_TRANSPARENT = 0;
+
+    // Alpha level of color for selector.
+    private static final int ALPHA_SELECTOR = 51;
+
+    // Alpha level of color for selected circle.
+    private static final int ALPHA_AMPM_SELECTED = ALPHA_SELECTOR;
+
+    // Alpha level of color for pressed circle.
+    private static final int ALPHA_AMPM_PRESSED = 175;
+
+    private static final float COSINE_30_DEGREES = ((float) Math.sqrt(3)) * 0.5f;
+    private static final float SINE_30_DEGREES = 0.5f;
+
+    private static final int DEGREES_FOR_ONE_HOUR = 30;
+    private static final int DEGREES_FOR_ONE_MINUTE = 6;
+
+    private static final int[] HOURS_NUMBERS = {12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+    private static final int[] HOURS_NUMBERS_24 = {0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
+    private static final int[] MINUTES_NUMBERS = {0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55};
+
+    private static final int CENTER_RADIUS = 2;
+
+    private static int[] sSnapPrefer30sMap = new int[361];
+
+    private final String[] mHours12Texts = new String[12];
+    private final String[] mOuterHours24Texts = new String[12];
+    private final String[] mInnerHours24Texts = new String[12];
+    private final String[] mMinutesTexts = new String[12];
+
+    private final String[] mAmPmText = new String[2];
+
+    private final Paint[] mPaint = new Paint[2];
+    private final Paint mPaintCenter = new Paint();
+    private final Paint[][] mPaintSelector = new Paint[2][3];
+    private final Paint mPaintAmPmText = new Paint();
+    private final Paint[] mPaintAmPmCircle = new Paint[2];
+
+    private final Paint mPaintBackground = new Paint();
+    private final Paint mPaintDisabled = new Paint();
+    private final Paint mPaintDebug = new Paint();
+
+    private Typeface mTypeface;
+
+    private boolean mIs24HourMode;
+    private boolean mShowHours;
+    private boolean mIsOnInnerCircle;
+
+    private int mXCenter;
+    private int mYCenter;
+
+    private float[] mCircleRadius = new float[3];
+
+    private int mMinHypotenuseForInnerNumber;
+    private int mMaxHypotenuseForOuterNumber;
+    private int mHalfwayHypotenusePoint;
+
+    private float[] mTextSize = new float[2];
+    private float mInnerTextSize;
+
+    private float[][] mTextGridHeights = new float[2][7];
+    private float[][] mTextGridWidths = new float[2][7];
+
+    private float[] mInnerTextGridHeights = new float[7];
+    private float[] mInnerTextGridWidths = new float[7];
+
+    private String[] mOuterTextHours;
+    private String[] mInnerTextHours;
+    private String[] mOuterTextMinutes;
+
+    private float[] mCircleRadiusMultiplier = new float[2];
+    private float[] mNumbersRadiusMultiplier = new float[3];
+
+    private float[] mTextSizeMultiplier = new float[3];
+
+    private float[] mAnimationRadiusMultiplier = new float[3];
+
+    private float mTransitionMidRadiusMultiplier;
+    private float mTransitionEndRadiusMultiplier;
+
+    private AnimatorSet mTransition;
+    private InvalidateUpdateListener mInvalidateUpdateListener = new InvalidateUpdateListener();
+
+    private int[] mLineLength = new int[3];
+    private int[] mSelectionRadius = new int[3];
+    private float mSelectionRadiusMultiplier;
+    private int[] mSelectionDegrees = new int[3];
+
+    private int mAmPmCircleRadius;
+    private float mAmPmYCenter;
+
+    private float mAmPmCircleRadiusMultiplier;
+    private int mAmPmTextColor;
+
+    private float mLeftIndicatorXCenter;
+    private float mRightIndicatorXCenter;
+
+    private int mAmPmUnselectedColor;
+    private int mAmPmSelectedColor;
+
+    private int mAmOrPm;
+    private int mAmOrPmPressed;
+
+    private RectF mRectF = new RectF();
+    private boolean mInputEnabled = true;
+    private OnValueSelectedListener mListener;
+
+    private final ArrayList<Animator> mHoursToMinutesAnims = new ArrayList<Animator>();
+    private final ArrayList<Animator> mMinuteToHoursAnims = new ArrayList<Animator>();
+
+    public interface OnValueSelectedListener {
+        void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance);
+    }
+
+    static {
+        // Prepare mapping to snap touchable degrees to selectable degrees.
+        preparePrefer30sMap();
+    }
+
+    /**
+     * Split up the 360 degrees of the circle among the 60 selectable values. Assigns a larger
+     * selectable area to each of the 12 visible values, such that the ratio of space apportioned
+     * to a visible value : space apportioned to a non-visible value will be 14 : 4.
+     * E.g. the output of 30 degrees should have a higher range of input associated with it than
+     * the output of 24 degrees, because 30 degrees corresponds to a visible number on the clock
+     * circle (5 on the minutes, 1 or 13 on the hours).
+     */
+    private static void preparePrefer30sMap() {
+        // We'll split up the visible output and the non-visible output such that each visible
+        // output will correspond to a range of 14 associated input degrees, and each non-visible
+        // output will correspond to a range of 4 associate input degrees, so visible numbers
+        // are more than 3 times easier to get than non-visible numbers:
+        // {354-359,0-7}:0, {8-11}:6, {12-15}:12, {16-19}:18, {20-23}:24, {24-37}:30, etc.
+        //
+        // If an output of 30 degrees should correspond to a range of 14 associated degrees, then
+        // we'll need any input between 24 - 37 to snap to 30. Working out from there, 20-23 should
+        // snap to 24, while 38-41 should snap to 36. This is somewhat counter-intuitive, that you
+        // can be touching 36 degrees but have the selection snapped to 30 degrees; however, this
+        // inconsistency isn't noticeable at such fine-grained degrees, and it affords us the
+        // ability to aggressively prefer the visible values by a factor of more than 3:1, which
+        // greatly contributes to the selectability of these values.
+
+        // The first output is 0, and each following output will increment by 6 {0, 6, 12, ...}.
+        int snappedOutputDegrees = 0;
+        // Count of how many inputs we've designated to the specified output.
+        int count = 1;
+        // How many input we expect for a specified output. This will be 14 for output divisible
+        // by 30, and 4 for the remaining output. We'll special case the outputs of 0 and 360, so
+        // the caller can decide which they need.
+        int expectedCount = 8;
+        // Iterate through the input.
+        for (int degrees = 0; degrees < 361; degrees++) {
+            // Save the input-output mapping.
+            sSnapPrefer30sMap[degrees] = snappedOutputDegrees;
+            // If this is the last input for the specified output, calculate the next output and
+            // the next expected count.
+            if (count == expectedCount) {
+                snappedOutputDegrees += 6;
+                if (snappedOutputDegrees == 360) {
+                    expectedCount = 7;
+                } else if (snappedOutputDegrees % 30 == 0) {
+                    expectedCount = 14;
+                } else {
+                    expectedCount = 4;
+                }
+                count = 1;
+            } else {
+                count++;
+            }
+        }
+    }
+
+    /**
+     * Returns mapping of any input degrees (0 to 360) to one of 60 selectable output degrees,
+     * where the degrees corresponding to visible numbers (i.e. those divisible by 30) will be
+     * weighted heavier than the degrees corresponding to non-visible numbers.
+     * See {@link #preparePrefer30sMap()} documentation for the rationale and generation of the
+     * mapping.
+     */
+    private static int snapPrefer30s(int degrees) {
+        if (sSnapPrefer30sMap == null) {
+            return -1;
+        }
+        return sSnapPrefer30sMap[degrees];
+    }
+
+    /**
+     * Returns mapping of any input degrees (0 to 360) to one of 12 visible output degrees (all
+     * multiples of 30), where the input will be "snapped" to the closest visible degrees.
+     * @param degrees The input degrees
+     * @param forceHigherOrLower The output may be forced to either the higher or lower step, or may
+     * be allowed to snap to whichever is closer. Use 1 to force strictly higher, -1 to force
+     * strictly lower, and 0 to snap to the closer one.
+     * @return output degrees, will be a multiple of 30
+     */
+    private static int snapOnly30s(int degrees, int forceHigherOrLower) {
+        final int stepSize = DEGREES_FOR_ONE_HOUR;
+        int floor = (degrees / stepSize) * stepSize;
+        final int ceiling = floor + stepSize;
+        if (forceHigherOrLower == 1) {
+            degrees = ceiling;
+        } else if (forceHigherOrLower == -1) {
+            if (degrees == floor) {
+                floor -= stepSize;
+            }
+            degrees = floor;
+        } else {
+            if ((degrees - floor) < (ceiling - degrees)) {
+                degrees = floor;
+            } else {
+                degrees = ceiling;
+            }
+        }
+        return degrees;
+    }
+
+    public RadialTimePickerView(Context context, AttributeSet attrs)  {
+        this(context, attrs, R.attr.timePickerStyle);
+    }
+
+    public RadialTimePickerView(Context context, AttributeSet attrs, int defStyle)  {
+        super(context, attrs);
+
+        // process style attributes
+        final TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.TimePicker,
+                defStyle, 0);
+
+        final Resources res = getResources();
+
+        mAmPmUnselectedColor = a.getColor(R.styleable.TimePicker_amPmUnselectedBackgroundColor,
+                res.getColor(
+                        R.color.timepicker_default_ampm_unselected_background_color_holo_light));
+
+        mAmPmSelectedColor = a.getColor(R.styleable.TimePicker_amPmSelectedBackgroundColor,
+                res.getColor(R.color.timepicker_default_ampm_selected_background_color_holo_light));
+
+        mAmPmTextColor = a.getColor(R.styleable.TimePicker_amPmTextColor,
+                res.getColor(R.color.timepicker_default_text_color_holo_light));
+
+        final int numbersTextColor = a.getColor(R.styleable.TimePicker_numbersTextColor,
+                res.getColor(R.color.timepicker_default_text_color_holo_light));
+
+        mTypeface = Typeface.create("sans-serif", Typeface.NORMAL);
+
+        mPaint[HOURS] = new Paint();
+        mPaint[HOURS].setColor(numbersTextColor);
+        mPaint[HOURS].setAntiAlias(true);
+        mPaint[HOURS].setTextAlign(Paint.Align.CENTER);
+
+        mPaint[MINUTES] = new Paint();
+        mPaint[MINUTES].setColor(numbersTextColor);
+        mPaint[MINUTES].setAntiAlias(true);
+        mPaint[MINUTES].setTextAlign(Paint.Align.CENTER);
+
+        mPaintCenter.setColor(numbersTextColor);
+        mPaintCenter.setAntiAlias(true);
+        mPaintCenter.setTextAlign(Paint.Align.CENTER);
+
+        mPaintSelector[HOURS][SELECTOR_CIRCLE] = new Paint();
+        mPaintSelector[HOURS][SELECTOR_CIRCLE].setColor(
+                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
+        mPaintSelector[HOURS][SELECTOR_CIRCLE].setAntiAlias(true);
+
+        mPaintSelector[HOURS][SELECTOR_DOT] = new Paint();
+        mPaintSelector[HOURS][SELECTOR_DOT].setColor(
+                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
+        mPaintSelector[HOURS][SELECTOR_DOT].setAntiAlias(true);
+
+        mPaintSelector[HOURS][SELECTOR_LINE] = new Paint();
+        mPaintSelector[HOURS][SELECTOR_LINE].setColor(
+                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
+        mPaintSelector[HOURS][SELECTOR_LINE].setAntiAlias(true);
+        mPaintSelector[HOURS][SELECTOR_LINE].setStrokeWidth(2);
+
+        mPaintSelector[MINUTES][SELECTOR_CIRCLE] = new Paint();
+        mPaintSelector[MINUTES][SELECTOR_CIRCLE].setColor(
+                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
+        mPaintSelector[MINUTES][SELECTOR_CIRCLE].setAntiAlias(true);
+
+        mPaintSelector[MINUTES][SELECTOR_DOT] = new Paint();
+        mPaintSelector[MINUTES][SELECTOR_DOT].setColor(
+                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
+        mPaintSelector[MINUTES][SELECTOR_DOT].setAntiAlias(true);
+
+        mPaintSelector[MINUTES][SELECTOR_LINE] = new Paint();
+        mPaintSelector[MINUTES][SELECTOR_LINE].setColor(
+                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
+        mPaintSelector[MINUTES][SELECTOR_LINE].setAntiAlias(true);
+        mPaintSelector[MINUTES][SELECTOR_LINE].setStrokeWidth(2);
+
+        mPaintAmPmText.setColor(mAmPmTextColor);
+        mPaintAmPmText.setTypeface(mTypeface);
+        mPaintAmPmText.setAntiAlias(true);
+        mPaintAmPmText.setTextAlign(Paint.Align.CENTER);
+
+        mPaintAmPmCircle[AM] = new Paint();
+        mPaintAmPmCircle[AM].setAntiAlias(true);
+        mPaintAmPmCircle[PM] = new Paint();
+        mPaintAmPmCircle[PM].setAntiAlias(true);
+
+        mPaintBackground.setColor(
+                a.getColor(R.styleable.TimePicker_numbersBackgroundColor, Color.WHITE));
+        mPaintBackground.setAntiAlias(true);
+
+        final int disabledColor = a.getColor(R.styleable.TimePicker_disabledColor,
+                res.getColor(R.color.timepicker_default_disabled_color_holo_light));
+        mPaintDisabled.setColor(disabledColor);
+        mPaintDisabled.setAntiAlias(true);
+
+        if (DEBUG) {
+            mPaintDebug.setColor(DEBUG_COLOR);
+            mPaintDebug.setAntiAlias(true);
+            mPaintDebug.setStrokeWidth(DEBUG_STROKE_WIDTH);
+            mPaintDebug.setStyle(Paint.Style.STROKE);
+            mPaintDebug.setTextAlign(Paint.Align.CENTER);
+        }
+
+        mShowHours = true;
+        mIs24HourMode = false;
+        mAmOrPm = AM;
+        mAmOrPmPressed = -1;
+
+        initHoursAndMinutesText();
+        initData();
+
+        mTransitionMidRadiusMultiplier =  Float.parseFloat(
+                res.getString(R.string.timepicker_transition_mid_radius_multiplier));
+        mTransitionEndRadiusMultiplier = Float.parseFloat(
+                res.getString(R.string.timepicker_transition_end_radius_multiplier));
+
+        mTextGridHeights[HOURS] = new float[7];
+        mTextGridHeights[MINUTES] = new float[7];
+
+        mSelectionRadiusMultiplier = Float.parseFloat(
+                res.getString(R.string.timepicker_selection_radius_multiplier));
+
+        setOnTouchListener(this);
+
+        // Initial values
+        final Calendar calendar = Calendar.getInstance(Locale.getDefault());
+        final int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
+        final int currentMinute = calendar.get(Calendar.MINUTE);
+
+        setCurrentHour(currentHour);
+        setCurrentMinute(currentMinute);
+
+        setHapticFeedbackEnabled(true);
+    }
+
+    /**
+     * Measure the view to end up as a square, based on the minimum of the height and width.
+     */
+    @Override
+    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
+        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        int minDimension = Math.min(measuredWidth, measuredHeight);
+
+        super.onMeasure(MeasureSpec.makeMeasureSpec(minDimension, widthMode),
+                MeasureSpec.makeMeasureSpec(minDimension, heightMode));
+    }
+
+    public void initialize(int hour, int minute, boolean is24HourMode) {
+        mIs24HourMode = is24HourMode;
+        setCurrentHour(hour);
+        setCurrentMinute(minute);
+    }
+
+    public void setCurrentItemShowing(int item, boolean animate) {
+        switch (item){
+            case HOURS:
+                showHours(animate);
+                break;
+            case MINUTES:
+                showMinutes(animate);
+                break;
+            default:
+                Log.e(TAG, "ClockView does not support showing item " + item);
+        }
+    }
+
+    public int getCurrentItemShowing() {
+        return mShowHours ? HOURS : MINUTES;
+    }
+
+    public void setOnValueSelectedListener(OnValueSelectedListener listener) {
+        mListener = listener;
+    }
+
+    public void setCurrentHour(int hour) {
+        final int degrees = (hour % 12) * DEGREES_FOR_ONE_HOUR;
+        mSelectionDegrees[HOURS] = degrees;
+        mSelectionDegrees[HOURS_INNER] = degrees;
+        mAmOrPm = ((hour % 24) < 12) ? AM : PM;
+        if (mIs24HourMode) {
+            mIsOnInnerCircle = (mAmOrPm == AM);
+        } else {
+            mIsOnInnerCircle = false;
+        }
+        initData();
+        updateLayoutData();
+        invalidate();
+    }
+
+    // Return hours in 0-23 range
+    public int getCurrentHour() {
+        int hours =
+                mSelectionDegrees[mIsOnInnerCircle ? HOURS_INNER : HOURS] / DEGREES_FOR_ONE_HOUR;
+        if (mIs24HourMode) {
+            if (mIsOnInnerCircle) {
+                hours = hours % 12;
+            } else {
+                if (hours != 0) {
+                    hours += 12;
+                }
+            }
+        } else {
+            hours = hours % 12;
+            if (hours == 0) {
+                if (mAmOrPm == PM) {
+                    hours = 12;
+                }
+            } else {
+                if (mAmOrPm == PM) {
+                    hours += 12;
+                }
+            }
+        }
+        return hours;
+    }
+
+    public void setCurrentMinute(int minute) {
+        mSelectionDegrees[MINUTES] = (minute % 60) * DEGREES_FOR_ONE_MINUTE;
+        invalidate();
+    }
+
+    // Returns minutes in 0-59 range
+    public int getCurrentMinute() {
+        return (mSelectionDegrees[MINUTES] / DEGREES_FOR_ONE_MINUTE);
+    }
+
+    public void setAmOrPm(int val) {
+        mAmOrPm = (val % 2);
+        invalidate();
+    }
+
+    public int getAmOrPm() {
+        return mAmOrPm;
+    }
+
+    public void swapAmPm() {
+        mAmOrPm = (mAmOrPm == AM) ? PM : AM;
+        invalidate();
+    }
+
+    public void showHours(boolean animate) {
+        if (mShowHours) return;
+        mShowHours = true;
+        if (animate) {
+            startMinutesToHoursAnimation();
+        }
+        initData();
+        updateLayoutData();
+        invalidate();
+    }
+
+    public void showMinutes(boolean animate) {
+        if (!mShowHours) return;
+        mShowHours = false;
+        if (animate) {
+            startHoursToMinutesAnimation();
+        }
+        initData();
+        updateLayoutData();
+        invalidate();
+    }
+
+    private void initHoursAndMinutesText() {
+        // Initialize the hours and minutes numbers.
+        for (int i = 0; i < 12; i++) {
+            mHours12Texts[i] = String.format("%d", HOURS_NUMBERS[i]);
+            mOuterHours24Texts[i] = String.format("%02d", HOURS_NUMBERS_24[i]);
+            mInnerHours24Texts[i] = String.format("%d", HOURS_NUMBERS[i]);
+            mMinutesTexts[i] = String.format("%02d", MINUTES_NUMBERS[i]);
+        }
+
+        String[] amPmTexts = new DateFormatSymbols().getAmPmStrings();
+        mAmPmText[AM] = amPmTexts[0];
+        mAmPmText[PM] = amPmTexts[1];
+    }
+
+    private void initData() {
+        if (mIs24HourMode) {
+            mOuterTextHours = mOuterHours24Texts;
+            mInnerTextHours = mInnerHours24Texts;
+        } else {
+            mOuterTextHours = mHours12Texts;
+            mInnerTextHours = null;
+        }
+
+        mOuterTextMinutes = mMinutesTexts;
+
+        final Resources res = getResources();
+
+        if (mShowHours) {
+            if (mIs24HourMode) {
+                mCircleRadiusMultiplier[HOURS] = Float.parseFloat(
+                        res.getString(R.string.timepicker_circle_radius_multiplier_24HourMode));
+                mNumbersRadiusMultiplier[HOURS] = Float.parseFloat(
+                        res.getString(R.string.timepicker_numbers_radius_multiplier_outer));
+                mTextSizeMultiplier[HOURS] = Float.parseFloat(
+                        res.getString(R.string.timepicker_text_size_multiplier_outer));
+
+                mNumbersRadiusMultiplier[HOURS_INNER] = Float.parseFloat(
+                        res.getString(R.string.timepicker_numbers_radius_multiplier_inner));
+                mTextSizeMultiplier[HOURS_INNER] = Float.parseFloat(
+                        res.getString(R.string.timepicker_text_size_multiplier_inner));
+            } else {
+                mCircleRadiusMultiplier[HOURS] = Float.parseFloat(
+                        res.getString(R.string.timepicker_circle_radius_multiplier));
+                mNumbersRadiusMultiplier[HOURS] = Float.parseFloat(
+                        res.getString(R.string.timepicker_numbers_radius_multiplier_normal));
+                mTextSizeMultiplier[HOURS] = Float.parseFloat(
+                        res.getString(R.string.timepicker_text_size_multiplier_normal));
+            }
+        } else {
+            mCircleRadiusMultiplier[MINUTES] = Float.parseFloat(
+                    res.getString(R.string.timepicker_circle_radius_multiplier));
+            mNumbersRadiusMultiplier[MINUTES] = Float.parseFloat(
+                    res.getString(R.string.timepicker_numbers_radius_multiplier_normal));
+            mTextSizeMultiplier[MINUTES] = Float.parseFloat(
+                    res.getString(R.string.timepicker_text_size_multiplier_normal));
+        }
+
+        mAnimationRadiusMultiplier[HOURS] = 1;
+        mAnimationRadiusMultiplier[HOURS_INNER] = 1;
+        mAnimationRadiusMultiplier[MINUTES] = 1;
+
+        mAmPmCircleRadiusMultiplier = Float.parseFloat(
+                res.getString(R.string.timepicker_ampm_circle_radius_multiplier));
+
+        mPaint[HOURS].setAlpha(mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT);
+        mPaint[MINUTES].setAlpha(mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE);
+
+        mPaintSelector[HOURS][SELECTOR_CIRCLE].setAlpha(
+                mShowHours ?ALPHA_SELECTOR : ALPHA_TRANSPARENT);
+        mPaintSelector[HOURS][SELECTOR_DOT].setAlpha(
+                mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT);
+        mPaintSelector[HOURS][SELECTOR_LINE].setAlpha(
+                mShowHours ? ALPHA_SELECTOR : ALPHA_TRANSPARENT);
+
+        mPaintSelector[MINUTES][SELECTOR_CIRCLE].setAlpha(
+                mShowHours ? ALPHA_TRANSPARENT : ALPHA_SELECTOR);
+        mPaintSelector[MINUTES][SELECTOR_DOT].setAlpha(
+                mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE);
+        mPaintSelector[MINUTES][SELECTOR_LINE].setAlpha(
+                mShowHours ? ALPHA_TRANSPARENT : ALPHA_SELECTOR);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        updateLayoutData();
+    }
+
+    private void updateLayoutData() {
+        mXCenter = getWidth() / 2;
+        mYCenter = getHeight() / 2;
+
+        final int min = Math.min(mXCenter, mYCenter);
+
+        mCircleRadius[HOURS] = min * mCircleRadiusMultiplier[HOURS];
+        mCircleRadius[HOURS_INNER] = min * mCircleRadiusMultiplier[HOURS];
+        mCircleRadius[MINUTES] = min * mCircleRadiusMultiplier[MINUTES];
+
+        if (!mIs24HourMode) {
+            // We'll need to draw the AM/PM circles, so the main circle will need to have
+            // a slightly higher center. To keep the entire view centered vertically, we'll
+            // have to push it up by half the radius of the AM/PM circles.
+            int amPmCircleRadius = (int) (mCircleRadius[HOURS] * mAmPmCircleRadiusMultiplier);
+            mYCenter -= amPmCircleRadius / 2;
+        }
+
+        mMinHypotenuseForInnerNumber = (int) (mCircleRadius[HOURS]
+                * mNumbersRadiusMultiplier[HOURS_INNER]) - mSelectionRadius[HOURS];
+        mMaxHypotenuseForOuterNumber = (int) (mCircleRadius[HOURS]
+                * mNumbersRadiusMultiplier[HOURS]) + mSelectionRadius[HOURS];
+        mHalfwayHypotenusePoint = (int) (mCircleRadius[HOURS]
+                * ((mNumbersRadiusMultiplier[HOURS] + mNumbersRadiusMultiplier[HOURS_INNER]) / 2));
+
+        mTextSize[HOURS] = mCircleRadius[HOURS] * mTextSizeMultiplier[HOURS];
+        mTextSize[MINUTES] = mCircleRadius[MINUTES] * mTextSizeMultiplier[MINUTES];
+
+        if (mIs24HourMode) {
+            mInnerTextSize = mCircleRadius[HOURS] * mTextSizeMultiplier[HOURS_INNER];
+        }
+
+        calculateGridSizesHours();
+        calculateGridSizesMinutes();
+
+        mSelectionRadius[HOURS] = (int) (mCircleRadius[HOURS] * mSelectionRadiusMultiplier);
+        mSelectionRadius[HOURS_INNER] = mSelectionRadius[HOURS];
+        mSelectionRadius[MINUTES] = (int) (mCircleRadius[MINUTES] * mSelectionRadiusMultiplier);
+
+        mAmPmCircleRadius = (int) (mCircleRadius[HOURS] * mAmPmCircleRadiusMultiplier);
+        mPaintAmPmText.setTextSize(mAmPmCircleRadius * 3 / 4);
+
+        // Line up the vertical center of the AM/PM circles with the bottom of the main circle.
+        mAmPmYCenter = mYCenter + mCircleRadius[HOURS];
+
+        // Line up the horizontal edges of the AM/PM circles with the horizontal edges
+        // of the main circle
+        mLeftIndicatorXCenter = mXCenter - mCircleRadius[HOURS] + mAmPmCircleRadius;
+        mRightIndicatorXCenter = mXCenter + mCircleRadius[HOURS] - mAmPmCircleRadius;
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        canvas.save();
+
+        calculateGridSizesHours();
+        calculateGridSizesMinutes();
+
+        drawCircleBackground(canvas);
+
+        drawTextElements(canvas, mTextSize[HOURS], mTypeface, mOuterTextHours,
+                mTextGridWidths[HOURS], mTextGridHeights[HOURS], mPaint[HOURS]);
+
+        if (mIs24HourMode && mInnerTextHours != null) {
+            drawTextElements(canvas, mInnerTextSize, mTypeface, mInnerTextHours,
+                    mInnerTextGridWidths, mInnerTextGridHeights, mPaint[HOURS]);
+        }
+
+        drawTextElements(canvas, mTextSize[MINUTES], mTypeface, mOuterTextMinutes,
+                mTextGridWidths[MINUTES], mTextGridHeights[MINUTES], mPaint[MINUTES]);
+
+        drawCenter(canvas);
+        drawSelector(canvas);
+        if (!mIs24HourMode) {
+            drawAmPm(canvas);
+        }
+
+        if(!mInputEnabled) {
+            // Draw outer view rectangle
+            mRectF.set(0, 0, getWidth(), getHeight());
+            canvas.drawRect(mRectF, mPaintDisabled);
+        }
+
+        if (DEBUG) {
+            drawDebug(canvas);
+        }
+
+        canvas.restore();
+    }
+
+    private void drawCircleBackground(Canvas canvas) {
+        canvas.drawCircle(mXCenter, mYCenter, mCircleRadius[HOURS], mPaintBackground);
+    }
+
+    private void drawCenter(Canvas canvas) {
+        canvas.drawCircle(mXCenter, mYCenter, CENTER_RADIUS, mPaintCenter);
+    }
+
+    private void drawSelector(Canvas canvas) {
+        drawSelector(canvas, mIsOnInnerCircle ? HOURS_INNER : HOURS);
+        drawSelector(canvas, MINUTES);
+    }
+
+    private void drawAmPm(Canvas canvas) {
+        final boolean isLayoutRtl = isLayoutRtl();
+
+        int amColor = mAmPmUnselectedColor;
+        int amAlpha = ALPHA_OPAQUE;
+        int pmColor = mAmPmUnselectedColor;
+        int pmAlpha = ALPHA_OPAQUE;
+        if (mAmOrPm == AM) {
+            amColor = mAmPmSelectedColor;
+            amAlpha = ALPHA_AMPM_SELECTED;
+        } else if (mAmOrPm == PM) {
+            pmColor = mAmPmSelectedColor;
+            pmAlpha = ALPHA_AMPM_SELECTED;
+        }
+        if (mAmOrPmPressed == AM) {
+            amColor = mAmPmSelectedColor;
+            amAlpha = ALPHA_AMPM_PRESSED;
+        } else if (mAmOrPmPressed == PM) {
+            pmColor = mAmPmSelectedColor;
+            pmAlpha = ALPHA_AMPM_PRESSED;
+        }
+
+        // Draw the two circles
+        mPaintAmPmCircle[AM].setColor(amColor);
+        mPaintAmPmCircle[AM].setAlpha(amAlpha);
+        canvas.drawCircle(isLayoutRtl ? mRightIndicatorXCenter : mLeftIndicatorXCenter,
+                mAmPmYCenter, mAmPmCircleRadius, mPaintAmPmCircle[AM]);
+
+        mPaintAmPmCircle[PM].setColor(pmColor);
+        mPaintAmPmCircle[PM].setAlpha(pmAlpha);
+        canvas.drawCircle(isLayoutRtl ? mLeftIndicatorXCenter : mRightIndicatorXCenter,
+                mAmPmYCenter, mAmPmCircleRadius, mPaintAmPmCircle[PM]);
+
+        // Draw the AM/PM texts on top
+        mPaintAmPmText.setColor(mAmPmTextColor);
+        float textYCenter = mAmPmYCenter -
+                (int) (mPaintAmPmText.descent() + mPaintAmPmText.ascent()) / 2;
+
+        canvas.drawText(isLayoutRtl ? mAmPmText[PM] : mAmPmText[AM], mLeftIndicatorXCenter,
+                textYCenter, mPaintAmPmText);
+        canvas.drawText(isLayoutRtl ? mAmPmText[AM] : mAmPmText[PM], mRightIndicatorXCenter,
+                textYCenter, mPaintAmPmText);
+    }
+
+    private void drawSelector(Canvas canvas, int index) {
+        // Calculate the current radius at which to place the selection circle.
+        mLineLength[index] = (int) (mCircleRadius[index]
+                * mNumbersRadiusMultiplier[index] * mAnimationRadiusMultiplier[index]);
+
+        double selectionRadians = Math.toRadians(mSelectionDegrees[index]);
+
+        int pointX = mXCenter + (int) (mLineLength[index] * Math.sin(selectionRadians));
+        int pointY = mYCenter - (int) (mLineLength[index] * Math.cos(selectionRadians));
+
+        // Draw the selection circle
+        canvas.drawCircle(pointX, pointY, mSelectionRadius[index],
+                mPaintSelector[index % 2][SELECTOR_CIRCLE]);
+
+        // Draw the dot if needed
+        if (mSelectionDegrees[index] % 30 != 0) {
+            // We're not on a direct tick
+            canvas.drawCircle(pointX, pointY, (mSelectionRadius[index] * 2 / 7),
+                    mPaintSelector[index % 2][SELECTOR_DOT]);
+        } else {
+            // We're not drawing the dot, so shorten the line to only go as far as the edge of the
+            // selection circle
+            int lineLength = mLineLength[index] - mSelectionRadius[index];
+            pointX = mXCenter + (int) (lineLength * Math.sin(selectionRadians));
+            pointY = mYCenter - (int) (lineLength * Math.cos(selectionRadians));
+        }
+
+        // Draw the line
+        canvas.drawLine(mXCenter, mYCenter, pointX, pointY,
+                mPaintSelector[index % 2][SELECTOR_LINE]);
+    }
+
+    private void drawDebug(Canvas canvas) {
+        // Draw outer numbers circle
+        final float outerRadius = mCircleRadius[HOURS] * mNumbersRadiusMultiplier[HOURS];
+        canvas.drawCircle(mXCenter, mYCenter, outerRadius, mPaintDebug);
+
+        // Draw inner numbers circle
+        final float innerRadius = mCircleRadius[HOURS] * mNumbersRadiusMultiplier[HOURS_INNER];
+        canvas.drawCircle(mXCenter, mYCenter, innerRadius, mPaintDebug);
+
+        // Draw outer background circle
+        canvas.drawCircle(mXCenter, mYCenter, mCircleRadius[HOURS], mPaintDebug);
+
+        // Draw outer rectangle for circles
+        float left = mXCenter - outerRadius;
+        float top = mYCenter - outerRadius;
+        float right = mXCenter + outerRadius;
+        float bottom = mYCenter + outerRadius;
+        mRectF = new RectF(left, top, right, bottom);
+        canvas.drawRect(mRectF, mPaintDebug);
+
+        // Draw outer rectangle for background
+        left = mXCenter - mCircleRadius[HOURS];
+        top = mYCenter - mCircleRadius[HOURS];
+        right = mXCenter + mCircleRadius[HOURS];
+        bottom = mYCenter + mCircleRadius[HOURS];
+        mRectF.set(left, top, right, bottom);
+        canvas.drawRect(mRectF, mPaintDebug);
+
+        // Draw outer view rectangle
+        mRectF.set(0, 0, getWidth(), getHeight());
+        canvas.drawRect(mRectF, mPaintDebug);
+
+        // Draw selected time
+        final String selected = String.format("%02d:%02d", getCurrentHour(), getCurrentMinute());
+
+        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+        TextView tv = new TextView(getContext());
+        tv.setLayoutParams(lp);
+        tv.setText(selected);
+        tv.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+        Paint paint = tv.getPaint();
+        paint.setColor(DEBUG_TEXT_COLOR);
+
+        final int width = tv.getMeasuredWidth();
+
+        float height = paint.descent() - paint.ascent();
+        float x = mXCenter - width / 2;
+        float y = mYCenter + 1.5f * height;
+
+        canvas.drawText(selected.toString(), x, y, paint);
+    }
+
+    private void calculateGridSizesHours() {
+        // Calculate the text positions
+        float numbersRadius = mCircleRadius[HOURS]
+                * mNumbersRadiusMultiplier[HOURS] * mAnimationRadiusMultiplier[HOURS];
+
+        // Calculate the positions for the 12 numbers in the main circle.
+        calculateGridSizes(mPaint[HOURS], numbersRadius, mXCenter, mYCenter,
+                mTextSize[HOURS], mTextGridHeights[HOURS], mTextGridWidths[HOURS]);
+
+        // If we have an inner circle, calculate those positions too.
+        if (mIs24HourMode) {
+            float innerNumbersRadius = mCircleRadius[HOURS_INNER]
+                    * mNumbersRadiusMultiplier[HOURS_INNER]
+                    * mAnimationRadiusMultiplier[HOURS_INNER];
+
+            calculateGridSizes(mPaint[HOURS], innerNumbersRadius, mXCenter, mYCenter,
+                    mInnerTextSize, mInnerTextGridHeights, mInnerTextGridWidths);
+        }
+    }
+
+    private void calculateGridSizesMinutes() {
+        // Calculate the text positions
+        float numbersRadius = mCircleRadius[MINUTES]
+                * mNumbersRadiusMultiplier[MINUTES] * mAnimationRadiusMultiplier[MINUTES];
+
+        // Calculate the positions for the 12 numbers in the main circle.
+        calculateGridSizes(mPaint[MINUTES], numbersRadius, mXCenter, mYCenter,
+                mTextSize[MINUTES], mTextGridHeights[MINUTES], mTextGridWidths[MINUTES]);
+    }
+
+
+    /**
+     * Using the trigonometric Unit Circle, calculate the positions that the text will need to be
+     * drawn at based on the specified circle radius. Place the values in the textGridHeights and
+     * textGridWidths parameters.
+     */
+    private static void calculateGridSizes(Paint paint, float numbersRadius, float xCenter,
+            float yCenter, float textSize, float[] textGridHeights, float[] textGridWidths) {
+        /*
+         * The numbers need to be drawn in a 7x7 grid, representing the points on the Unit Circle.
+         */
+        final float offset1 = numbersRadius;
+        // cos(30) = a / r => r * cos(30)
+        final float offset2 = numbersRadius * COSINE_30_DEGREES;
+        // sin(30) = o / r => r * sin(30)
+        final float offset3 = numbersRadius * SINE_30_DEGREES;
+
+        paint.setTextSize(textSize);
+        // We'll need yTextBase to be slightly lower to account for the text's baseline.
+        yCenter -= (paint.descent() + paint.ascent()) / 2;
+
+        textGridHeights[0] = yCenter - offset1;
+        textGridWidths[0] = xCenter - offset1;
+        textGridHeights[1] = yCenter - offset2;
+        textGridWidths[1] = xCenter - offset2;
+        textGridHeights[2] = yCenter - offset3;
+        textGridWidths[2] = xCenter - offset3;
+        textGridHeights[3] = yCenter;
+        textGridWidths[3] = xCenter;
+        textGridHeights[4] = yCenter + offset3;
+        textGridWidths[4] = xCenter + offset3;
+        textGridHeights[5] = yCenter + offset2;
+        textGridWidths[5] = xCenter + offset2;
+        textGridHeights[6] = yCenter + offset1;
+        textGridWidths[6] = xCenter + offset1;
+    }
+
+    /**
+     * Draw the 12 text values at the positions specified by the textGrid parameters.
+     */
+    private void drawTextElements(Canvas canvas, float textSize, Typeface typeface, String[] texts,
+            float[] textGridWidths, float[] textGridHeights, Paint paint) {
+        paint.setTextSize(textSize);
+        paint.setTypeface(typeface);
+        canvas.drawText(texts[0], textGridWidths[3], textGridHeights[0], paint);
+        canvas.drawText(texts[1], textGridWidths[4], textGridHeights[1], paint);
+        canvas.drawText(texts[2], textGridWidths[5], textGridHeights[2], paint);
+        canvas.drawText(texts[3], textGridWidths[6], textGridHeights[3], paint);
+        canvas.drawText(texts[4], textGridWidths[5], textGridHeights[4], paint);
+        canvas.drawText(texts[5], textGridWidths[4], textGridHeights[5], paint);
+        canvas.drawText(texts[6], textGridWidths[3], textGridHeights[6], paint);
+        canvas.drawText(texts[7], textGridWidths[2], textGridHeights[5], paint);
+        canvas.drawText(texts[8], textGridWidths[1], textGridHeights[4], paint);
+        canvas.drawText(texts[9], textGridWidths[0], textGridHeights[3], paint);
+        canvas.drawText(texts[10], textGridWidths[1], textGridHeights[2], paint);
+        canvas.drawText(texts[11], textGridWidths[2], textGridHeights[1], paint);
+    }
+
+    // Used for animating the hours by changing their radius
+    private void setAnimationRadiusMultiplierHours(float animationRadiusMultiplier) {
+        mAnimationRadiusMultiplier[HOURS] = animationRadiusMultiplier;
+        mAnimationRadiusMultiplier[HOURS_INNER] = animationRadiusMultiplier;
+    }
+
+    // Used for animating the minutes by changing their radius
+    private void setAnimationRadiusMultiplierMinutes(float animationRadiusMultiplier) {
+        mAnimationRadiusMultiplier[MINUTES] = animationRadiusMultiplier;
+    }
+
+    private static ObjectAnimator getRadiusDisappearAnimator(Object target,
+            String radiusPropertyName, InvalidateUpdateListener updateListener,
+            float midRadiusMultiplier, float endRadiusMultiplier) {
+        Keyframe kf0, kf1, kf2;
+        float midwayPoint = 0.2f;
+        int duration = 500;
+
+        kf0 = Keyframe.ofFloat(0f, 1);
+        kf1 = Keyframe.ofFloat(midwayPoint, midRadiusMultiplier);
+        kf2 = Keyframe.ofFloat(1f, endRadiusMultiplier);
+        PropertyValuesHolder radiusDisappear = PropertyValuesHolder.ofKeyframe(
+                radiusPropertyName, kf0, kf1, kf2);
+
+        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(
+                target, radiusDisappear).setDuration(duration);
+        animator.addUpdateListener(updateListener);
+        return animator;
+    }
+
+    private static ObjectAnimator getRadiusReappearAnimator(Object target,
+            String radiusPropertyName, InvalidateUpdateListener updateListener,
+            float midRadiusMultiplier, float endRadiusMultiplier) {
+        Keyframe kf0, kf1, kf2, kf3;
+        float midwayPoint = 0.2f;
+        int duration = 500;
+
+        // Set up animator for reappearing.
+        float delayMultiplier = 0.25f;
+        float transitionDurationMultiplier = 1f;
+        float totalDurationMultiplier = transitionDurationMultiplier + delayMultiplier;
+        int totalDuration = (int) (duration * totalDurationMultiplier);
+        float delayPoint = (delayMultiplier * duration) / totalDuration;
+        midwayPoint = 1 - (midwayPoint * (1 - delayPoint));
+
+        kf0 = Keyframe.ofFloat(0f, endRadiusMultiplier);
+        kf1 = Keyframe.ofFloat(delayPoint, endRadiusMultiplier);
+        kf2 = Keyframe.ofFloat(midwayPoint, midRadiusMultiplier);
+        kf3 = Keyframe.ofFloat(1f, 1);
+        PropertyValuesHolder radiusReappear = PropertyValuesHolder.ofKeyframe(
+                radiusPropertyName, kf0, kf1, kf2, kf3);
+
+        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(
+                target, radiusReappear).setDuration(totalDuration);
+        animator.addUpdateListener(updateListener);
+        return animator;
+    }
+
+    private static ObjectAnimator getFadeOutAnimator(Object target, int startAlpha, int endAlpha,
+                InvalidateUpdateListener updateListener) {
+        int duration = 500;
+        ObjectAnimator animator = ObjectAnimator.ofInt(target, "alpha", startAlpha, endAlpha);
+        animator.setDuration(duration);
+        animator.addUpdateListener(updateListener);
+
+        return animator;
+    }
+
+    private static ObjectAnimator getFadeInAnimator(Object target, int startAlpha, int endAlpha,
+                InvalidateUpdateListener updateListener) {
+        Keyframe kf0, kf1, kf2;
+        int duration = 500;
+
+        // Set up animator for reappearing.
+        float delayMultiplier = 0.25f;
+        float transitionDurationMultiplier = 1f;
+        float totalDurationMultiplier = transitionDurationMultiplier + delayMultiplier;
+        int totalDuration = (int) (duration * totalDurationMultiplier);
+        float delayPoint = (delayMultiplier * duration) / totalDuration;
+
+        kf0 = Keyframe.ofInt(0f, startAlpha);
+        kf1 = Keyframe.ofInt(delayPoint, startAlpha);
+        kf2 = Keyframe.ofInt(1f, endAlpha);
+        PropertyValuesHolder fadeIn = PropertyValuesHolder.ofKeyframe("alpha", kf0, kf1, kf2);
+
+        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(
+                target, fadeIn).setDuration(totalDuration);
+        animator.addUpdateListener(updateListener);
+        return animator;
+    }
+
+    private class InvalidateUpdateListener implements ValueAnimator.AnimatorUpdateListener {
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            RadialTimePickerView.this.invalidate();
+        }
+    }
+
+    private void startHoursToMinutesAnimation() {
+        if (mHoursToMinutesAnims.size() == 0) {
+            mHoursToMinutesAnims.add(getRadiusDisappearAnimator(this,
+                    "animationRadiusMultiplierHours", mInvalidateUpdateListener,
+                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
+            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaint[HOURS],
+                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaintSelector[HOURS][SELECTOR_CIRCLE],
+                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaintSelector[HOURS][SELECTOR_DOT],
+                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaintSelector[HOURS][SELECTOR_LINE],
+                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+
+            mHoursToMinutesAnims.add(getRadiusReappearAnimator(this,
+                    "animationRadiusMultiplierMinutes", mInvalidateUpdateListener,
+                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
+            mHoursToMinutesAnims.add(getFadeInAnimator(mPaint[MINUTES],
+                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
+            mHoursToMinutesAnims.add(getFadeInAnimator(mPaintSelector[MINUTES][SELECTOR_CIRCLE],
+                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
+            mHoursToMinutesAnims.add(getFadeInAnimator(mPaintSelector[MINUTES][SELECTOR_DOT],
+                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
+            mHoursToMinutesAnims.add(getFadeInAnimator(mPaintSelector[MINUTES][SELECTOR_LINE],
+                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
+        }
+
+        if (mTransition != null && mTransition.isRunning()) {
+            mTransition.end();
+        }
+        mTransition = new AnimatorSet();
+        mTransition.playTogether(mHoursToMinutesAnims);
+        mTransition.start();
+    }
+
+    private void startMinutesToHoursAnimation() {
+        if (mMinuteToHoursAnims.size() == 0) {
+            mMinuteToHoursAnims.add(getRadiusDisappearAnimator(this,
+                    "animationRadiusMultiplierMinutes", mInvalidateUpdateListener,
+                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
+            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaint[MINUTES],
+                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaintSelector[MINUTES][SELECTOR_CIRCLE],
+                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaintSelector[MINUTES][SELECTOR_DOT],
+                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaintSelector[MINUTES][SELECTOR_LINE],
+                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+
+            mMinuteToHoursAnims.add(getRadiusReappearAnimator(this,
+                    "animationRadiusMultiplierHours", mInvalidateUpdateListener,
+                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
+            mMinuteToHoursAnims.add(getFadeInAnimator(mPaint[HOURS],
+                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
+            mMinuteToHoursAnims.add(getFadeInAnimator(mPaintSelector[HOURS][SELECTOR_CIRCLE],
+                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
+            mMinuteToHoursAnims.add(getFadeInAnimator(mPaintSelector[HOURS][SELECTOR_DOT],
+                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
+            mMinuteToHoursAnims.add(getFadeInAnimator(mPaintSelector[HOURS][SELECTOR_LINE],
+                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
+        }
+
+        if (mTransition != null && mTransition.isRunning()) {
+            mTransition.end();
+        }
+        mTransition = new AnimatorSet();
+        mTransition.playTogether(mMinuteToHoursAnims);
+        mTransition.start();
+    }
+
+    private int getDegreesFromXY(float x, float y) {
+        final double hypotenuse = Math.sqrt(
+                (y - mYCenter) * (y - mYCenter) + (x - mXCenter) * (x - mXCenter));
+
+        // Basic check if we're outside the range of the disk
+        if (hypotenuse > mCircleRadius[HOURS]) {
+            return -1;
+        }
+        // Check
+        if (mIs24HourMode && mShowHours) {
+            if (hypotenuse >= mMinHypotenuseForInnerNumber
+                    && hypotenuse <= mHalfwayHypotenusePoint) {
+                mIsOnInnerCircle = true;
+            } else if (hypotenuse <= mMaxHypotenuseForOuterNumber
+                    && hypotenuse >= mHalfwayHypotenusePoint) {
+                mIsOnInnerCircle = false;
+            } else {
+                return -1;
+            }
+        } else {
+            final int index =  (mShowHours) ? HOURS : MINUTES;
+            final float length = (mCircleRadius[index] * mNumbersRadiusMultiplier[index]);
+            final int distanceToNumber = (int) Math.abs(hypotenuse - length);
+            final int maxAllowedDistance =
+                    (int) (mCircleRadius[index] * (1 - mNumbersRadiusMultiplier[index]));
+            if (distanceToNumber > maxAllowedDistance) {
+                return -1;
+            }
+        }
+
+        final float opposite = Math.abs(y - mYCenter);
+        double degrees = Math.toDegrees(Math.asin(opposite / hypotenuse));
+
+        // Now we have to translate to the correct quadrant.
+        boolean rightSide = (x > mXCenter);
+        boolean topSide = (y < mYCenter);
+        if (rightSide && topSide) {
+            degrees = 90 - degrees;
+        } else if (rightSide && !topSide) {
+            degrees = 90 + degrees;
+        } else if (!rightSide && !topSide) {
+            degrees = 270 - degrees;
+        } else if (!rightSide && topSide) {
+            degrees = 270 + degrees;
+        }
+        return (int) degrees;
+    }
+
+    private int getIsTouchingAmOrPm(float x, float y) {
+        final boolean isLayoutRtl = isLayoutRtl();
+        int squaredYDistance = (int) ((y - mAmPmYCenter) * (y - mAmPmYCenter));
+
+        int distanceToAmCenter = (int) Math.sqrt(
+                (x - mLeftIndicatorXCenter) * (x - mLeftIndicatorXCenter) + squaredYDistance);
+        if (distanceToAmCenter <= mAmPmCircleRadius) {
+            return (isLayoutRtl ? PM : AM);
+        }
+
+        int distanceToPmCenter = (int) Math.sqrt(
+                (x - mRightIndicatorXCenter) * (x - mRightIndicatorXCenter) + squaredYDistance);
+        if (distanceToPmCenter <= mAmPmCircleRadius) {
+            return (isLayoutRtl ? AM : PM);
+        }
+
+        // Neither was close enough.
+        return -1;
+    }
+
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+        if(!mInputEnabled) {
+            return true;
+        }
+
+        final float eventX = event.getX();
+        final float eventY = event.getY();
+
+        int degrees;
+        int snapDegrees;
+        boolean result = false;
+
+        switch(event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_MOVE:
+                mAmOrPmPressed = getIsTouchingAmOrPm(eventX, eventY);
+                if (mAmOrPmPressed != -1) {
+                    result = true;
+                } else {
+                    degrees = getDegreesFromXY(eventX, eventY);
+                    if (degrees != -1) {
+                        snapDegrees = (mShowHours ?
+                                snapOnly30s(degrees, 0) : snapPrefer30s(degrees)) % 360;
+                        if (mShowHours) {
+                            mSelectionDegrees[HOURS] = snapDegrees;
+                            mSelectionDegrees[HOURS_INNER] = snapDegrees;
+                        } else {
+                            mSelectionDegrees[MINUTES] = snapDegrees;
+                        }
+                        performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
+                        if (mListener != null) {
+                            if (mShowHours) {
+                                mListener.onValueSelected(HOURS, getCurrentHour(), false);
+                            } else  {
+                                mListener.onValueSelected(MINUTES, getCurrentMinute(), false);
+                            }
+                        }
+                        result = true;
+                    }
+                }
+                invalidate();
+                return result;
+
+            case MotionEvent.ACTION_UP:
+                mAmOrPmPressed = getIsTouchingAmOrPm(eventX, eventY);
+                if (mAmOrPmPressed != -1) {
+                    if (mAmOrPm != mAmOrPmPressed) {
+                        swapAmPm();
+                    }
+                    mAmOrPmPressed = -1;
+                    if (mListener != null) {
+                        mListener.onValueSelected(AMPM, getCurrentHour(), true);
+                    }
+                    result = true;
+                } else {
+                    degrees = getDegreesFromXY(eventX, eventY);
+                    if (degrees != -1) {
+                        snapDegrees = (mShowHours ?
+                                snapOnly30s(degrees, 0) : snapPrefer30s(degrees)) % 360;
+                        if (mShowHours) {
+                            mSelectionDegrees[HOURS] = snapDegrees;
+                            mSelectionDegrees[HOURS_INNER] = snapDegrees;
+                        } else {
+                            mSelectionDegrees[MINUTES] = snapDegrees;
+                        }
+                        if (mListener != null) {
+                            if (mShowHours) {
+                                mListener.onValueSelected(HOURS, getCurrentHour(), true);
+                            } else  {
+                                mListener.onValueSelected(MINUTES, getCurrentMinute(), true);
+                            }
+                        }
+                        result = true;
+                    }
+                }
+                if (result) {
+                    invalidate();
+                }
+                return result;
+
+            default:
+                break;
+        }
+        return false;
+    }
+
+    /**
+     * Necessary for accessibility, to ensure we support "scrolling" forward and backward
+     * in the circle.
+     */
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+        info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+    }
+
+    /**
+     * Announce the currently-selected time when launched.
+     */
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+            // Clear the event's current text so that only the current time will be spoken.
+            event.getText().clear();
+            Time time = new Time();
+            time.hour = getCurrentHour();
+            time.minute = getCurrentMinute();
+            long millis = time.normalize(true);
+            int flags = DateUtils.FORMAT_SHOW_TIME;
+            if (mIs24HourMode) {
+                flags |= DateUtils.FORMAT_24HOUR;
+            }
+            String timeString = DateUtils.formatDateTime(getContext(), millis, flags);
+            event.getText().add(timeString);
+            return true;
+        }
+        return super.dispatchPopulateAccessibilityEvent(event);
+    }
+
+    /**
+     * When scroll forward/backward events are received, jump the time to the higher/lower
+     * discrete, visible value on the circle.
+     */
+    @SuppressLint("NewApi")
+    @Override
+    public boolean performAccessibilityAction(int action, Bundle arguments) {
+        if (super.performAccessibilityAction(action, arguments)) {
+            return true;
+        }
+
+        int changeMultiplier = 0;
+        if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) {
+            changeMultiplier = 1;
+        } else if (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) {
+            changeMultiplier = -1;
+        }
+        if (changeMultiplier != 0) {
+            int value = 0;
+            int stepSize = 0;
+            if (mShowHours) {
+                stepSize = DEGREES_FOR_ONE_HOUR;
+                value = getCurrentHour() % 12;
+            } else {
+                stepSize = DEGREES_FOR_ONE_MINUTE;
+                value = getCurrentMinute();
+            }
+
+            int degrees = value * stepSize;
+            degrees = snapOnly30s(degrees, changeMultiplier);
+            value = degrees / stepSize;
+            int maxValue = 0;
+            int minValue = 0;
+            if (mShowHours) {
+                if (mIs24HourMode) {
+                    maxValue = 23;
+                } else {
+                    maxValue = 12;
+                    minValue = 1;
+                }
+            } else {
+                maxValue = 55;
+            }
+            if (value > maxValue) {
+                // If we scrolled forward past the highest number, wrap around to the lowest.
+                value = minValue;
+            } else if (value < minValue) {
+                // If we scrolled backward past the lowest number, wrap around to the highest.
+                value = maxValue;
+            }
+            if (mShowHours) {
+                setCurrentHour(value);
+                if (mListener != null) {
+                    mListener.onValueSelected(HOURS, value, false);
+                }
+            } else {
+                setCurrentMinute(value);
+                if (mListener != null) {
+                    mListener.onValueSelected(MINUTES, value, false);
+                }
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    public void setInputEnabled(boolean inputEnabled) {
+        mInputEnabled = inputEnabled;
+        invalidate();
+    }
+}
diff --git a/core/java/android/widget/RadioButton.java b/core/java/android/widget/RadioButton.java
index a0fef7d..afc4830 100644
--- a/core/java/android/widget/RadioButton.java
+++ b/core/java/android/widget/RadioButton.java
@@ -21,8 +21,6 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 
-import com.android.internal.R;
-
 
 /**
  * <p>
@@ -59,8 +57,12 @@
         this(context, attrs, com.android.internal.R.attr.radioButtonStyle);
     }
 
-    public RadioButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public RadioButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public RadioButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     /**
diff --git a/core/java/android/widget/RatingBar.java b/core/java/android/widget/RatingBar.java
index 4d3c56c..82b490e 100644
--- a/core/java/android/widget/RatingBar.java
+++ b/core/java/android/widget/RatingBar.java
@@ -82,11 +82,15 @@
     
     private OnRatingBarChangeListener mOnRatingBarChangeListener;
     
-    public RatingBar(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RatingBar,
-                defStyle, 0);
+    public RatingBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public RatingBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.RatingBar, defStyleAttr, defStyleRes);
         final int numStars = a.getInt(R.styleable.RatingBar_numStars, mNumStars);
         setIsIndicator(a.getBoolean(R.styleable.RatingBar_isIndicator, !mIsUserSeekable));
         final float rating = a.getFloat(R.styleable.RatingBar_rating, -1);
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index e03e83d..70ef10b 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -228,24 +228,27 @@
     private static final int DEFAULT_WIDTH = 0x00010000;
 
     public RelativeLayout(Context context) {
-        super(context);
-        queryCompatibilityModes(context);
+        this(context, null);
     }
 
     public RelativeLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        initFromAttributes(context, attrs);
+        this(context, attrs, 0);
+    }
+
+    public RelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public RelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        initFromAttributes(context, attrs, defStyleAttr, defStyleRes);
         queryCompatibilityModes(context);
     }
 
-    public RelativeLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        initFromAttributes(context, attrs);
-        queryCompatibilityModes(context);
-    }
-
-    private void initFromAttributes(Context context, AttributeSet attrs) {
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RelativeLayout);
+    private void initFromAttributes(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.RelativeLayout, defStyleAttr, defStyleRes);
         mIgnoreGravity = a.getResourceId(R.styleable.RelativeLayout_ignoreGravity, View.NO_ID);
         mGravity = a.getInt(R.styleable.RelativeLayout_gravity, mGravity);
         a.recycle();
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 3ff0cee..bbe6f9e 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -32,7 +32,6 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
@@ -45,7 +44,6 @@
 
 import com.android.internal.widget.IRemoteViewsAdapterConnection;
 import com.android.internal.widget.IRemoteViewsFactory;
-import com.android.internal.widget.LockPatternUtils;
 
 /**
  * An adapter to a RemoteViewsService which fetches and caches RemoteViews
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 6680393..082d728 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -162,12 +162,16 @@
         this(context, attrs, com.android.internal.R.attr.scrollViewStyle);
     }
 
-    public ScrollView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initScrollView();
 
-        TypedArray a =
-            context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.ScrollView, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ScrollView, defStyleAttr, defStyleRes);
 
         setFillViewport(a.getBoolean(R.styleable.ScrollView_fillViewport, false));
 
diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java
index 3bfd39d..1a0ce9c 100644
--- a/core/java/android/widget/Scroller.java
+++ b/core/java/android/widget/Scroller.java
@@ -61,6 +61,8 @@
  * }</pre>
  */
 public class Scroller  {
+    private final Interpolator mInterpolator;
+
     private int mMode;
 
     private int mStartX;
@@ -81,7 +83,6 @@
     private float mDeltaX;
     private float mDeltaY;
     private boolean mFinished;
-    private Interpolator mInterpolator;
     private boolean mFlywheel;
 
     private float mVelocity;
@@ -142,18 +143,8 @@
             SPLINE_TIME[i] = coef * ((1.0f - y) * P1 + y * P2) + y * y * y;
         }
         SPLINE_POSITION[NB_SAMPLES] = SPLINE_TIME[NB_SAMPLES] = 1.0f;
-
-        // This controls the viscous fluid effect (how much of it)
-        sViscousFluidScale = 8.0f;
-        // must be set to 1.0 (used in viscousFluid())
-        sViscousFluidNormalize = 1.0f;
-        sViscousFluidNormalize = 1.0f / viscousFluid(1.0f);
-
     }
 
-    private static float sViscousFluidScale;
-    private static float sViscousFluidNormalize;
-
     /**
      * Create a Scroller with the default duration and interpolator.
      */
@@ -178,7 +169,11 @@
      */
     public Scroller(Context context, Interpolator interpolator, boolean flywheel) {
         mFinished = true;
-        mInterpolator = interpolator;
+        if (interpolator == null) {
+            mInterpolator = new ViscousFluidInterpolator();
+        } else {
+            mInterpolator = interpolator;
+        }
         mPpi = context.getResources().getDisplayMetrics().density * 160.0f;
         mDeceleration = computeDeceleration(ViewConfiguration.getScrollFriction());
         mFlywheel = flywheel;
@@ -312,13 +307,7 @@
         if (timePassed < mDuration) {
             switch (mMode) {
             case SCROLL_MODE:
-                float x = timePassed * mDurationReciprocal;
-    
-                if (mInterpolator == null)
-                    x = viscousFluid(x); 
-                else
-                    x = mInterpolator.getInterpolation(x);
-    
+                final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal);
                 mCurrX = mStartX + Math.round(x * mDeltaX);
                 mCurrY = mStartY + Math.round(x * mDeltaY);
                 break;
@@ -499,20 +488,6 @@
         return mFlingFriction * mPhysicalCoeff * Math.exp(DECELERATION_RATE / decelMinusOne * l);
     }
 
-    static float viscousFluid(float x)
-    {
-        x *= sViscousFluidScale;
-        if (x < 1.0f) {
-            x -= (1.0f - (float)Math.exp(-x));
-        } else {
-            float start = 0.36787944117f;   // 1/e == exp(-1)
-            x = 1.0f - (float)Math.exp(1.0f - x);
-            x = start + x * (1.0f - start);
-        }
-        x *= sViscousFluidNormalize;
-        return x;
-    }
-    
     /**
      * Stops the animation. Contrary to {@link #forceFinished(boolean)},
      * aborting the animating cause the scroller to move to the final x and y
@@ -583,4 +558,41 @@
         return !mFinished && Math.signum(xvel) == Math.signum(mFinalX - mStartX) &&
                 Math.signum(yvel) == Math.signum(mFinalY - mStartY);
     }
+
+    static class ViscousFluidInterpolator implements Interpolator {
+        /** Controls the viscous fluid effect (how much of it). */
+        private static final float VISCOUS_FLUID_SCALE = 8.0f;
+
+        private static final float VISCOUS_FLUID_NORMALIZE;
+        private static final float VISCOUS_FLUID_OFFSET;
+
+        static {
+
+            // must be set to 1.0 (used in viscousFluid())
+            VISCOUS_FLUID_NORMALIZE = 1.0f / viscousFluid(1.0f);
+            // account for very small floating-point error
+            VISCOUS_FLUID_OFFSET = 1.0f - VISCOUS_FLUID_NORMALIZE * viscousFluid(1.0f);
+        }
+
+        private static float viscousFluid(float x) {
+            x *= VISCOUS_FLUID_SCALE;
+            if (x < 1.0f) {
+                x -= (1.0f - (float)Math.exp(-x));
+            } else {
+                float start = 0.36787944117f;   // 1/e == exp(-1)
+                x = 1.0f - (float)Math.exp(1.0f - x);
+                x = start + x * (1.0f - start);
+            }
+            return x;
+        }
+
+        @Override
+        public float getInterpolation(float input) {
+            final float interpolated = VISCOUS_FLUID_NORMALIZE * viscousFluid(input);
+            if (input > 0) {
+                return input + VISCOUS_FLUID_OFFSET;
+            }
+            return input;
+        }
+    }
 }
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 0281602..3791258 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -242,7 +242,15 @@
     }
 
     public SearchView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
+    }
+
+    public SearchView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public SearchView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         LayoutInflater inflater = (LayoutInflater) context
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -281,7 +289,8 @@
             }
         });
 
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SearchView, 0, 0);
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.SearchView, defStyleAttr, defStyleRes);
         setIconifiedByDefault(a.getBoolean(R.styleable.SearchView_iconifiedByDefault, true));
         int maxWidth = a.getDimensionPixelSize(R.styleable.SearchView_maxWidth, -1);
         if (maxWidth != -1) {
@@ -304,7 +313,7 @@
 
         boolean focusable = true;
 
-        a = context.obtainStyledAttributes(attrs, R.styleable.View, 0, 0);
+        a = context.obtainStyledAttributes(attrs, R.styleable.View, defStyleAttr, defStyleRes);
         focusable = a.getBoolean(R.styleable.View_focusable, focusable);
         a.recycle();
         setFocusable(focusable);
@@ -1661,8 +1670,14 @@
             mThreshold = getThreshold();
         }
 
-        public SearchAutoComplete(Context context, AttributeSet attrs, int defStyle) {
-            super(context, attrs, defStyle);
+        public SearchAutoComplete(Context context, AttributeSet attrs, int defStyleAttrs) {
+            super(context, attrs, defStyleAttrs);
+            mThreshold = getThreshold();
+        }
+
+        public SearchAutoComplete(
+                Context context, AttributeSet attrs, int defStyleAttrs, int defStyleRes) {
+            super(context, attrs, defStyleAttrs, defStyleRes);
             mThreshold = getThreshold();
         }
 
diff --git a/core/java/android/widget/SeekBar.java b/core/java/android/widget/SeekBar.java
index 2737f94..dc7c04c 100644
--- a/core/java/android/widget/SeekBar.java
+++ b/core/java/android/widget/SeekBar.java
@@ -79,8 +79,12 @@
         this(context, attrs, com.android.internal.R.attr.seekBarStyle);
     }
 
-    public SeekBar(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public SeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public SeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
diff --git a/core/java/android/widget/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java
index 62afd2e..bdaaa01 100644
--- a/core/java/android/widget/ShareActionProvider.java
+++ b/core/java/android/widget/ShareActionProvider.java
@@ -266,7 +266,7 @@
      * Intent shareIntent = new Intent(Intent.ACTION_SEND);
      * shareIntent.setType("image/*");
      * Uri uri = Uri.fromFile(new File(getFilesDir(), "foo.jpg"));
-     * shareIntent.putExtra(Intent.EXTRA_STREAM, uri.toString());</pre>
+     * shareIntent.putExtra(Intent.EXTRA_STREAM, uri));</pre>
      *
      * @param shareIntent The share intent.
      *
diff --git a/core/java/android/widget/SlidingDrawer.java b/core/java/android/widget/SlidingDrawer.java
index 517246b..ec06c02 100644
--- a/core/java/android/widget/SlidingDrawer.java
+++ b/core/java/android/widget/SlidingDrawer.java
@@ -192,11 +192,32 @@
      *
      * @param context The application's environment.
      * @param attrs The attributes defined in XML.
-     * @param defStyle The style to apply to this widget.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public SlidingDrawer(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlidingDrawer, defStyle, 0);
+    public SlidingDrawer(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * Creates a new SlidingDrawer from a specified set of attributes defined in XML.
+     *
+     * @param context The application's environment.
+     * @param attrs The attributes defined in XML.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     */
+    public SlidingDrawer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.SlidingDrawer, defStyleAttr, defStyleRes);
 
         int orientation = a.getInt(R.styleable.SlidingDrawer_orientation, ORIENTATION_VERTICAL);
         mVertical = orientation == ORIENTATION_VERTICAL;
diff --git a/core/java/android/widget/Space.java b/core/java/android/widget/Space.java
index bb53a77..c4eaeb7 100644
--- a/core/java/android/widget/Space.java
+++ b/core/java/android/widget/Space.java
@@ -20,7 +20,6 @@
 import android.graphics.Canvas;
 import android.util.AttributeSet;
 import android.view.View;
-import android.view.ViewGroup;
 
 /**
  * Space is a lightweight View subclass that may be used to create gaps between components
@@ -30,8 +29,8 @@
     /**
      * {@inheritDoc}
      */
-    public Space(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public Space(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         if (getVisibility() == VISIBLE) {
             setVisibility(INVISIBLE);
         }
@@ -40,6 +39,13 @@
     /**
      * {@inheritDoc}
      */
+    public Space(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public Space(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index b75d36f..afe5804 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -130,18 +130,17 @@
 
     /**
      * Construct a new spinner with the given context's theme, the supplied attribute set,
-     * and default style.
+     * and default style attribute.
      *
      * @param context The Context the view is running in, through which it can
      *        access the current theme, resources, etc.
      * @param attrs The attributes of the XML tag that is inflating the view.
-     * @param defStyle The default style to apply to this view. If 0, no style
-     *        will be applied (beyond what is included in the theme). This may
-     *        either be an attribute resource, whose value will be retrieved
-     *        from the current theme, or an explicit style resource.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public Spinner(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, MODE_THEME);
+    public Spinner(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0, MODE_THEME);
     }
 
     /**
@@ -152,20 +151,44 @@
      * @param context The Context the view is running in, through which it can
      *        access the current theme, resources, etc.
      * @param attrs The attributes of the XML tag that is inflating the view.
-     * @param defStyle The default style to apply to this view. If 0, no style
-     *        will be applied (beyond what is included in the theme). This may
-     *        either be an attribute resource, whose value will be retrieved
-     *        from the current theme, or an explicit style resource.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      * @param mode Constant describing how the user will select choices from the spinner.
-     * 
+     *
      * @see #MODE_DIALOG
      * @see #MODE_DROPDOWN
      */
-    public Spinner(Context context, AttributeSet attrs, int defStyle, int mode) {
-        super(context, attrs, defStyle);
+    public Spinner(Context context, AttributeSet attrs, int defStyleAttr, int mode) {
+        this(context, attrs, defStyleAttr, 0, mode);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.Spinner, defStyle, 0);
+    /**
+     * Construct a new spinner with the given context's theme, the supplied attribute set,
+     * and default style. <code>mode</code> may be one of {@link #MODE_DIALOG} or
+     * {@link #MODE_DROPDOWN} and determines how the user will select choices from the spinner.
+     *
+     * @param context The Context the view is running in, through which it can
+     *        access the current theme, resources, etc.
+     * @param attrs The attributes of the XML tag that is inflating the view.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     * @param mode Constant describing how the user will select choices from the spinner.
+     *
+     * @see #MODE_DIALOG
+     * @see #MODE_DROPDOWN
+     */
+    public Spinner(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes, int mode) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.Spinner, defStyleAttr, defStyleRes);
 
         if (mode == MODE_THEME) {
             mode = a.getInt(com.android.internal.R.styleable.Spinner_spinnerMode, MODE_DIALOG);
@@ -178,7 +201,7 @@
         }
 
         case MODE_DROPDOWN: {
-            final DropdownPopup popup = new DropdownPopup(context, attrs, defStyle);
+            final DropdownPopup popup = new DropdownPopup(context, attrs, defStyleAttr, defStyleRes);
 
             mDropDownWidth = a.getLayoutDimension(
                     com.android.internal.R.styleable.Spinner_dropDownWidth,
@@ -1031,8 +1054,9 @@
         private CharSequence mHintText;
         private ListAdapter mAdapter;
 
-        public DropdownPopup(Context context, AttributeSet attrs, int defStyleRes) {
-            super(context, attrs, 0, defStyleRes);
+        public DropdownPopup(
+                Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+            super(context, attrs, defStyleAttr, defStyleRes);
 
             setAnchorView(Spinner.this);
             setModal(true);
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 6853660..d2e718c 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -168,9 +168,16 @@
      * {@inheritDoc}
      */
     public StackView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.StackView, defStyleAttr, 0);
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public StackView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.StackView, defStyleAttr, defStyleRes);
 
         mResOutColor = a.getColor(
                 com.android.internal.R.styleable.StackView_resOutColor, 0);
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index e754c17..c9a1ca4 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -32,6 +33,8 @@
 import android.text.method.AllCapsTransformationMethod;
 import android.text.method.TransformationMethod2;
 import android.util.AttributeSet;
+import android.util.FloatProperty;
+import android.util.MathUtils;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
@@ -66,6 +69,8 @@
  * @attr ref android.R.styleable#Switch_track
  */
 public class Switch extends CompoundButton {
+    private static final int THUMB_ANIMATION_DURATION = 250;
+
     private static final int TOUCH_MODE_IDLE = 0;
     private static final int TOUCH_MODE_DOWN = 1;
     private static final int TOUCH_MODE_DRAGGING = 2;
@@ -105,6 +110,7 @@
     private Layout mOnLayout;
     private Layout mOffLayout;
     private TransformationMethod2 mSwitchTransformationMethod;
+    private ObjectAnimator mPositionAnimator;
 
     @SuppressWarnings("hiding")
     private final Rect mTempRect = new Rect();
@@ -139,19 +145,41 @@
      *
      * @param context The Context that will determine this widget's theming.
      * @param attrs Specification of attributes that should deviate from the default styling.
-     * @param defStyle An attribute ID within the active theme containing a reference to the
-     *                 default style for this widget. e.g. android.R.attr.switchStyle.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public Switch(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public Switch(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+
+    /**
+     * Construct a new Switch with a default style determined by the given theme
+     * attribute or style resource, overriding specific style attributes as
+     * requested.
+     *
+     * @param context The Context that will determine this widget's theming.
+     * @param attrs Specification of attributes that should deviate from the
+     *        default styling.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     */
+    public Switch(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
         Resources res = getResources();
         mTextPaint.density = res.getDisplayMetrics().density;
         mTextPaint.setCompatibilityScaling(res.getCompatibilityInfo().applicationScale);
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.Switch, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.Switch, defStyleAttr, defStyleRes);
 
         mThumbDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_thumb);
         mTrackDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_track);
@@ -528,9 +556,12 @@
      * @return true if (x, y) is within the target area of the switch thumb
      */
     private boolean hitThumb(float x, float y) {
+        // Relies on mTempRect, MUST be called first!
+        final int thumbOffset = getThumbOffset();
+
         mThumbDrawable.getPadding(mTempRect);
         final int thumbTop = mSwitchTop - mTouchSlop;
-        final int thumbLeft = mSwitchLeft + (int) (mThumbPosition + 0.5f) - mTouchSlop;
+        final int thumbLeft = mSwitchLeft + thumbOffset - mTouchSlop;
         final int thumbRight = thumbLeft + mThumbWidth +
                 mTempRect.left + mTempRect.right + mTouchSlop;
         final int thumbBottom = mSwitchBottom + mTouchSlop;
@@ -575,13 +606,23 @@
 
                     case TOUCH_MODE_DRAGGING: {
                         final float x = ev.getX();
-                        final float dx = x - mTouchX;
-                        float newPos = Math.max(0,
-                                Math.min(mThumbPosition + dx, getThumbScrollRange()));
+                        final int thumbScrollRange = getThumbScrollRange();
+                        final float thumbScrollOffset = x - mTouchX;
+                        float dPos;
+                        if (thumbScrollRange != 0) {
+                            dPos = thumbScrollOffset / thumbScrollRange;
+                        } else {
+                            // If the thumb scroll range is empty, just use the
+                            // movement direction to snap on or off.
+                            dPos = thumbScrollOffset > 0 ? 1 : -1;
+                        }
+                        if (isLayoutRtl()) {
+                            dPos = -dPos;
+                        }
+                        final float newPos = MathUtils.constrain(mThumbPosition + dPos, 0, 1);
                         if (newPos != mThumbPosition) {
-                            mThumbPosition = newPos;
                             mTouchX = x;
-                            invalidate();
+                            setThumbPosition(newPos);
                         }
                         return true;
                     }
@@ -618,62 +659,77 @@
      */
     private void stopDrag(MotionEvent ev) {
         mTouchMode = TOUCH_MODE_IDLE;
-        // Up and not canceled, also checks the switch has not been disabled during the drag
-        boolean commitChange = ev.getAction() == MotionEvent.ACTION_UP && isEnabled();
 
-        cancelSuperTouch(ev);
-
+        // Commit the change if the event is up and not canceled and the switch
+        // has not been disabled during the drag.
+        final boolean commitChange = ev.getAction() == MotionEvent.ACTION_UP && isEnabled();
+        final boolean newState;
         if (commitChange) {
-            boolean newState;
             mVelocityTracker.computeCurrentVelocity(1000);
-            float xvel = mVelocityTracker.getXVelocity();
+            final float xvel = mVelocityTracker.getXVelocity();
             if (Math.abs(xvel) > mMinFlingVelocity) {
                 newState = isLayoutRtl() ? (xvel < 0) : (xvel > 0);
             } else {
                 newState = getTargetCheckedState();
             }
-            animateThumbToCheckedState(newState);
         } else {
-            animateThumbToCheckedState(isChecked());
+            newState = isChecked();
         }
+
+        setChecked(newState);
+        cancelSuperTouch(ev);
     }
 
     private void animateThumbToCheckedState(boolean newCheckedState) {
-        // TODO animate!
-        //float targetPos = newCheckedState ? 0 : getThumbScrollRange();
-        //mThumbPosition = targetPos;
-        setChecked(newCheckedState);
+        final float targetPosition = newCheckedState ? 1 : 0;
+        mPositionAnimator = ObjectAnimator.ofFloat(this, THUMB_POS, targetPosition);
+        mPositionAnimator.setDuration(THUMB_ANIMATION_DURATION);
+        mPositionAnimator.setAutoCancel(true);
+        mPositionAnimator.start();
+    }
+
+    private void cancelPositionAnimator() {
+        if (mPositionAnimator != null) {
+            mPositionAnimator.cancel();
+        }
     }
 
     private boolean getTargetCheckedState() {
-        if (isLayoutRtl()) {
-            return mThumbPosition <= getThumbScrollRange() / 2;
-        } else {
-            return mThumbPosition >= getThumbScrollRange() / 2;
-        }
+        return mThumbPosition > 0.5f;
     }
 
-    private void setThumbPosition(boolean checked) {
-        if (isLayoutRtl()) {
-            mThumbPosition = checked ? 0 : getThumbScrollRange();
-        } else {
-            mThumbPosition = checked ? getThumbScrollRange() : 0;
-        }
+    /**
+     * Sets the thumb position as a decimal value between 0 (off) and 1 (on).
+     *
+     * @param position new position between [0,1]
+     */
+    private void setThumbPosition(float position) {
+        mThumbPosition = position;
+        invalidate();
+    }
+
+    @Override
+    public void toggle() {
+        setChecked(!isChecked());
     }
 
     @Override
     public void setChecked(boolean checked) {
         super.setChecked(checked);
-        setThumbPosition(isChecked());
-        invalidate();
+
+        if (isAttachedToWindow() && isLaidOut()) {
+            animateThumbToCheckedState(checked);
+        } else {
+            // Immediately move the thumb to the new position.
+            cancelPositionAnimator();
+            setThumbPosition(checked ? 1 : 0);
+        }
     }
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
 
-        setThumbPosition(isChecked());
-
         int switchRight;
         int switchLeft;
 
@@ -734,11 +790,12 @@
         int switchInnerBottom = switchBottom - mTempRect.bottom;
         canvas.clipRect(switchInnerLeft, switchTop, switchInnerRight, switchBottom);
 
+        // Relies on mTempRect, MUST be called first!
+        final int thumbPos = getThumbOffset();
+
         mThumbDrawable.getPadding(mTempRect);
-        final int thumbPos = (int) (mThumbPosition + 0.5f);
         int thumbLeft = switchInnerLeft - mTempRect.left + thumbPos;
         int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + mTempRect.right;
-
         mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);
         mThumbDrawable.draw(canvas);
 
@@ -783,6 +840,22 @@
         return padding;
     }
 
+    /**
+     * Translates thumb position to offset according to current RTL setting and
+     * thumb scroll range.
+     *
+     * @return thumb offset
+     */
+    private int getThumbOffset() {
+        final float thumbPosition;
+        if (isLayoutRtl()) {
+            thumbPosition = 1 - mThumbPosition;
+        } else {
+            thumbPosition = mThumbPosition;
+        }
+        return (int) (thumbPosition * getThumbScrollRange() + 0.5f);
+    }
+
     private int getThumbScrollRange() {
         if (mTrackDrawable == null) {
             return 0;
@@ -848,4 +921,16 @@
             }
         }
     }
+
+    private static final FloatProperty<Switch> THUMB_POS = new FloatProperty<Switch>("thumbPos") {
+        @Override
+        public Float get(Switch object) {
+            return object.mThumbPosition;
+        }
+
+        @Override
+        public void setValue(Switch object, float value) {
+            object.setThumbPosition(value);
+        }
+    };
 }
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 238dc55..89df51a 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -77,11 +77,18 @@
     }
 
     public TabHost(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.tabWidgetStyle);
+    }
+
+    public TabHost(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public TabHost(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs);
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.TabWidget,
-                com.android.internal.R.attr.tabWidgetStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.TabWidget, defStyleAttr, defStyleRes);
 
         mTabLayoutId = a.getResourceId(R.styleable.TabWidget_tabLayout, 0);
         a.recycle();
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 6bced1c..568b3e6a 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -74,11 +74,15 @@
         this(context, attrs, com.android.internal.R.attr.tabWidgetStyle);
     }
 
-    public TabWidget(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TabWidget(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public TabWidget(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         final TypedArray a = context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.TabWidget, defStyle, 0);
+                attrs, com.android.internal.R.styleable.TabWidget, defStyleAttr, defStyleRes);
 
         setStripEnabled(a.getBoolean(R.styleable.TabWidget_tabStripEnabled, true));
         setLeftStripDrawable(a.getDrawable(R.styleable.TabWidget_tabStripLeft));
diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java
index b3b95d9..4c5c71d 100644
--- a/core/java/android/widget/TextClock.java
+++ b/core/java/android/widget/TextClock.java
@@ -198,15 +198,19 @@
      * @param context The Context the view is running in, through which it can
      *        access the current theme, resources, etc.
      * @param attrs The attributes of the XML tag that is inflating the view
-     * @param defStyle The default style to apply to this view. If 0, no style
-     *        will be applied (beyond what is included in the theme). This may
-     *        either be an attribute resource, whose value will be retrieved
-     *        from the current theme, or an explicit style resource
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public TextClock(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TextClock(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextClock, defStyle, 0);
+    public TextClock(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.TextClock, defStyleAttr, defStyleRes);
         try {
             mFormat12 = a.getText(R.styleable.TextClock_format12Hour);
             mFormat24 = a.getText(R.styleable.TextClock_format24Hour);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 7a9809f..5d42589 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -136,7 +136,6 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Locale;
-import java.util.concurrent.locks.ReentrantLock;
 
 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
 
@@ -618,9 +617,14 @@
         this(context, attrs, com.android.internal.R.attr.textViewStyle);
     }
 
+    public TextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     @SuppressWarnings("deprecation")
-    public TextView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
         mText = "";
 
         final Resources res = getResources();
@@ -657,8 +661,8 @@
          * to be able to parse the appearance first and then let specific tags
          * for this View override it.
          */
-        TypedArray a = theme.obtainStyledAttributes(
-                    attrs, com.android.internal.R.styleable.TextViewAppearance, defStyle, 0);
+        TypedArray a = theme.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.TextViewAppearance, defStyleAttr, defStyleRes);
         TypedArray appearance = null;
         int ap = a.getResourceId(
                 com.android.internal.R.styleable.TextViewAppearance_textAppearance, -1);
@@ -751,7 +755,7 @@
         int inputType = EditorInfo.TYPE_NULL;
 
         a = theme.obtainStyledAttributes(
-                    attrs, com.android.internal.R.styleable.TextView, defStyle, 0);
+                    attrs, com.android.internal.R.styleable.TextView, defStyleAttr, defStyleRes);
 
         int n = a.getIndexCount();
         for (int i = 0; i < n; i++) {
@@ -1275,9 +1279,8 @@
          * However, TextViews that have input or movement methods *are*
          * focusable by default.
          */
-        a = context.obtainStyledAttributes(attrs,
-                                           com.android.internal.R.styleable.View,
-                                           defStyle, 0);
+        a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
 
         boolean focusable = mMovement != null || getKeyListener() != null;
         boolean clickable = focusable;
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index c26cb24..8e4ba0d 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -20,26 +20,17 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
-import android.os.Parcel;
 import android.os.Parcelable;
-import android.text.format.DateFormat;
-import android.text.format.DateUtils;
 import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.NumberPicker.OnValueChangeListener;
 
 import com.android.internal.R;
 
-import java.text.DateFormatSymbols;
-import java.util.Calendar;
 import java.util.Locale;
 
+import static android.os.Build.VERSION_CODES.KITKAT;
+
 /**
  * A view for selecting the time of day, in either 24 hour or AM/PM mode. The
  * hour, each minute digit, and AM/PM (if applicable) can be conrolled by
@@ -57,58 +48,12 @@
 @Widget
 public class TimePicker extends FrameLayout {
 
-    private static final boolean DEFAULT_ENABLED_STATE = true;
+    private TimePickerDelegate mDelegate;
 
-    private static final int HOURS_IN_HALF_DAY = 12;
-
-    /**
-     * A no-op callback used in the constructor to avoid null checks later in
-     * the code.
-     */
-    private static final OnTimeChangedListener NO_OP_CHANGE_LISTENER = new OnTimeChangedListener() {
-        public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
-        }
-    };
-
-    // state
-    private boolean mIs24HourView;
-
-    private boolean mIsAm;
-
-    // ui components
-    private final NumberPicker mHourSpinner;
-
-    private final NumberPicker mMinuteSpinner;
-
-    private final NumberPicker mAmPmSpinner;
-
-    private final EditText mHourSpinnerInput;
-
-    private final EditText mMinuteSpinnerInput;
-
-    private final EditText mAmPmSpinnerInput;
-
-    private final TextView mDivider;
-
-    // Note that the legacy implementation of the TimePicker is
-    // using a button for toggling between AM/PM while the new
-    // version uses a NumberPicker spinner. Therefore the code
-    // accommodates these two cases to be backwards compatible.
-    private final Button mAmPmButton;
-
-    private final String[] mAmPmStrings;
-
-    private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
-
-    // callbacks
-    private OnTimeChangedListener mOnTimeChangedListener;
-
-    private Calendar mTempCalendar;
-
-    private Locale mCurrentLocale;
-
-    private boolean mHourWithTwoDigit;
-    private char mHourFormat;
+    private AttributeSet mAttrs;
+    private int mDefStyleAttr;
+    private int mDefStyleRes;
+    private Context mContext;
 
     /**
      * The callback interface used to indicate the time has been adjusted.
@@ -131,345 +76,79 @@
         this(context, attrs, R.attr.timePickerStyle);
     }
 
-    public TimePicker(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        // initialization based on locale
-        setCurrentLocale(Locale.getDefault());
-
-        // process style attributes
-        TypedArray attributesArray = context.obtainStyledAttributes(
-                attrs, R.styleable.TimePicker, defStyle, 0);
-        int layoutResourceId = attributesArray.getResourceId(
-                R.styleable.TimePicker_internalLayout, R.layout.time_picker);
-        attributesArray.recycle();
-
-        LayoutInflater inflater = (LayoutInflater) context.getSystemService(
-                Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(layoutResourceId, this, true);
-
-        // hour
-        mHourSpinner = (NumberPicker) findViewById(R.id.hour);
-        mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
-            public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
-                updateInputState();
-                if (!is24HourView()) {
-                    if ((oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY)
-                            || (oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1)) {
-                        mIsAm = !mIsAm;
-                        updateAmPmControl();
-                    }
-                }
-                onTimeChanged();
-            }
-        });
-        mHourSpinnerInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input);
-        mHourSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
-
-        // divider (only for the new widget style)
-        mDivider = (TextView) findViewById(R.id.divider);
-        if (mDivider != null) {
-            setDividerText();
-        }
-
-        // minute
-        mMinuteSpinner = (NumberPicker) findViewById(R.id.minute);
-        mMinuteSpinner.setMinValue(0);
-        mMinuteSpinner.setMaxValue(59);
-        mMinuteSpinner.setOnLongPressUpdateInterval(100);
-        mMinuteSpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
-        mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
-            public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
-                updateInputState();
-                int minValue = mMinuteSpinner.getMinValue();
-                int maxValue = mMinuteSpinner.getMaxValue();
-                if (oldVal == maxValue && newVal == minValue) {
-                    int newHour = mHourSpinner.getValue() + 1;
-                    if (!is24HourView() && newHour == HOURS_IN_HALF_DAY) {
-                        mIsAm = !mIsAm;
-                        updateAmPmControl();
-                    }
-                    mHourSpinner.setValue(newHour);
-                } else if (oldVal == minValue && newVal == maxValue) {
-                    int newHour = mHourSpinner.getValue() - 1;
-                    if (!is24HourView() && newHour == HOURS_IN_HALF_DAY - 1) {
-                        mIsAm = !mIsAm;
-                        updateAmPmControl();
-                    }
-                    mHourSpinner.setValue(newHour);
-                }
-                onTimeChanged();
-            }
-        });
-        mMinuteSpinnerInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input);
-        mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
-
-        /* Get the localized am/pm strings and use them in the spinner */
-        mAmPmStrings = new DateFormatSymbols().getAmPmStrings();
-
-        // am/pm
-        View amPmView = findViewById(R.id.amPm);
-        if (amPmView instanceof Button) {
-            mAmPmSpinner = null;
-            mAmPmSpinnerInput = null;
-            mAmPmButton = (Button) amPmView;
-            mAmPmButton.setOnClickListener(new OnClickListener() {
-                public void onClick(View button) {
-                    button.requestFocus();
-                    mIsAm = !mIsAm;
-                    updateAmPmControl();
-                    onTimeChanged();
-                }
-            });
-        } else {
-            mAmPmButton = null;
-            mAmPmSpinner = (NumberPicker) amPmView;
-            mAmPmSpinner.setMinValue(0);
-            mAmPmSpinner.setMaxValue(1);
-            mAmPmSpinner.setDisplayedValues(mAmPmStrings);
-            mAmPmSpinner.setOnValueChangedListener(new OnValueChangeListener() {
-                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
-                    updateInputState();
-                    picker.requestFocus();
-                    mIsAm = !mIsAm;
-                    updateAmPmControl();
-                    onTimeChanged();
-                }
-            });
-            mAmPmSpinnerInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input);
-            mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
-        }
-
-        if (isAmPmAtStart()) {
-            // Move the am/pm view to the beginning
-            ViewGroup amPmParent = (ViewGroup) findViewById(R.id.timePickerLayout);
-            amPmParent.removeView(amPmView);
-            amPmParent.addView(amPmView, 0);
-            // Swap layout margins if needed. They may be not symmetrical (Old Standard Theme for
-            // example and not for Holo Theme)
-            ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) amPmView.getLayoutParams();
-            final int startMargin = lp.getMarginStart();
-            final int endMargin = lp.getMarginEnd();
-            if (startMargin != endMargin) {
-                lp.setMarginStart(endMargin);
-                lp.setMarginEnd(startMargin);
-            }
-        }
-
-        getHourFormatData();
-
-        // update controls to initial state
-        updateHourControl();
-        updateMinuteControl();
-        updateAmPmControl();
-
-        setOnTimeChangedListener(NO_OP_CHANGE_LISTENER);
-
-        // set to current time
-        setCurrentHour(mTempCalendar.get(Calendar.HOUR_OF_DAY));
-        setCurrentMinute(mTempCalendar.get(Calendar.MINUTE));
-
-        if (!isEnabled()) {
-            setEnabled(false);
-        }
-
-        // set the content descriptions
-        setContentDescriptions();
-
-        // If not explicitly specified this view is important for accessibility.
-        if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
-            setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
-        }
+    public TimePicker(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
-    private void getHourFormatData() {
-        final Locale defaultLocale = Locale.getDefault();
-        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale,
-                (mIs24HourView) ? "Hm" : "hm");
-        final int lengthPattern = bestDateTimePattern.length();
-        mHourWithTwoDigit = false;
-        char hourFormat = '\0';
-        // Check if the returned pattern is single or double 'H', 'h', 'K', 'k'. We also save
-        // the hour format that we found.
-        for (int i = 0; i < lengthPattern; i++) {
-            final char c = bestDateTimePattern.charAt(i);
-            if (c == 'H' || c == 'h' || c == 'K' || c == 'k') {
-                mHourFormat = c;
-                if (i + 1 < lengthPattern && c == bestDateTimePattern.charAt(i + 1)) {
-                    mHourWithTwoDigit = true;
-                }
-                break;
-            }
-        }
+    public TimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        mContext = context;
+        mAttrs = attrs;
+        mDefStyleAttr = defStyleAttr;
+        mDefStyleRes = defStyleRes;
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TimePicker,
+                mDefStyleAttr, mDefStyleRes);
+
+        // Create the correct UI delegate. Default is the legacy one.
+        final boolean isLegacyMode = shouldForceLegacyMode() ?
+                true : a.getBoolean(R.styleable.TimePicker_legacyMode, true);
+        setLegacyMode(isLegacyMode);
     }
 
-    private boolean isAmPmAtStart() {
-        final Locale defaultLocale = Locale.getDefault();
-        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale,
-                "hm" /* skeleton */);
-
-        return bestDateTimePattern.startsWith("a");
+    private boolean shouldForceLegacyMode() {
+        final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
+        return targetSdkVersion < KITKAT;
     }
 
-    @Override
-    public void setEnabled(boolean enabled) {
-        if (mIsEnabled == enabled) {
-            return;
-        }
-        super.setEnabled(enabled);
-        mMinuteSpinner.setEnabled(enabled);
-        if (mDivider != null) {
-            mDivider.setEnabled(enabled);
-        }
-        mHourSpinner.setEnabled(enabled);
-        if (mAmPmSpinner != null) {
-            mAmPmSpinner.setEnabled(enabled);
-        } else {
-            mAmPmButton.setEnabled(enabled);
-        }
-        mIsEnabled = enabled;
+    private TimePickerDelegate createLegacyUIDelegate(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        return new LegacyTimePickerDelegate(this, context, attrs, defStyleAttr, defStyleRes);
     }
 
-    @Override
-    public boolean isEnabled() {
-        return mIsEnabled;
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        setCurrentLocale(newConfig.locale);
+    private TimePickerDelegate createNewUIDelegate(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        return new android.widget.TimePickerDelegate(this, context, attrs, defStyleAttr,
+                defStyleRes);
     }
 
     /**
-     * Sets the current locale.
-     *
-     * @param locale The current locale.
+     * @hide
      */
-    private void setCurrentLocale(Locale locale) {
-        if (locale.equals(mCurrentLocale)) {
-            return;
-        }
-        mCurrentLocale = locale;
-        mTempCalendar = Calendar.getInstance(locale);
-    }
-
-    /**
-     * Used to save / restore state of time picker
-     */
-    private static class SavedState extends BaseSavedState {
-
-        private final int mHour;
-
-        private final int mMinute;
-
-        private SavedState(Parcelable superState, int hour, int minute) {
-            super(superState);
-            mHour = hour;
-            mMinute = minute;
-        }
-
-        private SavedState(Parcel in) {
-            super(in);
-            mHour = in.readInt();
-            mMinute = in.readInt();
-        }
-
-        public int getHour() {
-            return mHour;
-        }
-
-        public int getMinute() {
-            return mMinute;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            super.writeToParcel(dest, flags);
-            dest.writeInt(mHour);
-            dest.writeInt(mMinute);
-        }
-
-        @SuppressWarnings({"unused", "hiding"})
-        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
-            public SavedState createFromParcel(Parcel in) {
-                return new SavedState(in);
-            }
-
-            public SavedState[] newArray(int size) {
-                return new SavedState[size];
-            }
-        };
-    }
-
-    @Override
-    protected Parcelable onSaveInstanceState() {
-        Parcelable superState = super.onSaveInstanceState();
-        return new SavedState(superState, getCurrentHour(), getCurrentMinute());
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Parcelable state) {
-        SavedState ss = (SavedState) state;
-        super.onRestoreInstanceState(ss.getSuperState());
-        setCurrentHour(ss.getHour());
-        setCurrentMinute(ss.getMinute());
-    }
-
-    /**
-     * Set the callback that indicates the time has been adjusted by the user.
-     *
-     * @param onTimeChangedListener the callback, should not be null.
-     */
-    public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) {
-        mOnTimeChangedListener = onTimeChangedListener;
-    }
-
-    /**
-     * @return The current hour in the range (0-23).
-     */
-    public Integer getCurrentHour() {
-        int currentHour = mHourSpinner.getValue();
-        if (is24HourView()) {
-            return currentHour;
-        } else if (mIsAm) {
-            return currentHour % HOURS_IN_HALF_DAY;
-        } else {
-            return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY;
-        }
+    public void setLegacyMode(boolean isLegacyMode) {
+        removeAllViewsInLayout();
+        mDelegate = isLegacyMode ?
+                createLegacyUIDelegate(mContext, mAttrs, mDefStyleAttr, mDefStyleRes) :
+                createNewUIDelegate(mContext, mAttrs, mDefStyleAttr, mDefStyleRes);
     }
 
     /**
      * Set the current hour.
      */
     public void setCurrentHour(Integer currentHour) {
-        setCurrentHour(currentHour, true);
+        mDelegate.setCurrentHour(currentHour);
     }
 
-    private void setCurrentHour(Integer currentHour, boolean notifyTimeChanged) {
-        // why was Integer used in the first place?
-        if (currentHour == null || currentHour == getCurrentHour()) {
-            return;
-        }
-        if (!is24HourView()) {
-            // convert [0,23] ordinal to wall clock display
-            if (currentHour >= HOURS_IN_HALF_DAY) {
-                mIsAm = false;
-                if (currentHour > HOURS_IN_HALF_DAY) {
-                    currentHour = currentHour - HOURS_IN_HALF_DAY;
-                }
-            } else {
-                mIsAm = true;
-                if (currentHour == 0) {
-                    currentHour = HOURS_IN_HALF_DAY;
-                }
-            }
-            updateAmPmControl();
-        }
-        mHourSpinner.setValue(currentHour);
-        if (notifyTimeChanged) {
-            onTimeChanged();
-        }
+    /**
+     * @return The current hour in the range (0-23).
+     */
+    public Integer getCurrentHour() {
+        return mDelegate.getCurrentHour();
+    }
+
+    /**
+     * Set the current minute (0-59).
+     */
+    public void setCurrentMinute(Integer currentMinute) {
+        mDelegate.setCurrentMinute(currentMinute);
+    }
+
+    /**
+     * @return The current minute.
+     */
+    public Integer getCurrentMinute() {
+        return mDelegate.getCurrentMinute();
     }
 
     /**
@@ -478,223 +157,174 @@
      * @param is24HourView True = 24 hour mode. False = AM/PM.
      */
     public void setIs24HourView(Boolean is24HourView) {
-        if (mIs24HourView == is24HourView) {
-            return;
-        }
-        // cache the current hour since spinner range changes and BEFORE changing mIs24HourView!!
-        int currentHour = getCurrentHour();
-        // Order is important here.
-        mIs24HourView = is24HourView;
-        getHourFormatData();
-        updateHourControl();
-        // set value after spinner range is updated - be aware that because mIs24HourView has
-        // changed then getCurrentHour() is not equal to the currentHour we cached before so
-        // explicitly ask for *not* propagating any onTimeChanged()
-        setCurrentHour(currentHour, false /* no onTimeChanged() */);
-        updateMinuteControl();
-        updateAmPmControl();
+        mDelegate.setIs24HourView(is24HourView);
     }
 
     /**
      * @return true if this is in 24 hour view else false.
      */
     public boolean is24HourView() {
-        return mIs24HourView;
+        return mDelegate.is24HourView();
     }
 
     /**
-     * @return The current minute.
+     * Set the callback that indicates the time has been adjusted by the user.
+     *
+     * @param onTimeChangedListener the callback, should not be null.
      */
-    public Integer getCurrentMinute() {
-        return mMinuteSpinner.getValue();
+    public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) {
+        mDelegate.setOnTimeChangedListener(onTimeChangedListener);
     }
 
-    /**
-     * Set the current minute (0-59).
-     */
-    public void setCurrentMinute(Integer currentMinute) {
-        if (currentMinute == getCurrentMinute()) {
+    @Override
+    public void setEnabled(boolean enabled) {
+        if (mDelegate.isEnabled() == enabled) {
             return;
         }
-        mMinuteSpinner.setValue(currentMinute);
-        onTimeChanged();
+        super.setEnabled(enabled);
+        mDelegate.setEnabled(enabled);
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return mDelegate.isEnabled();
     }
 
     /**
-     * The time separator is defined in the Unicode CLDR and cannot be supposed to be ":".
-     *
-     * See http://unicode.org/cldr/trac/browser/trunk/common/main
-     *
-     * We pass the correct "skeleton" depending on 12 or 24 hours view and then extract the
-     * separator as the character which is just after the hour marker in the returned pattern.
+     * @hide
      */
-    private void setDividerText() {
-        final Locale defaultLocale = Locale.getDefault();
-        final String skeleton = (mIs24HourView) ? "Hm" : "hm";
-        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale,
-                skeleton);
-        final String separatorText;
-        int hourIndex = bestDateTimePattern.lastIndexOf('H');
-        if (hourIndex == -1) {
-            hourIndex = bestDateTimePattern.lastIndexOf('h');
-        }
-        if (hourIndex == -1) {
-            // Default case
-            separatorText = ":";
-        } else {
-            int minuteIndex = bestDateTimePattern.indexOf('m', hourIndex + 1);
-            if  (minuteIndex == -1) {
-                separatorText = Character.toString(bestDateTimePattern.charAt(hourIndex + 1));
-            } else {
-                separatorText = bestDateTimePattern.substring(hourIndex + 1, minuteIndex);
-            }
-        }
-        mDivider.setText(separatorText);
+    public void setShowDoneButton(boolean showDoneButton) {
+        mDelegate.setShowDoneButton(showDoneButton);
+    }
+
+    /**
+     * @hide
+     */
+    public void setDismissCallback(TimePickerDismissCallback callback) {
+        mDelegate.setDismissCallback(callback);
     }
 
     @Override
     public int getBaseline() {
-        return mHourSpinner.getBaseline();
+        return mDelegate.getBaseline();
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mDelegate.onConfigurationChanged(newConfig);
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        Parcelable superState = super.onSaveInstanceState();
+        return mDelegate.onSaveInstanceState(superState);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        BaseSavedState ss = (BaseSavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        mDelegate.onRestoreInstanceState(ss);
     }
 
     @Override
     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        onPopulateAccessibilityEvent(event);
-        return true;
+        return mDelegate.dispatchPopulateAccessibilityEvent(event);
     }
 
     @Override
     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
         super.onPopulateAccessibilityEvent(event);
-
-        int flags = DateUtils.FORMAT_SHOW_TIME;
-        if (mIs24HourView) {
-            flags |= DateUtils.FORMAT_24HOUR;
-        } else {
-            flags |= DateUtils.FORMAT_12HOUR;
-        }
-        mTempCalendar.set(Calendar.HOUR_OF_DAY, getCurrentHour());
-        mTempCalendar.set(Calendar.MINUTE, getCurrentMinute());
-        String selectedDateUtterance = DateUtils.formatDateTime(mContext,
-                mTempCalendar.getTimeInMillis(), flags);
-        event.getText().add(selectedDateUtterance);
+        mDelegate.onPopulateAccessibilityEvent(event);
     }
 
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
-        event.setClassName(TimePicker.class.getName());
+        mDelegate.onInitializeAccessibilityEvent(event);
     }
 
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
-        info.setClassName(TimePicker.class.getName());
+        mDelegate.onInitializeAccessibilityNodeInfo(info);
     }
 
-    private void updateHourControl() {
-        if (is24HourView()) {
-            // 'k' means 1-24 hour
-            if (mHourFormat == 'k') {
-                mHourSpinner.setMinValue(1);
-                mHourSpinner.setMaxValue(24);
-            } else {
-                mHourSpinner.setMinValue(0);
-                mHourSpinner.setMaxValue(23);
+    /**
+     * A delegate interface that defined the public API of the TimePicker. Allows different
+     * TimePicker implementations. This would need to be implemented by the TimePicker delegates
+     * for the real behavior.
+     */
+    interface TimePickerDelegate {
+        void setCurrentHour(Integer currentHour);
+        Integer getCurrentHour();
+
+        void setCurrentMinute(Integer currentMinute);
+        Integer getCurrentMinute();
+
+        void setIs24HourView(Boolean is24HourView);
+        boolean is24HourView();
+
+        void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener);
+
+        void setEnabled(boolean enabled);
+        boolean isEnabled();
+
+        void setShowDoneButton(boolean showDoneButton);
+        void setDismissCallback(TimePickerDismissCallback callback);
+
+        int getBaseline();
+
+        void onConfigurationChanged(Configuration newConfig);
+
+        Parcelable onSaveInstanceState(Parcelable superState);
+        void onRestoreInstanceState(Parcelable state);
+
+        boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
+        void onPopulateAccessibilityEvent(AccessibilityEvent event);
+        void onInitializeAccessibilityEvent(AccessibilityEvent event);
+        void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
+    }
+
+    /**
+     * A callback interface for dismissing the TimePicker when included into a Dialog
+     *
+     * @hide
+     */
+    public static interface TimePickerDismissCallback {
+        void dismiss(TimePicker view, boolean isCancel, int hourOfDay, int minute);
+    }
+
+    /**
+     * An abstract class which can be used as a start for TimePicker implementations
+     */
+    abstract static class AbstractTimePickerDelegate implements TimePickerDelegate {
+        // The delegator
+        protected TimePicker mDelegator;
+
+        // The context
+        protected Context mContext;
+
+        // The current locale
+        protected Locale mCurrentLocale;
+
+        // Callbacks
+        protected  OnTimeChangedListener mOnTimeChangedListener;
+
+        public AbstractTimePickerDelegate(TimePicker delegator, Context context) {
+            mDelegator = delegator;
+            mContext = context;
+
+            // initialization based on locale
+            setCurrentLocale(Locale.getDefault());
+        }
+
+        public void setCurrentLocale(Locale locale) {
+            if (locale.equals(mCurrentLocale)) {
+                return;
             }
-        } else {
-            // 'K' means 0-11 hour
-            if (mHourFormat == 'K') {
-                mHourSpinner.setMinValue(0);
-                mHourSpinner.setMaxValue(11);
-            } else {
-                mHourSpinner.setMinValue(1);
-                mHourSpinner.setMaxValue(12);
-            }
-        }
-        mHourSpinner.setFormatter(mHourWithTwoDigit ? NumberPicker.getTwoDigitFormatter() : null);
-    }
-
-    private void updateMinuteControl() {
-        if (is24HourView()) {
-            mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
-        } else {
-            mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
-        }
-    }
-
-    private void updateAmPmControl() {
-        if (is24HourView()) {
-            if (mAmPmSpinner != null) {
-                mAmPmSpinner.setVisibility(View.GONE);
-            } else {
-                mAmPmButton.setVisibility(View.GONE);
-            }
-        } else {
-            int index = mIsAm ? Calendar.AM : Calendar.PM;
-            if (mAmPmSpinner != null) {
-                mAmPmSpinner.setValue(index);
-                mAmPmSpinner.setVisibility(View.VISIBLE);
-            } else {
-                mAmPmButton.setText(mAmPmStrings[index]);
-                mAmPmButton.setVisibility(View.VISIBLE);
-            }
-        }
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
-    }
-
-    private void onTimeChanged() {
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
-        if (mOnTimeChangedListener != null) {
-            mOnTimeChangedListener.onTimeChanged(this, getCurrentHour(), getCurrentMinute());
-        }
-    }
-
-    private void setContentDescriptions() {
-        // Minute
-        trySetContentDescription(mMinuteSpinner, R.id.increment,
-                R.string.time_picker_increment_minute_button);
-        trySetContentDescription(mMinuteSpinner, R.id.decrement,
-                R.string.time_picker_decrement_minute_button);
-        // Hour
-        trySetContentDescription(mHourSpinner, R.id.increment,
-                R.string.time_picker_increment_hour_button);
-        trySetContentDescription(mHourSpinner, R.id.decrement,
-                R.string.time_picker_decrement_hour_button);
-        // AM/PM
-        if (mAmPmSpinner != null) {
-            trySetContentDescription(mAmPmSpinner, R.id.increment,
-                    R.string.time_picker_increment_set_pm_button);
-            trySetContentDescription(mAmPmSpinner, R.id.decrement,
-                    R.string.time_picker_decrement_set_am_button);
-        }
-    }
-
-    private void trySetContentDescription(View root, int viewId, int contDescResId) {
-        View target = root.findViewById(viewId);
-        if (target != null) {
-            target.setContentDescription(mContext.getString(contDescResId));
-        }
-    }
-
-    private void updateInputState() {
-        // Make sure that if the user changes the value and the IME is active
-        // for one of the inputs if this widget, the IME is closed. If the user
-        // changed the value via the IME and there is a next input the IME will
-        // be shown, otherwise the user chose another means of changing the
-        // value and having the IME up makes no sense.
-        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
-        if (inputMethodManager != null) {
-            if (inputMethodManager.isActive(mHourSpinnerInput)) {
-                mHourSpinnerInput.clearFocus();
-                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-            } else if (inputMethodManager.isActive(mMinuteSpinnerInput)) {
-                mMinuteSpinnerInput.clearFocus();
-                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-            } else if (inputMethodManager.isActive(mAmPmSpinnerInput)) {
-                mAmPmSpinnerInput.clearFocus();
-                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-            }
+            mCurrentLocale = locale;
         }
     }
 }
diff --git a/core/java/android/widget/TimePickerDelegate.java b/core/java/android/widget/TimePickerDelegate.java
new file mode 100644
index 0000000..182d370
--- /dev/null
+++ b/core/java/android/widget/TimePickerDelegate.java
@@ -0,0 +1,1380 @@
+/*
+ * 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.widget;
+
+import android.animation.Keyframe;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.HapticFeedbackConstants;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.android.internal.R;
+
+import java.text.DateFormatSymbols;
+import java.util.ArrayList;
+import java.util.Calendar;
+
+/**
+ * A view for selecting the time of day, in either 24 hour or AM/PM mode.
+ */
+class TimePickerDelegate extends TimePicker.AbstractTimePickerDelegate implements
+        RadialTimePickerView.OnValueSelectedListener {
+
+    private static final String TAG = "TimePickerDelegate";
+
+    // Index used by RadialPickerLayout
+    private static final int HOUR_INDEX = 0;
+    private static final int MINUTE_INDEX = 1;
+
+    // NOT a real index for the purpose of what's showing.
+    private static final int AMPM_INDEX = 2;
+
+    // Also NOT a real index, just used for keyboard mode.
+    private static final int ENABLE_PICKER_INDEX = 3;
+
+    private static final int AM = 0;
+    private static final int PM = 1;
+
+    private static final boolean DEFAULT_ENABLED_STATE = true;
+    private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
+
+    private static final int HOURS_IN_HALF_DAY = 12;
+
+    // Delay in ms before starting the pulse animation
+    private static final int PULSE_ANIMATOR_DELAY = 300;
+
+    // Duration in ms of the pulse animation
+    private static final int PULSE_ANIMATOR_DURATION = 544;
+
+    private static int[] TEXT_APPEARANCE_TIME_LABEL_ATTR =
+            new int[] { R.attr.timePickerHeaderTimeLabelTextAppearance };
+
+    private final View mMainView;
+    private TextView mHourView;
+    private TextView mMinuteView;
+    private TextView mAmPmTextView;
+    private RadialTimePickerView mRadialTimePickerView;
+    private TextView mSeparatorView;
+
+    private ViewGroup mLayoutButtons;
+
+    private int mHeaderSelectedColor;
+    private int mHeaderUnSelectedColor;
+    private String mAmText;
+    private String mPmText;
+
+    private boolean mAllowAutoAdvance;
+    private int mInitialHourOfDay;
+    private int mInitialMinute;
+    private boolean mIs24HourView;
+
+    // For hardware IME input.
+    private char mPlaceholderText;
+    private String mDoublePlaceholderText;
+    private String mDeletedKeyFormat;
+    private boolean mInKbMode;
+    private ArrayList<Integer> mTypedTimes = new ArrayList<Integer>();
+    private Node mLegalTimesTree;
+    private int mAmKeyCode;
+    private int mPmKeyCode;
+
+    // For showing the done button when in a Dialog
+    private Button mDoneButton;
+    private boolean mShowDoneButton;
+    private TimePicker.TimePickerDismissCallback mDismissCallback;
+
+    // Accessibility strings.
+    private String mHourPickerDescription;
+    private String mSelectHours;
+    private String mMinutePickerDescription;
+    private String mSelectMinutes;
+
+    public TimePickerDelegate(TimePicker delegator, Context context, AttributeSet attrs,
+                              int defStyleAttr, int defStyleRes) {
+        super(delegator, context);
+
+        // process style attributes
+        final TypedArray a = mContext.obtainStyledAttributes(attrs,
+                R.styleable.TimePicker, defStyleAttr, defStyleRes);
+
+        final Resources res = mContext.getResources();
+
+        mHourPickerDescription = res.getString(R.string.hour_picker_description);
+        mSelectHours = res.getString(R.string.select_hours);
+        mMinutePickerDescription = res.getString(R.string.minute_picker_description);
+        mSelectMinutes = res.getString(R.string.select_minutes);
+
+        mHeaderSelectedColor = a.getColor(R.styleable.TimePicker_headerSelectedTextColor,
+                android.R.color.holo_blue_light);
+
+        mHeaderUnSelectedColor = getUnselectedColor(
+                R.color.timepicker_default_text_color_holo_light);
+        if (mHeaderUnSelectedColor == -1) {
+            mHeaderUnSelectedColor = a.getColor(R.styleable.TimePicker_headerUnselectedTextColor,
+                    R.color.timepicker_default_text_color_holo_light);
+        }
+
+        final int headerBackgroundColor = a.getColor(
+                R.styleable.TimePicker_headerBackgroundColor, 0);
+
+        a.recycle();
+
+        final int layoutResourceId = a.getResourceId(
+                R.styleable.TimePicker_internalLayout, R.layout.time_picker_holo);
+
+        final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+
+        mMainView = inflater.inflate(layoutResourceId, null);
+        mDelegator.addView(mMainView);
+
+        if (headerBackgroundColor != 0) {
+            RelativeLayout header = (RelativeLayout) mMainView.findViewById(R.id.time_header);
+            header.setBackgroundColor(headerBackgroundColor);
+        }
+
+        mHourView = (TextView) mMainView.findViewById(R.id.hours);
+        mMinuteView = (TextView) mMainView.findViewById(R.id.minutes);
+        mAmPmTextView = (TextView) mMainView.findViewById(R.id.ampm_label);
+        mSeparatorView = (TextView) mMainView.findViewById(R.id.separator);
+        mRadialTimePickerView = (RadialTimePickerView) mMainView.findViewById(R.id.radial_picker);
+
+        mLayoutButtons = (ViewGroup) mMainView.findViewById(R.id.layout_buttons);
+        mDoneButton = (Button) mMainView.findViewById(R.id.done_button);
+
+        String[] amPmTexts = new DateFormatSymbols().getAmPmStrings();
+        mAmText = amPmTexts[0];
+        mPmText = amPmTexts[1];
+
+        setupListeners();
+
+        mAllowAutoAdvance = true;
+
+        // Set up for keyboard mode.
+        mDoublePlaceholderText = res.getString(R.string.time_placeholder);
+        mDeletedKeyFormat = res.getString(R.string.deleted_key);
+        mPlaceholderText = mDoublePlaceholderText.charAt(0);
+        mAmKeyCode = mPmKeyCode = -1;
+        generateLegalTimesTree();
+
+        // Initialize with current time
+        final Calendar calendar = Calendar.getInstance(mCurrentLocale);
+        final int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
+        final int currentMinute = calendar.get(Calendar.MINUTE);
+        initialize(currentHour, currentMinute, false /* 12h */, HOUR_INDEX, false);
+    }
+
+    private int getUnselectedColor(int defColor) {
+        int result = -1;
+        final Resources.Theme theme = mContext.getTheme();
+        final TypedValue outValue = new TypedValue();
+        theme.resolveAttribute(R.attr.timePickerHeaderTimeLabelTextAppearance, outValue, true);
+        final int appearanceResId = outValue.resourceId;
+        TypedArray appearance = null;
+        if (appearanceResId != -1) {
+            appearance = theme.obtainStyledAttributes(appearanceResId,
+                    com.android.internal.R.styleable.TextAppearance);
+        }
+        if (appearance != null) {
+            result = appearance.getColor(
+                    com.android.internal.R.styleable.TextAppearance_textColor, defColor);
+            appearance.recycle();
+        }
+        return result;
+    }
+
+    private void initialize(int hourOfDay, int minute, boolean is24HourView, int index,
+                            boolean showDoneButton) {
+        mInitialHourOfDay = hourOfDay;
+        mInitialMinute = minute;
+        mIs24HourView = is24HourView;
+        mInKbMode = false;
+        mShowDoneButton = showDoneButton;
+        updateUI(index);
+    }
+
+    private void setupListeners() {
+        KeyboardListener keyboardListener = new KeyboardListener();
+        mDelegator.setOnKeyListener(keyboardListener);
+
+        mHourView.setOnKeyListener(keyboardListener);
+        mMinuteView.setOnKeyListener(keyboardListener);
+        mAmPmTextView.setOnKeyListener(keyboardListener);
+        mRadialTimePickerView.setOnValueSelectedListener(this);
+        mRadialTimePickerView.setOnKeyListener(keyboardListener);
+
+        mHourView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                setCurrentItemShowing(HOUR_INDEX, true, false, true);
+                tryVibrate();
+            }
+        });
+        mMinuteView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                setCurrentItemShowing(MINUTE_INDEX, true, false, true);
+                tryVibrate();
+            }
+        });
+        mDoneButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mInKbMode && isTypedTimeFullyLegal()) {
+                    finishKbMode(false);
+                } else {
+                    tryVibrate();
+                }
+                if (mDismissCallback != null) {
+                    mDismissCallback.dismiss(mDelegator, false, getCurrentHour(),
+                            getCurrentMinute());
+                }
+            }
+        });
+        mDoneButton.setOnKeyListener(keyboardListener);
+    }
+
+    private void updateUI(int index) {
+        // Update RadialPicker values
+        updateRadialPicker(index);
+        // Enable or disable the AM/PM view.
+        updateHeaderAmPm();
+        // Show or hide Done button
+        updateDoneButton();
+        // Update Hour and Minutes
+        updateHeaderHour(mInitialHourOfDay, true);
+        // Update time separator
+        updateHeaderSeparator();
+        // Update Minutes
+        updateHeaderMinute(mInitialMinute);
+        // Invalidate everything
+        mDelegator.invalidate();
+    }
+
+    private void updateRadialPicker(int index) {
+        mRadialTimePickerView.initialize(mInitialHourOfDay, mInitialMinute, mIs24HourView);
+        setCurrentItemShowing(index, false, true, true);
+    }
+
+    private int computeMaxWidthOfNumbers(int max) {
+        TextView tempView = new TextView(mContext);
+        TypedArray a = mContext.obtainStyledAttributes(TEXT_APPEARANCE_TIME_LABEL_ATTR);
+        final int textAppearanceResId = a.getResourceId(0, 0);
+        tempView.setTextAppearance(mContext, (textAppearanceResId != 0) ?
+                textAppearanceResId : R.style.TextAppearance_Holo_TimePicker_TimeLabel);
+        a.recycle();
+        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+        tempView.setLayoutParams(lp);
+        int maxWidth = 0;
+        for (int minutes = 0; minutes < max; minutes++) {
+            final String text = String.format("%02d", minutes);
+            tempView.setText(text);
+            tempView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+            maxWidth = Math.max(maxWidth, tempView.getMeasuredWidth());
+        }
+        return maxWidth;
+    }
+
+    private void updateHeaderAmPm() {
+        if (mIs24HourView) {
+            mAmPmTextView.setVisibility(View.GONE);
+        } else {
+            mAmPmTextView.setVisibility(View.VISIBLE);
+            final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+                    "hm");
+
+            boolean amPmOnLeft = bestDateTimePattern.startsWith("a");
+            if (TextUtils.getLayoutDirectionFromLocale(mCurrentLocale) ==
+                    View.LAYOUT_DIRECTION_RTL) {
+                amPmOnLeft = !amPmOnLeft;
+            }
+
+            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
+                    mAmPmTextView.getLayoutParams();
+
+            if (amPmOnLeft) {
+                layoutParams.rightMargin = computeMaxWidthOfNumbers(12 /* for hours */);
+                layoutParams.removeRule(RelativeLayout.RIGHT_OF);
+                layoutParams.addRule(RelativeLayout.LEFT_OF, R.id.separator);
+            } else {
+                layoutParams.leftMargin = computeMaxWidthOfNumbers(60 /* for minutes */);
+                layoutParams.removeRule(RelativeLayout.LEFT_OF);
+                layoutParams.addRule(RelativeLayout.RIGHT_OF, R.id.separator);
+            }
+
+            updateAmPmDisplay(mInitialHourOfDay < 12 ? AM : PM);
+            mAmPmTextView.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    tryVibrate();
+                    int amOrPm = mRadialTimePickerView.getAmOrPm();
+                    if (amOrPm == AM) {
+                        amOrPm = PM;
+                    } else if (amOrPm == PM){
+                        amOrPm = AM;
+                    }
+                    updateAmPmDisplay(amOrPm);
+                    mRadialTimePickerView.setAmOrPm(amOrPm);
+                }
+            });
+        }
+    }
+
+    private void updateDoneButton() {
+        mLayoutButtons.setVisibility(mShowDoneButton ? View.VISIBLE : View.GONE);
+    }
+
+    /**
+     * Set the current hour.
+     */
+    @Override
+    public void setCurrentHour(Integer currentHour) {
+        if (mInitialHourOfDay == currentHour) {
+            return;
+        }
+        mInitialHourOfDay = currentHour;
+        updateHeaderHour(currentHour, true /* accessibility announce */);
+        updateHeaderAmPm();
+        mRadialTimePickerView.setCurrentHour(currentHour);
+        mRadialTimePickerView.setAmOrPm(mInitialHourOfDay < 12 ? AM : PM);
+        mDelegator.invalidate();
+        onTimeChanged();
+    }
+
+    /**
+     * @return The current hour in the range (0-23).
+     */
+    @Override
+    public Integer getCurrentHour() {
+        int currentHour = mRadialTimePickerView.getCurrentHour();
+        if (mIs24HourView) {
+            return currentHour;
+        } else {
+            switch(mRadialTimePickerView.getAmOrPm()) {
+                case PM:
+                    return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY;
+                case AM:
+                default:
+                    return currentHour % HOURS_IN_HALF_DAY;
+            }
+        }
+    }
+
+    /**
+     * Set the current minute (0-59).
+     */
+    @Override
+    public void setCurrentMinute(Integer currentMinute) {
+        if (mInitialMinute == currentMinute) {
+            return;
+        }
+        mInitialMinute = currentMinute;
+        updateHeaderMinute(currentMinute);
+        mRadialTimePickerView.setCurrentMinute(currentMinute);
+        mDelegator.invalidate();
+        onTimeChanged();
+    }
+
+    /**
+     * @return The current minute.
+     */
+    @Override
+    public Integer getCurrentMinute() {
+        return mRadialTimePickerView.getCurrentMinute();
+    }
+
+    /**
+     * Set whether in 24 hour or AM/PM mode.
+     *
+     * @param is24HourView True = 24 hour mode. False = AM/PM.
+     */
+    @Override
+    public void setIs24HourView(Boolean is24HourView) {
+        if (is24HourView == mIs24HourView) {
+            return;
+        }
+        mIs24HourView = is24HourView;
+        generateLegalTimesTree();
+        int hour = mRadialTimePickerView.getCurrentHour();
+        mInitialHourOfDay = hour;
+        updateHeaderHour(hour, false /* no accessibility announce */);
+        updateHeaderAmPm();
+        updateRadialPicker(mRadialTimePickerView.getCurrentItemShowing());
+        mDelegator.invalidate();
+    }
+
+    /**
+     * @return true if this is in 24 hour view else false.
+     */
+    @Override
+    public boolean is24HourView() {
+        return mIs24HourView;
+    }
+
+    @Override
+    public void setOnTimeChangedListener(TimePicker.OnTimeChangedListener callback) {
+        mOnTimeChangedListener = callback;
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        mHourView.setEnabled(enabled);
+        mMinuteView.setEnabled(enabled);
+        mAmPmTextView.setEnabled(enabled);
+        mRadialTimePickerView.setEnabled(enabled);
+        mIsEnabled = enabled;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return mIsEnabled;
+    }
+
+    @Override
+    public void setShowDoneButton(boolean showDoneButton) {
+        mShowDoneButton = showDoneButton;
+        updateDoneButton();
+    }
+
+    @Override
+    public void setDismissCallback(TimePicker.TimePickerDismissCallback callback) {
+        mDismissCallback = callback;
+    }
+
+    @Override
+    public int getBaseline() {
+        // does not support baseline alignment
+        return -1;
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        updateUI(mRadialTimePickerView.getCurrentItemShowing());
+    }
+
+    @Override
+    public Parcelable onSaveInstanceState(Parcelable superState) {
+        return new SavedState(superState, getCurrentHour(), getCurrentMinute(),
+                is24HourView(), inKbMode(), getTypedTimes(), getCurrentItemShowing(),
+                isShowDoneButton());
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+        setInKbMode(ss.inKbMode());
+        setTypedTimes(ss.getTypesTimes());
+        initialize(ss.getHour(), ss.getMinute(), ss.is24HourMode(), ss.getCurrentItemShowing(),
+                ss.isShowDoneButton());
+        mRadialTimePickerView.invalidate();
+        if (mInKbMode) {
+            tryStartingKbMode(-1);
+            mHourView.invalidate();
+        }
+    }
+
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        return mRadialTimePickerView.dispatchPopulateAccessibilityEvent(event);
+    }
+
+    @Override
+    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        mRadialTimePickerView.onPopulateAccessibilityEvent(event);
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        mRadialTimePickerView.onInitializeAccessibilityEvent(event);
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        mRadialTimePickerView.onInitializeAccessibilityNodeInfo(info);
+    }
+
+    /**
+     * Set whether in keyboard mode or not.
+     *
+     * @param inKbMode True means in keyboard mode.
+     */
+    private void setInKbMode(boolean inKbMode) {
+        mInKbMode = inKbMode;
+    }
+
+    /**
+     * @return true if in keyboard mode
+     */
+    private boolean inKbMode() {
+        return mInKbMode;
+    }
+
+    private void setTypedTimes(ArrayList<Integer> typeTimes) {
+        mTypedTimes = typeTimes;
+    }
+
+    /**
+     * @return an array of typed times
+     */
+    private ArrayList<Integer> getTypedTimes() {
+        return mTypedTimes;
+    }
+
+    /**
+     * @return the index of the current item showing
+     */
+    private int getCurrentItemShowing() {
+        return mRadialTimePickerView.getCurrentItemShowing();
+    }
+
+    private boolean isShowDoneButton() {
+        return mShowDoneButton;
+    }
+
+    /**
+     * Propagate the time change
+     */
+    private void onTimeChanged() {
+        mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+        if (mOnTimeChangedListener != null) {
+            mOnTimeChangedListener.onTimeChanged(mDelegator,
+                    getCurrentHour(), getCurrentMinute());
+        }
+    }
+
+    /**
+     * Used to save / restore state of time picker
+     */
+    private static class SavedState extends View.BaseSavedState {
+
+        private final int mHour;
+        private final int mMinute;
+        private final boolean mIs24HourMode;
+        private final boolean mInKbMode;
+        private final ArrayList<Integer> mTypedTimes;
+        private final int mCurrentItemShowing;
+        private final boolean mShowDoneButton;
+
+        private SavedState(Parcelable superState, int hour, int minute, boolean is24HourMode,
+                           boolean isKbMode, ArrayList<Integer> typedTimes,
+                           int currentItemShowing, boolean showDoneButton) {
+            super(superState);
+            mHour = hour;
+            mMinute = minute;
+            mIs24HourMode = is24HourMode;
+            mInKbMode = isKbMode;
+            mTypedTimes = typedTimes;
+            mCurrentItemShowing = currentItemShowing;
+            mShowDoneButton = showDoneButton;
+        }
+
+        private SavedState(Parcel in) {
+            super(in);
+            mHour = in.readInt();
+            mMinute = in.readInt();
+            mIs24HourMode = (in.readInt() == 1);
+            mInKbMode = (in.readInt() == 1);
+            mTypedTimes = in.readArrayList(getClass().getClassLoader());
+            mCurrentItemShowing = in.readInt();
+            mShowDoneButton = (in.readInt() == 1);
+        }
+
+        public int getHour() {
+            return mHour;
+        }
+
+        public int getMinute() {
+            return mMinute;
+        }
+
+        public boolean is24HourMode() {
+            return mIs24HourMode;
+        }
+
+        public boolean inKbMode() {
+            return mInKbMode;
+        }
+
+        public ArrayList<Integer> getTypesTimes() {
+            return mTypedTimes;
+        }
+
+        public int getCurrentItemShowing() {
+            return mCurrentItemShowing;
+        }
+
+        public boolean isShowDoneButton() {
+            return mShowDoneButton;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeInt(mHour);
+            dest.writeInt(mMinute);
+            dest.writeInt(mIs24HourMode ? 1 : 0);
+            dest.writeInt(mInKbMode ? 1 : 0);
+            dest.writeList(mTypedTimes);
+            dest.writeInt(mCurrentItemShowing);
+            dest.writeInt(mShowDoneButton ? 1 : 0);
+        }
+
+        @SuppressWarnings({"unused", "hiding"})
+        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+
+    private void tryVibrate() {
+        mDelegator.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
+    }
+
+    private void updateAmPmDisplay(int amOrPm) {
+        if (amOrPm == AM) {
+            mAmPmTextView.setText(mAmText);
+            mRadialTimePickerView.announceForAccessibility(mAmText);
+        } else if (amOrPm == PM){
+            mAmPmTextView.setText(mPmText);
+            mRadialTimePickerView.announceForAccessibility(mPmText);
+        } else {
+            mAmPmTextView.setText(mDoublePlaceholderText);
+        }
+    }
+
+    /**
+     * Called by the picker for updating the header display.
+     */
+    @Override
+    public void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance) {
+        if (pickerIndex == HOUR_INDEX) {
+            updateHeaderHour(newValue, false);
+            String announcement = String.format("%d", newValue);
+            if (mAllowAutoAdvance && autoAdvance) {
+                setCurrentItemShowing(MINUTE_INDEX, true, true, false);
+                announcement += ". " + mSelectMinutes;
+            } else {
+                mRadialTimePickerView.setContentDescription(
+                        mHourPickerDescription + ": " + newValue);
+            }
+
+            mRadialTimePickerView.announceForAccessibility(announcement);
+        } else if (pickerIndex == MINUTE_INDEX){
+            updateHeaderMinute(newValue);
+            mRadialTimePickerView.setContentDescription(mMinutePickerDescription + ": " + newValue);
+        } else if (pickerIndex == AMPM_INDEX) {
+            updateAmPmDisplay(newValue);
+        } else if (pickerIndex == ENABLE_PICKER_INDEX) {
+            if (!isTypedTimeFullyLegal()) {
+                mTypedTimes.clear();
+            }
+            finishKbMode(true);
+        }
+    }
+
+    private void updateHeaderHour(int value, boolean announce) {
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+                (mIs24HourView) ? "Hm" : "hm");
+        final int lengthPattern = bestDateTimePattern.length();
+        boolean hourWithTwoDigit = false;
+        char hourFormat = '\0';
+        // Check if the returned pattern is single or double 'H', 'h', 'K', 'k'. We also save
+        // the hour format that we found.
+        for (int i = 0; i < lengthPattern; i++) {
+            final char c = bestDateTimePattern.charAt(i);
+            if (c == 'H' || c == 'h' || c == 'K' || c == 'k') {
+                hourFormat = c;
+                if (i + 1 < lengthPattern && c == bestDateTimePattern.charAt(i + 1)) {
+                    hourWithTwoDigit = true;
+                }
+                break;
+            }
+        }
+        final String format;
+        if (hourWithTwoDigit) {
+            format = "%02d";
+        } else {
+            format = "%d";
+        }
+        if (mIs24HourView) {
+            // 'k' means 1-24 hour
+            if (hourFormat == 'k' && value == 0) {
+                value = 24;
+            }
+        } else {
+            // 'K' means 0-11 hour
+            value = modulo12(value, hourFormat == 'K');
+        }
+        CharSequence text = String.format(format, value);
+        mHourView.setText(text);
+        if (announce) {
+            mRadialTimePickerView.announceForAccessibility(text);
+        }
+    }
+
+    private static int modulo12(int n, boolean startWithZero) {
+        int value = n % 12;
+        if (value == 0 && !startWithZero) {
+            value = 12;
+        }
+        return value;
+    }
+
+    /**
+     * The time separator is defined in the Unicode CLDR and cannot be supposed to be ":".
+     *
+     * See http://unicode.org/cldr/trac/browser/trunk/common/main
+     *
+     * We pass the correct "skeleton" depending on 12 or 24 hours view and then extract the
+     * separator as the character which is just after the hour marker in the returned pattern.
+     */
+    private void updateHeaderSeparator() {
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+                (mIs24HourView) ? "Hm" : "hm");
+        final String separatorText;
+        // See http://www.unicode.org/reports/tr35/tr35-dates.html for hour formats
+        final char[] hourFormats = {'H', 'h', 'K', 'k'};
+        int hIndex = lastIndexOfAny(bestDateTimePattern, hourFormats);
+        if (hIndex == -1) {
+            // Default case
+            separatorText = ":";
+        } else {
+            separatorText = Character.toString(bestDateTimePattern.charAt(hIndex + 1));
+        }
+        mSeparatorView.setText(separatorText);
+    }
+
+    static private int lastIndexOfAny(String str, char[] any) {
+        final int lengthAny = any.length;
+        if (lengthAny > 0) {
+            for (int i = str.length() - 1; i >= 0; i--) {
+                char c = str.charAt(i);
+                for (int j = 0; j < lengthAny; j++) {
+                    if (c == any[j]) {
+                        return i;
+                    }
+                }
+            }
+        }
+        return -1;
+    }
+
+    private void updateHeaderMinute(int value) {
+        if (value == 60) {
+            value = 0;
+        }
+        CharSequence text = String.format(mCurrentLocale, "%02d", value);
+        mRadialTimePickerView.announceForAccessibility(text);
+        mMinuteView.setText(text);
+    }
+
+    /**
+     * Show either Hours or Minutes.
+     */
+    private void setCurrentItemShowing(int index, boolean animateCircle, boolean delayLabelAnimate,
+                                       boolean announce) {
+        mRadialTimePickerView.setCurrentItemShowing(index, animateCircle);
+
+        TextView labelToAnimate;
+        if (index == HOUR_INDEX) {
+            int hours = mRadialTimePickerView.getCurrentHour();
+            if (!mIs24HourView) {
+                hours = hours % 12;
+            }
+            mRadialTimePickerView.setContentDescription(mHourPickerDescription + ": " + hours);
+            if (announce) {
+                mRadialTimePickerView.announceForAccessibility(mSelectHours);
+            }
+            labelToAnimate = mHourView;
+        } else {
+            int minutes = mRadialTimePickerView.getCurrentMinute();
+            mRadialTimePickerView.setContentDescription(mMinutePickerDescription + ": " + minutes);
+            if (announce) {
+                mRadialTimePickerView.announceForAccessibility(mSelectMinutes);
+            }
+            labelToAnimate = mMinuteView;
+        }
+
+        int hourColor = (index == HOUR_INDEX) ? mHeaderSelectedColor : mHeaderUnSelectedColor;
+        int minuteColor = (index == MINUTE_INDEX) ? mHeaderSelectedColor : mHeaderUnSelectedColor;
+        mHourView.setTextColor(hourColor);
+        mMinuteView.setTextColor(minuteColor);
+
+        ObjectAnimator pulseAnimator = getPulseAnimator(labelToAnimate, 0.85f, 1.1f);
+        if (delayLabelAnimate) {
+            pulseAnimator.setStartDelay(PULSE_ANIMATOR_DELAY);
+        }
+        pulseAnimator.start();
+    }
+
+    /**
+     * For keyboard mode, processes key events.
+     *
+     * @param keyCode the pressed key.
+     *
+     * @return true if the key was successfully processed, false otherwise.
+     */
+    private boolean processKeyUp(int keyCode) {
+        if (keyCode == KeyEvent.KEYCODE_ESCAPE || keyCode == KeyEvent.KEYCODE_BACK) {
+            if (mDismissCallback != null) {
+                mDismissCallback.dismiss(mDelegator, true, getCurrentHour(), getCurrentMinute());
+            }
+            return true;
+        } else if (keyCode == KeyEvent.KEYCODE_TAB) {
+            if(mInKbMode) {
+                if (isTypedTimeFullyLegal()) {
+                    finishKbMode(true);
+                }
+                return true;
+            }
+        } else if (keyCode == KeyEvent.KEYCODE_ENTER) {
+            if (mInKbMode) {
+                if (!isTypedTimeFullyLegal()) {
+                    return true;
+                }
+                finishKbMode(false);
+            }
+            if (mOnTimeChangedListener != null) {
+                mOnTimeChangedListener.onTimeChanged(mDelegator,
+                        mRadialTimePickerView.getCurrentHour(),
+                        mRadialTimePickerView.getCurrentMinute());
+            }
+            if (mDismissCallback != null) {
+                mDismissCallback.dismiss(mDelegator, false, getCurrentHour(), getCurrentMinute());
+            }
+            return true;
+        } else if (keyCode == KeyEvent.KEYCODE_DEL) {
+            if (mInKbMode) {
+                if (!mTypedTimes.isEmpty()) {
+                    int deleted = deleteLastTypedKey();
+                    String deletedKeyStr;
+                    if (deleted == getAmOrPmKeyCode(AM)) {
+                        deletedKeyStr = mAmText;
+                    } else if (deleted == getAmOrPmKeyCode(PM)) {
+                        deletedKeyStr = mPmText;
+                    } else {
+                        deletedKeyStr = String.format("%d", getValFromKeyCode(deleted));
+                    }
+                    mRadialTimePickerView.announceForAccessibility(
+                            String.format(mDeletedKeyFormat, deletedKeyStr));
+                    updateDisplay(true);
+                }
+            }
+        } else if (keyCode == KeyEvent.KEYCODE_0 || keyCode == KeyEvent.KEYCODE_1
+                || keyCode == KeyEvent.KEYCODE_2 || keyCode == KeyEvent.KEYCODE_3
+                || keyCode == KeyEvent.KEYCODE_4 || keyCode == KeyEvent.KEYCODE_5
+                || keyCode == KeyEvent.KEYCODE_6 || keyCode == KeyEvent.KEYCODE_7
+                || keyCode == KeyEvent.KEYCODE_8 || keyCode == KeyEvent.KEYCODE_9
+                || (!mIs24HourView &&
+                (keyCode == getAmOrPmKeyCode(AM) || keyCode == getAmOrPmKeyCode(PM)))) {
+            if (!mInKbMode) {
+                if (mRadialTimePickerView == null) {
+                    // Something's wrong, because time picker should definitely not be null.
+                    Log.e(TAG, "Unable to initiate keyboard mode, TimePicker was null.");
+                    return true;
+                }
+                mTypedTimes.clear();
+                tryStartingKbMode(keyCode);
+                return true;
+            }
+            // We're already in keyboard mode.
+            if (addKeyIfLegal(keyCode)) {
+                updateDisplay(false);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Try to start keyboard mode with the specified key.
+     *
+     * @param keyCode The key to use as the first press. Keyboard mode will not be started if the
+     * key is not legal to start with. Or, pass in -1 to get into keyboard mode without a starting
+     * key.
+     */
+    private void tryStartingKbMode(int keyCode) {
+        if (keyCode == -1 || addKeyIfLegal(keyCode)) {
+            mInKbMode = true;
+            mDoneButton.setEnabled(false);
+            updateDisplay(false);
+            mRadialTimePickerView.setInputEnabled(false);
+        }
+    }
+
+    private boolean addKeyIfLegal(int keyCode) {
+        // If we're in 24hour mode, we'll need to check if the input is full. If in AM/PM mode,
+        // we'll need to see if AM/PM have been typed.
+        if ((mIs24HourView && mTypedTimes.size() == 4) ||
+                (!mIs24HourView && isTypedTimeFullyLegal())) {
+            return false;
+        }
+
+        mTypedTimes.add(keyCode);
+        if (!isTypedTimeLegalSoFar()) {
+            deleteLastTypedKey();
+            return false;
+        }
+
+        int val = getValFromKeyCode(keyCode);
+        mRadialTimePickerView.announceForAccessibility(String.format("%d", val));
+        // Automatically fill in 0's if AM or PM was legally entered.
+        if (isTypedTimeFullyLegal()) {
+            if (!mIs24HourView && mTypedTimes.size() <= 3) {
+                mTypedTimes.add(mTypedTimes.size() - 1, KeyEvent.KEYCODE_0);
+                mTypedTimes.add(mTypedTimes.size() - 1, KeyEvent.KEYCODE_0);
+            }
+            mDoneButton.setEnabled(true);
+        }
+
+        return true;
+    }
+
+    /**
+     * Traverse the tree to see if the keys that have been typed so far are legal as is,
+     * or may become legal as more keys are typed (excluding backspace).
+     */
+    private boolean isTypedTimeLegalSoFar() {
+        Node node = mLegalTimesTree;
+        for (int keyCode : mTypedTimes) {
+            node = node.canReach(keyCode);
+            if (node == null) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Check if the time that has been typed so far is completely legal, as is.
+     */
+    private boolean isTypedTimeFullyLegal() {
+        if (mIs24HourView) {
+            // For 24-hour mode, the time is legal if the hours and minutes are each legal. Note:
+            // getEnteredTime() will ONLY call isTypedTimeFullyLegal() when NOT in 24hour mode.
+            int[] values = getEnteredTime(null);
+            return (values[0] >= 0 && values[1] >= 0 && values[1] < 60);
+        } else {
+            // For AM/PM mode, the time is legal if it contains an AM or PM, as those can only be
+            // legally added at specific times based on the tree's algorithm.
+            return (mTypedTimes.contains(getAmOrPmKeyCode(AM)) ||
+                    mTypedTimes.contains(getAmOrPmKeyCode(PM)));
+        }
+    }
+
+    private int deleteLastTypedKey() {
+        int deleted = mTypedTimes.remove(mTypedTimes.size() - 1);
+        if (!isTypedTimeFullyLegal()) {
+            mDoneButton.setEnabled(false);
+        }
+        return deleted;
+    }
+
+    /**
+     * Get out of keyboard mode. If there is nothing in typedTimes, revert to TimePicker's time.
+     * @param updateDisplays If true, update the displays with the relevant time.
+     */
+    private void finishKbMode(boolean updateDisplays) {
+        mInKbMode = false;
+        if (!mTypedTimes.isEmpty()) {
+            int values[] = getEnteredTime(null);
+            mRadialTimePickerView.setCurrentHour(values[0]);
+            mRadialTimePickerView.setCurrentMinute(values[1]);
+            if (!mIs24HourView) {
+                mRadialTimePickerView.setAmOrPm(values[2]);
+            }
+            mTypedTimes.clear();
+        }
+        if (updateDisplays) {
+            updateDisplay(false);
+            mRadialTimePickerView.setInputEnabled(true);
+        }
+    }
+
+    /**
+     * Update the hours, minutes, and AM/PM displays with the typed times. If the typedTimes is
+     * empty, either show an empty display (filled with the placeholder text), or update from the
+     * timepicker's values.
+     *
+     * @param allowEmptyDisplay if true, then if the typedTimes is empty, use the placeholder text.
+     * Otherwise, revert to the timepicker's values.
+     */
+    private void updateDisplay(boolean allowEmptyDisplay) {
+        if (!allowEmptyDisplay && mTypedTimes.isEmpty()) {
+            int hour = mRadialTimePickerView.getCurrentHour();
+            int minute = mRadialTimePickerView.getCurrentMinute();
+            updateHeaderHour(hour, true);
+            updateHeaderMinute(minute);
+            if (!mIs24HourView) {
+                updateAmPmDisplay(hour < 12 ? AM : PM);
+            }
+            setCurrentItemShowing(mRadialTimePickerView.getCurrentItemShowing(), true, true, true);
+            mDoneButton.setEnabled(true);
+        } else {
+            boolean[] enteredZeros = {false, false};
+            int[] values = getEnteredTime(enteredZeros);
+            String hourFormat = enteredZeros[0] ? "%02d" : "%2d";
+            String minuteFormat = (enteredZeros[1]) ? "%02d" : "%2d";
+            String hourStr = (values[0] == -1) ? mDoublePlaceholderText :
+                    String.format(hourFormat, values[0]).replace(' ', mPlaceholderText);
+            String minuteStr = (values[1] == -1) ? mDoublePlaceholderText :
+                    String.format(minuteFormat, values[1]).replace(' ', mPlaceholderText);
+            mHourView.setText(hourStr);
+            mHourView.setTextColor(mHeaderUnSelectedColor);
+            mMinuteView.setText(minuteStr);
+            mMinuteView.setTextColor(mHeaderUnSelectedColor);
+            if (!mIs24HourView) {
+                updateAmPmDisplay(values[2]);
+            }
+        }
+    }
+
+    private int getValFromKeyCode(int keyCode) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_0:
+                return 0;
+            case KeyEvent.KEYCODE_1:
+                return 1;
+            case KeyEvent.KEYCODE_2:
+                return 2;
+            case KeyEvent.KEYCODE_3:
+                return 3;
+            case KeyEvent.KEYCODE_4:
+                return 4;
+            case KeyEvent.KEYCODE_5:
+                return 5;
+            case KeyEvent.KEYCODE_6:
+                return 6;
+            case KeyEvent.KEYCODE_7:
+                return 7;
+            case KeyEvent.KEYCODE_8:
+                return 8;
+            case KeyEvent.KEYCODE_9:
+                return 9;
+            default:
+                return -1;
+        }
+    }
+
+    /**
+     * Get the currently-entered time, as integer values of the hours and minutes typed.
+     *
+     * @param enteredZeros A size-2 boolean array, which the caller should initialize, and which
+     * may then be used for the caller to know whether zeros had been explicitly entered as either
+     * hours of minutes. This is helpful for deciding whether to show the dashes, or actual 0's.
+     *
+     * @return A size-3 int array. The first value will be the hours, the second value will be the
+     * minutes, and the third will be either AM or PM.
+     */
+    private int[] getEnteredTime(boolean[] enteredZeros) {
+        int amOrPm = -1;
+        int startIndex = 1;
+        if (!mIs24HourView && isTypedTimeFullyLegal()) {
+            int keyCode = mTypedTimes.get(mTypedTimes.size() - 1);
+            if (keyCode == getAmOrPmKeyCode(AM)) {
+                amOrPm = AM;
+            } else if (keyCode == getAmOrPmKeyCode(PM)){
+                amOrPm = PM;
+            }
+            startIndex = 2;
+        }
+        int minute = -1;
+        int hour = -1;
+        for (int i = startIndex; i <= mTypedTimes.size(); i++) {
+            int val = getValFromKeyCode(mTypedTimes.get(mTypedTimes.size() - i));
+            if (i == startIndex) {
+                minute = val;
+            } else if (i == startIndex+1) {
+                minute += 10 * val;
+                if (enteredZeros != null && val == 0) {
+                    enteredZeros[1] = true;
+                }
+            } else if (i == startIndex+2) {
+                hour = val;
+            } else if (i == startIndex+3) {
+                hour += 10 * val;
+                if (enteredZeros != null && val == 0) {
+                    enteredZeros[0] = true;
+                }
+            }
+        }
+
+        int[] ret = {hour, minute, amOrPm};
+        return ret;
+    }
+
+    /**
+     * Get the keycode value for AM and PM in the current language.
+     */
+    private int getAmOrPmKeyCode(int amOrPm) {
+        // Cache the codes.
+        if (mAmKeyCode == -1 || mPmKeyCode == -1) {
+            // Find the first character in the AM/PM text that is unique.
+            KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
+            char amChar;
+            char pmChar;
+            for (int i = 0; i < Math.max(mAmText.length(), mPmText.length()); i++) {
+                amChar = mAmText.toLowerCase(mCurrentLocale).charAt(i);
+                pmChar = mPmText.toLowerCase(mCurrentLocale).charAt(i);
+                if (amChar != pmChar) {
+                    KeyEvent[] events = kcm.getEvents(new char[]{amChar, pmChar});
+                    // There should be 4 events: a down and up for both AM and PM.
+                    if (events != null && events.length == 4) {
+                        mAmKeyCode = events[0].getKeyCode();
+                        mPmKeyCode = events[2].getKeyCode();
+                    } else {
+                        Log.e(TAG, "Unable to find keycodes for AM and PM.");
+                    }
+                    break;
+                }
+            }
+        }
+        if (amOrPm == AM) {
+            return mAmKeyCode;
+        } else if (amOrPm == PM) {
+            return mPmKeyCode;
+        }
+
+        return -1;
+    }
+
+    /**
+     * Create a tree for deciding what keys can legally be typed.
+     */
+    private void generateLegalTimesTree() {
+        // Create a quick cache of numbers to their keycodes.
+        final int k0 = KeyEvent.KEYCODE_0;
+        final int k1 = KeyEvent.KEYCODE_1;
+        final int k2 = KeyEvent.KEYCODE_2;
+        final int k3 = KeyEvent.KEYCODE_3;
+        final int k4 = KeyEvent.KEYCODE_4;
+        final int k5 = KeyEvent.KEYCODE_5;
+        final int k6 = KeyEvent.KEYCODE_6;
+        final int k7 = KeyEvent.KEYCODE_7;
+        final int k8 = KeyEvent.KEYCODE_8;
+        final int k9 = KeyEvent.KEYCODE_9;
+
+        // The root of the tree doesn't contain any numbers.
+        mLegalTimesTree = new Node();
+        if (mIs24HourView) {
+            // We'll be re-using these nodes, so we'll save them.
+            Node minuteFirstDigit = new Node(k0, k1, k2, k3, k4, k5);
+            Node minuteSecondDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9);
+            // The first digit must be followed by the second digit.
+            minuteFirstDigit.addChild(minuteSecondDigit);
+
+            // The first digit may be 0-1.
+            Node firstDigit = new Node(k0, k1);
+            mLegalTimesTree.addChild(firstDigit);
+
+            // When the first digit is 0-1, the second digit may be 0-5.
+            Node secondDigit = new Node(k0, k1, k2, k3, k4, k5);
+            firstDigit.addChild(secondDigit);
+            // We may now be followed by the first minute digit. E.g. 00:09, 15:58.
+            secondDigit.addChild(minuteFirstDigit);
+
+            // When the first digit is 0-1, and the second digit is 0-5, the third digit may be 6-9.
+            Node thirdDigit = new Node(k6, k7, k8, k9);
+            // The time must now be finished. E.g. 0:55, 1:08.
+            secondDigit.addChild(thirdDigit);
+
+            // When the first digit is 0-1, the second digit may be 6-9.
+            secondDigit = new Node(k6, k7, k8, k9);
+            firstDigit.addChild(secondDigit);
+            // We must now be followed by the first minute digit. E.g. 06:50, 18:20.
+            secondDigit.addChild(minuteFirstDigit);
+
+            // The first digit may be 2.
+            firstDigit = new Node(k2);
+            mLegalTimesTree.addChild(firstDigit);
+
+            // When the first digit is 2, the second digit may be 0-3.
+            secondDigit = new Node(k0, k1, k2, k3);
+            firstDigit.addChild(secondDigit);
+            // We must now be followed by the first minute digit. E.g. 20:50, 23:09.
+            secondDigit.addChild(minuteFirstDigit);
+
+            // When the first digit is 2, the second digit may be 4-5.
+            secondDigit = new Node(k4, k5);
+            firstDigit.addChild(secondDigit);
+            // We must now be followd by the last minute digit. E.g. 2:40, 2:53.
+            secondDigit.addChild(minuteSecondDigit);
+
+            // The first digit may be 3-9.
+            firstDigit = new Node(k3, k4, k5, k6, k7, k8, k9);
+            mLegalTimesTree.addChild(firstDigit);
+            // We must now be followed by the first minute digit. E.g. 3:57, 8:12.
+            firstDigit.addChild(minuteFirstDigit);
+        } else {
+            // We'll need to use the AM/PM node a lot.
+            // Set up AM and PM to respond to "a" and "p".
+            Node ampm = new Node(getAmOrPmKeyCode(AM), getAmOrPmKeyCode(PM));
+
+            // The first hour digit may be 1.
+            Node firstDigit = new Node(k1);
+            mLegalTimesTree.addChild(firstDigit);
+            // We'll allow quick input of on-the-hour times. E.g. 1pm.
+            firstDigit.addChild(ampm);
+
+            // When the first digit is 1, the second digit may be 0-2.
+            Node secondDigit = new Node(k0, k1, k2);
+            firstDigit.addChild(secondDigit);
+            // Also for quick input of on-the-hour times. E.g. 10pm, 12am.
+            secondDigit.addChild(ampm);
+
+            // When the first digit is 1, and the second digit is 0-2, the third digit may be 0-5.
+            Node thirdDigit = new Node(k0, k1, k2, k3, k4, k5);
+            secondDigit.addChild(thirdDigit);
+            // The time may be finished now. E.g. 1:02pm, 1:25am.
+            thirdDigit.addChild(ampm);
+
+            // When the first digit is 1, the second digit is 0-2, and the third digit is 0-5,
+            // the fourth digit may be 0-9.
+            Node fourthDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9);
+            thirdDigit.addChild(fourthDigit);
+            // The time must be finished now. E.g. 10:49am, 12:40pm.
+            fourthDigit.addChild(ampm);
+
+            // When the first digit is 1, and the second digit is 0-2, the third digit may be 6-9.
+            thirdDigit = new Node(k6, k7, k8, k9);
+            secondDigit.addChild(thirdDigit);
+            // The time must be finished now. E.g. 1:08am, 1:26pm.
+            thirdDigit.addChild(ampm);
+
+            // When the first digit is 1, the second digit may be 3-5.
+            secondDigit = new Node(k3, k4, k5);
+            firstDigit.addChild(secondDigit);
+
+            // When the first digit is 1, and the second digit is 3-5, the third digit may be 0-9.
+            thirdDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9);
+            secondDigit.addChild(thirdDigit);
+            // The time must be finished now. E.g. 1:39am, 1:50pm.
+            thirdDigit.addChild(ampm);
+
+            // The hour digit may be 2-9.
+            firstDigit = new Node(k2, k3, k4, k5, k6, k7, k8, k9);
+            mLegalTimesTree.addChild(firstDigit);
+            // We'll allow quick input of on-the-hour-times. E.g. 2am, 5pm.
+            firstDigit.addChild(ampm);
+
+            // When the first digit is 2-9, the second digit may be 0-5.
+            secondDigit = new Node(k0, k1, k2, k3, k4, k5);
+            firstDigit.addChild(secondDigit);
+
+            // When the first digit is 2-9, and the second digit is 0-5, the third digit may be 0-9.
+            thirdDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9);
+            secondDigit.addChild(thirdDigit);
+            // The time must be finished now. E.g. 2:57am, 9:30pm.
+            thirdDigit.addChild(ampm);
+        }
+    }
+
+    /**
+     * Simple node class to be used for traversal to check for legal times.
+     * mLegalKeys represents the keys that can be typed to get to the node.
+     * mChildren are the children that can be reached from this node.
+     */
+    private class Node {
+        private int[] mLegalKeys;
+        private ArrayList<Node> mChildren;
+
+        public Node(int... legalKeys) {
+            mLegalKeys = legalKeys;
+            mChildren = new ArrayList<Node>();
+        }
+
+        public void addChild(Node child) {
+            mChildren.add(child);
+        }
+
+        public boolean containsKey(int key) {
+            for (int i = 0; i < mLegalKeys.length; i++) {
+                if (mLegalKeys[i] == key) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public Node canReach(int key) {
+            if (mChildren == null) {
+                return null;
+            }
+            for (Node child : mChildren) {
+                if (child.containsKey(key)) {
+                    return child;
+                }
+            }
+            return null;
+        }
+    }
+
+    private class KeyboardListener implements View.OnKeyListener {
+        @Override
+        public boolean onKey(View v, int keyCode, KeyEvent event) {
+            if (event.getAction() == KeyEvent.ACTION_UP) {
+                return processKeyUp(keyCode);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Render an animator to pulsate a view in place.
+     *
+     * @param labelToAnimate the view to pulsate.
+     * @return The animator object. Use .start() to begin.
+     */
+    private static ObjectAnimator getPulseAnimator(View labelToAnimate, float decreaseRatio,
+            float increaseRatio) {
+        final Keyframe k0 = Keyframe.ofFloat(0f, 1f);
+        final Keyframe k1 = Keyframe.ofFloat(0.275f, decreaseRatio);
+        final Keyframe k2 = Keyframe.ofFloat(0.69f, increaseRatio);
+        final Keyframe k3 = Keyframe.ofFloat(1f, 1f);
+
+        PropertyValuesHolder scaleX = PropertyValuesHolder.ofKeyframe("scaleX", k0, k1, k2, k3);
+        PropertyValuesHolder scaleY = PropertyValuesHolder.ofKeyframe("scaleY", k0, k1, k2, k3);
+        ObjectAnimator pulseAnimator =
+                ObjectAnimator.ofPropertyValuesHolder(labelToAnimate, scaleX, scaleY);
+        pulseAnimator.setDuration(PULSE_ANIMATOR_DURATION);
+
+        return pulseAnimator;
+    }
+}
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index e38dfa7..bf5e49b9 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.annotation.IntDef;
 import android.app.INotificationManager;
 import android.app.ITransientNotification;
 import android.content.Context;
@@ -29,11 +30,13 @@
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A toast is a view containing a quick little message for the user.  The toast class
  * helps you create and show those.
@@ -61,6 +64,11 @@
     static final String TAG = "Toast";
     static final boolean localLOGV = false;
 
+    /** @hide */
+    @IntDef({LENGTH_SHORT, LENGTH_LONG})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Duration {}
+
     /**
      * Show the view or text notification for a short period of time.  This time
      * could be user-definable.  This is the default.
@@ -152,7 +160,7 @@
      * @see #LENGTH_SHORT
      * @see #LENGTH_LONG
      */
-    public void setDuration(int duration) {
+    public void setDuration(@Duration int duration) {
         mDuration = duration;
     }
 
@@ -160,6 +168,7 @@
      * Return the duration.
      * @see #setDuration
      */
+    @Duration
     public int getDuration() {
         return mDuration;
     }
@@ -237,7 +246,7 @@
      *                 {@link #LENGTH_LONG}
      *
      */
-    public static Toast makeText(Context context, CharSequence text, int duration) {
+    public static Toast makeText(Context context, CharSequence text, @Duration int duration) {
         Toast result = new Toast(context);
 
         LayoutInflater inflate = (LayoutInflater)
@@ -263,7 +272,7 @@
      *
      * @throws Resources.NotFoundException if the resource can't be found.
      */
-    public static Toast makeText(Context context, int resId, int duration)
+    public static Toast makeText(Context context, int resId, @Duration int duration)
                                 throws Resources.NotFoundException {
         return makeText(context, context.getResources().getText(resId), duration);
     }
diff --git a/core/java/android/widget/ToggleButton.java b/core/java/android/widget/ToggleButton.java
index cedc777..28519d1 100644
--- a/core/java/android/widget/ToggleButton.java
+++ b/core/java/android/widget/ToggleButton.java
@@ -16,7 +16,6 @@
 
 package android.widget;
 
-
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -25,8 +24,6 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 
-import com.android.internal.R;
-
 /**
  * Displays checked/unchecked states as a button
  * with a "light" indicator and by default accompanied with the text "ON" or "OFF".
@@ -46,13 +43,12 @@
 
     private static final int NO_ALPHA = 0xFF;
     private float mDisabledAlpha;
-    
-    public ToggleButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        
-        TypedArray a =
-            context.obtainStyledAttributes(
-                    attrs, com.android.internal.R.styleable.ToggleButton, defStyle, 0);
+
+    public ToggleButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ToggleButton, defStyleAttr, defStyleRes);
         mTextOn = a.getText(com.android.internal.R.styleable.ToggleButton_textOn);
         mTextOff = a.getText(com.android.internal.R.styleable.ToggleButton_textOff);
         mDisabledAlpha = a.getFloat(com.android.internal.R.styleable.ToggleButton_disabledAlpha, 0.5f);
@@ -60,6 +56,10 @@
         a.recycle();
     }
 
+    public ToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public ToggleButton(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.buttonStyleToggle);
     }
diff --git a/core/java/android/widget/TwoLineListItem.java b/core/java/android/widget/TwoLineListItem.java
index f7e5266..5606c60 100644
--- a/core/java/android/widget/TwoLineListItem.java
+++ b/core/java/android/widget/TwoLineListItem.java
@@ -56,11 +56,15 @@
         this(context, attrs, 0); 
     }
 
-    public TwoLineListItem(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TwoLineListItem(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.TwoLineListItem, defStyle, 0);
+    public TwoLineListItem(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.TwoLineListItem, defStyleAttr, defStyleRes);
 
         a.recycle();
     }
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index d57b739..f23c64f 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -19,7 +19,6 @@
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.media.AudioManager;
@@ -127,8 +126,12 @@
         initVideoView();
     }
 
-    public VideoView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public VideoView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public VideoView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initVideoView();
     }
 
@@ -297,11 +300,8 @@
             // not ready for playback just yet, will try again later
             return;
         }
-        // Tell the music playback service to pause
-        // TODO: these constants need to be published somewhere in the framework.
-        Intent i = new Intent("com.android.music.musicservicecommand");
-        i.putExtra("command", "pause");
-        mContext.sendBroadcast(i);
+        AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
 
         // we shouldn't clear the target state, because somebody might have
         // called start() previously
diff --git a/core/java/android/widget/ZoomButton.java b/core/java/android/widget/ZoomButton.java
index af17c94..715e868 100644
--- a/core/java/android/widget/ZoomButton.java
+++ b/core/java/android/widget/ZoomButton.java
@@ -49,8 +49,12 @@
         this(context, attrs, 0);
     }
     
-    public ZoomButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ZoomButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ZoomButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         mHandler = new Handler();
         setOnLongClickListener(this);
     }
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
index 50c803b..f7e9648 100644
--- a/core/java/android/widget/ZoomButtonsController.java
+++ b/core/java/android/widget/ZoomButtonsController.java
@@ -32,7 +32,6 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
-import android.view.ViewParent;
 import android.view.ViewRootImpl;
 import android.view.WindowManager;
 import android.view.View.OnClickListener;
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 066d6c3..347f957 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -42,7 +42,6 @@
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
-import android.util.Log;
 import android.util.TypedValue;
 import android.view.ActionMode;
 import android.view.ContextThemeWrapper;
@@ -51,7 +50,6 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.Window;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AnimationUtils;
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index fe532b0..a7a7e7e 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -70,6 +70,8 @@
     
     private View mView;
 
+    private int mViewLayoutResId;
+
     private int mViewSpacingLeft;
     
     private int mViewSpacingTop;
@@ -232,11 +234,6 @@
     public void installContent() {
         /* We use a custom title so never request a window title */
         mWindow.requestFeature(Window.FEATURE_NO_TITLE);
-        
-        if (mView == null || !canTextInput(mView)) {
-            mWindow.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
-                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
-        }
         mWindow.setContentView(mAlertDialogLayout);
         setupView();
     }
@@ -263,10 +260,20 @@
     }
 
     /**
+     * Set the view resource to display in the dialog.
+     */
+    public void setView(int layoutResId) {
+        mView = null;
+        mViewLayoutResId = layoutResId;
+        mViewSpacingSpecified = false;
+    }
+
+    /**
      * Set the view to display in the dialog.
      */
     public void setView(View view) {
         mView = view;
+        mViewLayoutResId = 0;
         mViewSpacingSpecified = false;
     }
     
@@ -276,6 +283,7 @@
     public void setView(View view, int viewSpacingLeft, int viewSpacingTop, int viewSpacingRight,
             int viewSpacingBottom) {
         mView = view;
+        mViewLayoutResId = 0;
         mViewSpacingSpecified = true;
         mViewSpacingLeft = viewSpacingLeft;
         mViewSpacingTop = viewSpacingTop;
@@ -406,20 +414,36 @@
             mWindow.setCloseOnTouchOutsideIfNotSet(true);
         }
 
-        FrameLayout customPanel = null;
+        final FrameLayout customPanel = (FrameLayout) mWindow.findViewById(R.id.customPanel);
+        final View customView;
         if (mView != null) {
-            customPanel = (FrameLayout) mWindow.findViewById(R.id.customPanel);
-            FrameLayout custom = (FrameLayout) mWindow.findViewById(R.id.custom);
-            custom.addView(mView, new LayoutParams(MATCH_PARENT, MATCH_PARENT));
+            customView = mView;
+        } else if (mViewLayoutResId != 0) {
+            final LayoutInflater inflater = LayoutInflater.from(mContext);
+            customView = inflater.inflate(mViewLayoutResId, customPanel, false);
+        } else {
+            customView = null;
+        }
+
+        if (customView == null || !canTextInput(customView)) {
+            mWindow.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+        }
+
+        if (customView != null) {
+            final FrameLayout custom = (FrameLayout) mWindow.findViewById(R.id.custom);
+            custom.addView(customView, new LayoutParams(MATCH_PARENT, MATCH_PARENT));
+
             if (mViewSpacingSpecified) {
-                custom.setPadding(mViewSpacingLeft, mViewSpacingTop, mViewSpacingRight,
-                        mViewSpacingBottom);
+                custom.setPadding(
+                        mViewSpacingLeft, mViewSpacingTop, mViewSpacingRight, mViewSpacingBottom);
             }
+
             if (mListView != null) {
                 ((LinearLayout.LayoutParams) customPanel.getLayoutParams()).weight = 0;
             }
         } else {
-            mWindow.findViewById(R.id.customPanel).setVisibility(View.GONE);
+            customPanel.setVisibility(View.GONE);
         }
         
         /* Only display the divider if we have a title and a 
@@ -427,7 +451,7 @@
          */
         if (hasTitle) {
             View divider = null;
-            if (mMessage != null || mView != null || mListView != null) {
+            if (mMessage != null || customView != null || mListView != null) {
                 divider = mWindow.findViewById(R.id.titleDivider);
             } else {
                 divider = mWindow.findViewById(R.id.titleDividerTop);
@@ -736,8 +760,13 @@
             super(context, attrs);
         }
 
-        public RecycleListView(Context context, AttributeSet attrs, int defStyle) {
-            super(context, attrs, defStyle);
+        public RecycleListView(Context context, AttributeSet attrs, int defStyleAttr) {
+            super(context, attrs, defStyleAttr);
+        }
+
+        public RecycleListView(
+                Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+            super(context, attrs, defStyleAttr, defStyleRes);
         }
 
         @Override
@@ -769,6 +798,7 @@
         public CharSequence[] mItems;
         public ListAdapter mAdapter;
         public DialogInterface.OnClickListener mOnClickListener;
+        public int mViewLayoutResId;
         public View mView;
         public int mViewSpacingLeft;
         public int mViewSpacingTop;
@@ -854,8 +884,10 @@
                 } else {
                     dialog.setView(mView);
                 }
+            } else if (mViewLayoutResId != 0) {
+                dialog.setView(mViewLayoutResId);
             }
-            
+
             /*
             dialog.setCancelable(mCancelable);
             dialog.setOnCancelListener(mOnCancelListener);
diff --git a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
index 3d46cdd..83ad9dc 100644
--- a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
+++ b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
@@ -32,7 +32,6 @@
 import android.view.View;
 import android.view.Window;
 import android.view.View.OnClickListener;
-import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
 
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 43c4b49..0771329 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -22,17 +22,15 @@
 import android.telephony.SignalStrength;
 
 interface IBatteryStats {
+    // These first methods are also called by native code, so must
+    // be kept in sync with frameworks/native/include/binder/IBatteryStats.h
+    void noteStartSensor(int uid, int sensor);
+    void noteStopSensor(int uid, int sensor);
+
+    // Remaining methods are only used in Java.
     byte[] getStatistics();
     void noteStartWakelock(int uid, int pid, String name, int type);
     void noteStopWakelock(int uid, int pid, String name, int type);
-    
-    /* DO NOT CHANGE the position of noteStartSensor without updating
-       SensorService.cpp */
-    void noteStartSensor(int uid, int sensor);
-
-    /* DO NOT CHANGE the position of noteStopSensor without updating
-       SensorService.cpp */
-    void noteStopSensor(int uid, int sensor);
 
     void noteStartWakelockFromSource(in WorkSource ws, int pid, String name, int type);
     void noteStopWakelockFromSource(in WorkSource ws, int pid, String name, int type);
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
index ae362af..237feed 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.view.View;
-import android.view.View.OnClickListener;
 
 /**
  * Media route chooser dialog fragment.
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 40a705c..8cdaf91 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -18,7 +18,6 @@
 
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
-import android.content.Context;
 import android.content.Intent;
 import android.graphics.Typeface;
 import android.provider.Settings;
@@ -26,19 +25,15 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.text.method.AllCapsTransformationMethod;
-import android.text.method.TransformationMethod;
 import android.util.DisplayMetrics;
 import android.view.Gravity;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.AnticipateOvershootInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
 import android.widget.TextView;
-import android.widget.Toast;
 
 public class PlatLogoActivity extends Activity {
     FrameLayout mContent;
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index 494bc78..a3323e9 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -23,22 +23,17 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Environment;
 import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
 import android.os.SELinux;
 import android.util.Log;
 
 import com.android.org.bouncycastle.util.encoders.Base64;
 
 import java.io.File;
-import java.io.FileFilter;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.util.ArrayList;
 
 /**
  * Backup transport for stashing stuff into a known location on disk, and
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index ab871fb..3798d62 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -22,7 +22,6 @@
 import android.content.IntentFilter;
 import android.net.Uri;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.UserHandle;
 import com.android.internal.os.BackgroundThread;
diff --git a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
new file mode 100644
index 0000000..dcc0a4c
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -0,0 +1,299 @@
+/*
+ * 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.internal.inputmethod;
+
+import com.android.internal.inputmethod.InputMethodUtils.InputMethodSettings;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.text.TextUtils;
+import android.util.Slog;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodSubtype;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.TreeMap;
+
+/**
+ * InputMethodSubtypeSwitchingController controls the switching behavior of the subtypes.
+ */
+public class InputMethodSubtypeSwitchingController {
+    private static final String TAG = InputMethodSubtypeSwitchingController.class.getSimpleName();
+    private static final boolean DEBUG = false;
+    // TODO: Turn on this flag and add CTS when the platform starts expecting that all IMEs return
+    // true for supportsSwitchingToNextInputMethod().
+    private static final boolean REQUIRE_SWITCHING_SUPPORT = false;
+    private static final int MAX_HISTORY_SIZE = 4;
+    private static final int NOT_A_SUBTYPE_ID = InputMethodUtils.NOT_A_SUBTYPE_ID;
+
+    private static class SubtypeParams {
+        public final InputMethodInfo mImi;
+        public final InputMethodSubtype mSubtype;
+        public final long mTime;
+
+        public SubtypeParams(InputMethodInfo imi, InputMethodSubtype subtype) {
+            mImi = imi;
+            mSubtype = subtype;
+            mTime = System.currentTimeMillis();
+        }
+    }
+
+    public static class ImeSubtypeListItem implements Comparable<ImeSubtypeListItem> {
+        public final CharSequence mImeName;
+        public final CharSequence mSubtypeName;
+        public final InputMethodInfo mImi;
+        public final int mSubtypeId;
+        private final boolean mIsSystemLocale;
+        private final boolean mIsSystemLanguage;
+
+        public ImeSubtypeListItem(CharSequence imeName, CharSequence subtypeName,
+                InputMethodInfo imi, int subtypeId, String subtypeLocale, String systemLocale) {
+            mImeName = imeName;
+            mSubtypeName = subtypeName;
+            mImi = imi;
+            mSubtypeId = subtypeId;
+            if (TextUtils.isEmpty(subtypeLocale)) {
+                mIsSystemLocale = false;
+                mIsSystemLanguage = false;
+            } else {
+                mIsSystemLocale = subtypeLocale.equals(systemLocale);
+                mIsSystemLanguage = mIsSystemLocale
+                        || subtypeLocale.startsWith(systemLocale.substring(0, 2));
+            }
+        }
+
+        @Override
+        public int compareTo(ImeSubtypeListItem other) {
+            if (TextUtils.isEmpty(mImeName)) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(other.mImeName)) {
+                return -1;
+            }
+            if (!TextUtils.equals(mImeName, other.mImeName)) {
+                return mImeName.toString().compareTo(other.mImeName.toString());
+            }
+            if (TextUtils.equals(mSubtypeName, other.mSubtypeName)) {
+                return 0;
+            }
+            if (mIsSystemLocale) {
+                return -1;
+            }
+            if (other.mIsSystemLocale) {
+                return 1;
+            }
+            if (mIsSystemLanguage) {
+                return -1;
+            }
+            if (other.mIsSystemLanguage) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(mSubtypeName)) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(other.mSubtypeName)) {
+                return -1;
+            }
+            return mSubtypeName.toString().compareTo(other.mSubtypeName.toString());
+        }
+    }
+
+    private static class InputMethodAndSubtypeCircularList {
+        private final Context mContext;
+        // Used to load label
+        private final PackageManager mPm;
+        private final String mSystemLocaleStr;
+        private final InputMethodSettings mSettings;
+
+        public InputMethodAndSubtypeCircularList(Context context, InputMethodSettings settings) {
+            mContext = context;
+            mSettings = settings;
+            mPm = context.getPackageManager();
+            final Locale locale = context.getResources().getConfiguration().locale;
+            mSystemLocaleStr = locale != null ? locale.toString() : "";
+        }
+
+        private final TreeMap<InputMethodInfo, List<InputMethodSubtype>> mSortedImmis =
+                new TreeMap<InputMethodInfo, List<InputMethodSubtype>>(
+                        new Comparator<InputMethodInfo>() {
+                            @Override
+                            public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
+                                if (imi2 == null)
+                                    return 0;
+                                if (imi1 == null)
+                                    return 1;
+                                if (mPm == null) {
+                                    return imi1.getId().compareTo(imi2.getId());
+                                }
+                                CharSequence imiId1 = imi1.loadLabel(mPm) + "/" + imi1.getId();
+                                CharSequence imiId2 = imi2.loadLabel(mPm) + "/" + imi2.getId();
+                                return imiId1.toString().compareTo(imiId2.toString());
+                            }
+                        });
+
+        public ImeSubtypeListItem getNextInputMethod(
+                boolean onlyCurrentIme, InputMethodInfo imi, InputMethodSubtype subtype) {
+            if (imi == null) {
+                return null;
+            }
+            final List<ImeSubtypeListItem> imList =
+                    getSortedInputMethodAndSubtypeList();
+            if (imList.size() <= 1) {
+                return null;
+            }
+            final int N = imList.size();
+            final int currentSubtypeId =
+                    subtype != null ? InputMethodUtils.getSubtypeIdFromHashCode(imi,
+                            subtype.hashCode()) : NOT_A_SUBTYPE_ID;
+            for (int i = 0; i < N; ++i) {
+                final ImeSubtypeListItem isli = imList.get(i);
+                if (isli.mImi.equals(imi) && isli.mSubtypeId == currentSubtypeId) {
+                    if (!onlyCurrentIme) {
+                        return imList.get((i + 1) % N);
+                    }
+                    for (int j = 0; j < N - 1; ++j) {
+                        final ImeSubtypeListItem candidate = imList.get((i + j + 1) % N);
+                        if (candidate.mImi.equals(imi)) {
+                            return candidate;
+                        }
+                    }
+                    return null;
+                }
+            }
+            return null;
+        }
+
+        public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList() {
+            return getSortedInputMethodAndSubtypeList(true, false, false);
+        }
+
+        public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(
+                boolean showSubtypes, boolean inputShown, boolean isScreenLocked) {
+            final ArrayList<ImeSubtypeListItem> imList =
+                    new ArrayList<ImeSubtypeListItem>();
+            final HashMap<InputMethodInfo, List<InputMethodSubtype>> immis =
+                    mSettings.getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked(
+                            mContext);
+            if (immis == null || immis.size() == 0) {
+                return Collections.emptyList();
+            }
+            mSortedImmis.clear();
+            mSortedImmis.putAll(immis);
+            for (InputMethodInfo imi : mSortedImmis.keySet()) {
+                if (imi == null) {
+                    continue;
+                }
+                List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypeList = immis.get(imi);
+                HashSet<String> enabledSubtypeSet = new HashSet<String>();
+                for (InputMethodSubtype subtype : explicitlyOrImplicitlyEnabledSubtypeList) {
+                    enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
+                }
+                final CharSequence imeLabel = imi.loadLabel(mPm);
+                if (showSubtypes && enabledSubtypeSet.size() > 0) {
+                    final int subtypeCount = imi.getSubtypeCount();
+                    if (DEBUG) {
+                        Slog.v(TAG, "Add subtypes: " + subtypeCount + ", " + imi.getId());
+                    }
+                    for (int j = 0; j < subtypeCount; ++j) {
+                        final InputMethodSubtype subtype = imi.getSubtypeAt(j);
+                        final String subtypeHashCode = String.valueOf(subtype.hashCode());
+                        // We show all enabled IMEs and subtypes when an IME is shown.
+                        if (enabledSubtypeSet.contains(subtypeHashCode)
+                                && ((inputShown && !isScreenLocked) || !subtype.isAuxiliary())) {
+                            final CharSequence subtypeLabel =
+                                    subtype.overridesImplicitlyEnabledSubtype() ? null : subtype
+                                            .getDisplayName(mContext, imi.getPackageName(),
+                                                    imi.getServiceInfo().applicationInfo);
+                            imList.add(new ImeSubtypeListItem(imeLabel,
+                                    subtypeLabel, imi, j, subtype.getLocale(), mSystemLocaleStr));
+
+                            // Removing this subtype from enabledSubtypeSet because we no
+                            // longer need to add an entry of this subtype to imList to avoid
+                            // duplicated entries.
+                            enabledSubtypeSet.remove(subtypeHashCode);
+                        }
+                    }
+                } else {
+                    imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID, null,
+                            mSystemLocaleStr));
+                }
+            }
+            Collections.sort(imList);
+            return imList;
+        }
+    }
+
+    private final ArrayDeque<SubtypeParams> mTypedSubtypeHistory = new ArrayDeque<SubtypeParams>();
+    private final Object mLock = new Object();
+    private final InputMethodSettings mSettings;
+    private InputMethodAndSubtypeCircularList mSubtypeList;
+
+    public InputMethodSubtypeSwitchingController(InputMethodSettings settings) {
+        mSettings = settings;
+    }
+
+    // TODO: write unit tests for this method and the logic that determines the next subtype
+    public void onCommitText(InputMethodInfo imi, InputMethodSubtype subtype) {
+        synchronized (mTypedSubtypeHistory) {
+            if (subtype == null) {
+                Slog.w(TAG, "Invalid InputMethodSubtype: " + imi.getId() + ", " + subtype);
+                return;
+            }
+            if (DEBUG) {
+                Slog.d(TAG, "onCommitText: " + imi.getId() + ", " + subtype);
+            }
+            if (REQUIRE_SWITCHING_SUPPORT) {
+                if (!imi.supportsSwitchingToNextInputMethod()) {
+                    Slog.w(TAG, imi.getId() + " doesn't support switching to next input method.");
+                    return;
+                }
+            }
+            if (mTypedSubtypeHistory.size() >= MAX_HISTORY_SIZE) {
+                mTypedSubtypeHistory.poll();
+            }
+            mTypedSubtypeHistory.addFirst(new SubtypeParams(imi, subtype));
+        }
+    }
+
+    public void resetCircularListLocked(Context context) {
+        synchronized(mLock) {
+            mSubtypeList = new InputMethodAndSubtypeCircularList(context, mSettings);
+        }
+    }
+
+    public ImeSubtypeListItem getNextInputMethod(
+            boolean onlyCurrentIme, InputMethodInfo imi, InputMethodSubtype subtype) {
+        synchronized(mLock) {
+            return mSubtypeList.getNextInputMethod(onlyCurrentIme, imi, subtype);
+        }
+    }
+
+    public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(boolean showSubtypes,
+            boolean inputShown, boolean isScreenLocked) {
+        synchronized(mLock) {
+            return mSubtypeList.getSortedInputMethodAndSubtypeList(
+                    showSubtypes, inputShown, isScreenLocked);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 63d018f..bc051ce 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -959,5 +959,16 @@
                 addSubtypeToHistory(curMethodId, subtypeId);
             }
         }
+
+        public HashMap<InputMethodInfo, List<InputMethodSubtype>>
+                getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked(Context context) {
+            HashMap<InputMethodInfo, List<InputMethodSubtype>> enabledInputMethodAndSubtypes =
+                    new HashMap<InputMethodInfo, List<InputMethodSubtype>>();
+            for (InputMethodInfo imi: getEnabledInputMethodListLocked()) {
+                enabledInputMethodAndSubtypes.put(
+                        imi, getEnabledInputMethodSubtypeListLocked(context, imi, true));
+            }
+            return enabledInputMethodAndSubtypes;
+        }
     }
 }
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
index 98599d0..0d00f41 100644
--- a/core/java/com/android/internal/net/VpnConfig.java
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -25,8 +25,6 @@
 import android.net.RouteInfo;
 import android.net.LinkAddress;
 
-import com.android.internal.util.Preconditions;
-
 import java.net.InetAddress;
 import java.util.List;
 import java.util.ArrayList;
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 0a702ff..2e5fcec 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -4839,7 +4839,7 @@
                 mHistoryCur.batteryStatus = (byte)status;
                 mHistoryCur.batteryHealth = (byte)health;
                 mHistoryCur.batteryPlugType = (byte)plugType;
-                mHistoryCur.batteryTemperature = (char)temp;
+                mHistoryCur.batteryTemperature = (short)temp;
                 mHistoryCur.batteryVoltage = (char)volt;
                 setOnBatteryLocked(onBattery, oldStatus, level);
             } else {
@@ -4862,7 +4862,7 @@
                 }
                 if (temp >= (mHistoryCur.batteryTemperature+10)
                         || temp <= (mHistoryCur.batteryTemperature-10)) {
-                    mHistoryCur.batteryTemperature = (char)temp;
+                    mHistoryCur.batteryTemperature = (short)temp;
                     changed = true;
                 }
                 if (volt > (mHistoryCur.batteryVoltage+20)
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index f54a3e9..9841f62 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -16,18 +16,10 @@
 
 package com.android.internal.os;
 
-import android.os.Binder;
 import android.os.IBinder;
 import android.os.SystemClock;
 import android.util.EventLog;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
-import java.lang.reflect.Modifier;
 
 /**
  * Private and debugging Binder APIs.
diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index c6b3e7c..1766f7b 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -25,7 +25,6 @@
 import java.io.IOException;
 
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 import dalvik.system.Zygote;
 
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index fd7e3b0..4f3b5b3 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -197,10 +197,14 @@
 
         try {
             parsedArgs = new Arguments(args);
+            if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
+                throw new ZygoteSecurityException("Client may not specify capabilities: " +
+                        "permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) +
+                        ", effective=0x" + Long.toHexString(parsedArgs.effectiveCapabilities));
+            }
 
             applyUidSecurityPolicy(parsedArgs, peer, peerSecurityContext);
             applyRlimitSecurityPolicy(parsedArgs, peer, peerSecurityContext);
-            applyCapabilitiesSecurityPolicy(parsedArgs, peer, peerSecurityContext);
             applyInvokeWithSecurityPolicy(parsedArgs, peer, peerSecurityContext);
             applyseInfoSecurityPolicy(parsedArgs, peer, peerSecurityContext);
 
@@ -703,71 +707,6 @@
     }
 
     /**
-     * Applies zygote security policy per bug #1042973. A root peer may
-     * spawn an instance with any capabilities. All other uids may spawn
-     * instances with any of the capabilities in the peer's permitted set
-     * but no more.
-     *
-     * @param args non-null; zygote spawner arguments
-     * @param peer non-null; peer credentials
-     * @throws ZygoteSecurityException
-     */
-    private static void applyCapabilitiesSecurityPolicy(
-            Arguments args, Credentials peer, String peerSecurityContext)
-            throws ZygoteSecurityException {
-
-        if (args.permittedCapabilities == 0
-                && args.effectiveCapabilities == 0) {
-            // nothing to check
-            return;
-        }
-
-        boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
-                                                     peerSecurityContext,
-                                                     "zygote",
-                                                     "specifycapabilities");
-        if (!allowed) {
-            throw new ZygoteSecurityException(
-                    "Peer may not specify capabilities");
-        }
-
-        if (peer.getUid() == 0) {
-            // root may specify anything
-            return;
-        }
-
-        long permittedCaps;
-
-        try {
-            permittedCaps = ZygoteInit.capgetPermitted(peer.getPid());
-        } catch (IOException ex) {
-            throw new ZygoteSecurityException(
-                    "Error retrieving peer's capabilities.");
-        }
-
-        /*
-         * Ensure that the client did not specify an effective set larger
-         * than the permitted set. The kernel will enforce this too, but we
-         * do it here to make the following check easier.
-         */
-        if (((~args.permittedCapabilities) & args.effectiveCapabilities) != 0) {
-            throw new ZygoteSecurityException(
-                    "Effective capabilities cannot be superset of "
-                            + " permitted capabilities" );
-        }
-
-        /*
-         * Ensure that the new permitted (and thus the new effective) set is
-         * a subset of the peer process's permitted set
-         */
-
-        if (((~permittedCaps) & args.permittedCapabilities) != 0) {
-            throw new ZygoteSecurityException(
-                    "Peer specified unpermitted capabilities" );
-        }
-    }
-
-    /**
      * Applies zygote security policy.
      * Based on the credentials of the process issuing a zygote command:
      * <ol>
@@ -803,7 +742,7 @@
     }
 
     /**
-     * Applies zygote security policy for SEAndroid information.
+     * Applies zygote security policy for SELinux information.
      *
      * @param args non-null; zygote spawner arguments
      * @param peer non-null; peer credentials
@@ -822,7 +761,7 @@
         if (!(peerUid == 0 || peerUid == Process.SYSTEM_UID)) {
             // All peers with UID other than root or SYSTEM_UID
             throw new ZygoteSecurityException(
-                    "This UID may not specify SEAndroid info.");
+                    "This UID may not specify SELinux info.");
         }
 
         boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
@@ -831,7 +770,7 @@
                                                      "specifyseinfo");
         if (!allowed) {
             throw new ZygoteSecurityException(
-                    "Peer may not specify SEAndroid info");
+                    "Peer may not specify SELinux info");
         }
 
         return;
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index c44afae..48092f6 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -489,6 +489,7 @@
     private static boolean startSystemServer()
             throws MethodAndArgsCaller, RuntimeException {
         long capabilities = posixCapabilitiesAsBits(
+            OsConstants.CAP_BLOCK_SUSPEND,
             OsConstants.CAP_KILL,
             OsConstants.CAP_NET_ADMIN,
             OsConstants.CAP_NET_BIND_SERVICE,
@@ -722,15 +723,6 @@
             throws IOException;
 
     /**
-     * Retrieves the permitted capability set from another process.
-     *
-     * @param pid &gt;=0 process ID or 0 for this process
-     * @throws IOException on error
-     */
-    static native long capgetPermitted(int pid)
-            throws IOException;
-
-    /**
      * Invokes select() on the provider array of file descriptors (selecting
      * for readability only). Array elements of null are ignored.
      *
diff --git a/core/java/com/android/internal/preference/YesNoPreference.java b/core/java/com/android/internal/preference/YesNoPreference.java
index cf68a58..7abf416 100644
--- a/core/java/com/android/internal/preference/YesNoPreference.java
+++ b/core/java/com/android/internal/preference/YesNoPreference.java
@@ -31,15 +31,19 @@
  */
 public class YesNoPreference extends DialogPreference {
     private boolean mWasPositiveResult;
-    
-    public YesNoPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+
+    public YesNoPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public YesNoPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
     public YesNoPreference(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.yesNoPreferenceStyle);
     }
-    
+
     public YesNoPreference(Context context) {
         this(context, null);
     }
diff --git a/core/java/com/android/internal/view/ActionBarPolicy.java b/core/java/com/android/internal/view/ActionBarPolicy.java
index 25086c5..bee59dc 100644
--- a/core/java/com/android/internal/view/ActionBarPolicy.java
+++ b/core/java/com/android/internal/view/ActionBarPolicy.java
@@ -19,11 +19,9 @@
 import com.android.internal.R;
 
 import android.content.Context;
-import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.os.Build;
-import android.view.ViewConfiguration;
 
 /**
  * Allows components to query for various configuration policy decisions
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 12ced68..325a27d 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -74,4 +74,6 @@
     boolean shouldOfferSwitchingToNextInputMethod(in IBinder token);
     boolean setInputMethodEnabled(String id, boolean enabled);
     oneway void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
+    int getInputMethodWindowVisibleHeight();
+    oneway void notifyTextCommitted();
 }
diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java
index 70e2bfc..df4e1a6 100644
--- a/core/java/com/android/internal/view/RotationPolicy.java
+++ b/core/java/com/android/internal/view/RotationPolicy.java
@@ -21,7 +21,6 @@
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.AsyncTask;
-import android.os.Build;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.UserHandle;
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItemView.java b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
index 238a9c0..c14d587 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
@@ -60,13 +60,17 @@
         this(context, attrs, 0);
     }
 
-    public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ActionMenuItemView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ActionMenuItemView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         final Resources res = context.getResources();
         mAllowTextWithIcon = res.getBoolean(
                 com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.ActionMenuItemView, 0, 0);
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.ActionMenuItemView, defStyleAttr, defStyleRes);
         mMinWidth = a.getDimensionPixelSize(
                 com.android.internal.R.styleable.ActionMenuItemView_minWidth, 0);
         a.recycle();
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 4654178..11c4777 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -21,8 +21,6 @@
 import android.content.res.Resources;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.transition.Transition;
-import android.transition.TransitionManager;
 import android.util.SparseBooleanArray;
 import android.view.ActionProvider;
 import android.view.Gravity;
diff --git a/core/java/com/android/internal/view/menu/IconMenuItemView.java b/core/java/com/android/internal/view/menu/IconMenuItemView.java
index 5d0b25f..de5e279 100644
--- a/core/java/com/android/internal/view/menu/IconMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/IconMenuItemView.java
@@ -57,8 +57,8 @@
     
     private static String sPrependShortcutLabel;
 
-    public IconMenuItemView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs);
+    public IconMenuItemView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         if (sPrependShortcutLabel == null) {
             /*
@@ -68,10 +68,9 @@
             sPrependShortcutLabel = getResources().getString(
                     com.android.internal.R.string.prepend_shortcut_label);
         }
-        
-        TypedArray a =
-            context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.MenuView, defStyle, 0);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.MenuView, defStyleAttr, defStyleRes);
 
         mDisabledAlpha = a.getFloat(
                 com.android.internal.R.styleable.MenuView_itemIconDisabledAlpha, 0.8f);
@@ -81,7 +80,11 @@
         
         a.recycle();
     }
-    
+
+    public IconMenuItemView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public IconMenuItemView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java
index a2a4acc..692bdac 100644
--- a/core/java/com/android/internal/view/menu/ListMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java
@@ -55,13 +55,13 @@
 
     private boolean mForceShowIcon;
 
-    public ListMenuItemView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs);
-    
-        TypedArray a =
-            context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.MenuView, defStyle, 0);
-        
+    public ListMenuItemView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.MenuView, defStyleAttr, defStyleRes);
+
         mBackground = a.getDrawable(com.android.internal.R.styleable.MenuView_itemBackground);
         mTextAppearance = a.getResourceId(com.android.internal.R.styleable.
                                           MenuView_itemTextAppearance, -1);
@@ -72,6 +72,10 @@
         a.recycle();
     }
 
+    public ListMenuItemView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public ListMenuItemView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
diff --git a/core/java/com/android/internal/view/menu/ListMenuPresenter.java b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
index 4882adc..c476354 100644
--- a/core/java/com/android/internal/view/menu/ListMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
@@ -17,7 +17,6 @@
 package com.android.internal.view.menu;
 
 import android.content.Context;
-import android.database.DataSetObserver;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.util.SparseArray;
@@ -163,7 +162,7 @@
 
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        mMenu.performItemAction(mAdapter.getItem(position), 0);
+        mMenu.performItemAction(mAdapter.getItem(position), this, 0);
     }
 
     @Override
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index aff697a..195a00d 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -247,11 +247,17 @@
         startDispatchingItemsChanged();
     }
     
-    private boolean dispatchSubMenuSelected(SubMenuBuilder subMenu) {
+    private boolean dispatchSubMenuSelected(SubMenuBuilder subMenu,
+            MenuPresenter preferredPresenter) {
         if (mPresenters.isEmpty()) return false;
 
         boolean result = false;
 
+        // Try the preferred presenter first.
+        if (preferredPresenter != null) {
+            result = preferredPresenter.onSubMenuSelected(subMenu);
+        }
+
         for (WeakReference<MenuPresenter> ref : mPresenters) {
             final MenuPresenter presenter = ref.get();
             if (presenter == null) {
@@ -865,6 +871,10 @@
     }
 
     public boolean performItemAction(MenuItem item, int flags) {
+        return performItemAction(item, null, flags);
+    }
+
+    public boolean performItemAction(MenuItem item, MenuPresenter preferredPresenter, int flags) {
         MenuItemImpl itemImpl = (MenuItemImpl) item;
         
         if (itemImpl == null || !itemImpl.isEnabled()) {
@@ -889,7 +899,7 @@
             if (providerHasSubMenu) {
                 provider.onPrepareSubMenu(subMenu);
             }
-            invoked |= dispatchSubMenuSelected(subMenu);
+            invoked |= dispatchSubMenuSelected(subMenu, preferredPresenter);
             if (!invoked) close(true);
         } else {
             if ((flags & FLAG_PERFORM_NO_CLOSE) == 0) {
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 05e9a66..d664058 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -23,7 +23,6 @@
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java
index f3891c7..6ea7372 100644
--- a/core/java/com/android/internal/widget/AbsActionBarView.java
+++ b/core/java/com/android/internal/widget/AbsActionBarView.java
@@ -47,15 +47,20 @@
     private static final int FADE_DURATION = 200;
 
     public AbsActionBarView(Context context) {
-        super(context);
+        this(context, null);
     }
 
     public AbsActionBarView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
     }
 
-    public AbsActionBarView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public AbsActionBarView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AbsActionBarView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java
index 8a49899..03fa9b4 100644
--- a/core/java/com/android/internal/widget/ActionBarContainer.java
+++ b/core/java/com/android/internal/widget/ActionBarContainer.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.widget;
 
-import android.app.ActionBar;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 8bc1081..0cacaa5 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -25,7 +25,6 @@
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
@@ -74,10 +73,16 @@
         this(context, attrs, com.android.internal.R.attr.actionModeStyle);
     }
     
-    public ActionBarContextView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionMode, defStyle, 0);
+    public ActionBarContextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ActionBarContextView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.ActionMode, defStyleAttr, defStyleRes);
         setBackgroundDrawable(a.getDrawable(
                 com.android.internal.R.styleable.ActionMode_background));
         mTitleStyleRes = a.getResourceId(
diff --git a/core/java/com/android/internal/widget/DialogTitle.java b/core/java/com/android/internal/widget/DialogTitle.java
index b86c438..7ea3d6b 100644
--- a/core/java/com/android/internal/widget/DialogTitle.java
+++ b/core/java/com/android/internal/widget/DialogTitle.java
@@ -28,10 +28,13 @@
  * the text to the available space.
  */
 public class DialogTitle extends TextView {
-    
-    public DialogTitle(Context context, AttributeSet attrs,
-            int defStyle) {
-        super(context, attrs, defStyle);
+
+    public DialogTitle(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public DialogTitle(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
     }
 
     public DialogTitle(Context context, AttributeSet attrs) {
diff --git a/core/java/com/android/internal/widget/FaceUnlockView.java b/core/java/com/android/internal/widget/FaceUnlockView.java
index e3c1247..121e601 100644
--- a/core/java/com/android/internal/widget/FaceUnlockView.java
+++ b/core/java/com/android/internal/widget/FaceUnlockView.java
@@ -18,8 +18,6 @@
 
 import android.content.Context;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
 import android.widget.RelativeLayout;
 
 public class FaceUnlockView extends RelativeLayout {
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 8602260..3419f15 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -24,7 +24,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -1201,7 +1200,7 @@
 
     private void setLong(String secureSettingKey, long value, int userHandle) {
         try {
-            getLockSettings().setLong(secureSettingKey, value, getCurrentOrCallingUserId());
+            getLockSettings().setLong(secureSettingKey, value, userHandle);
         } catch (RemoteException re) {
             // What can we do?
             Log.e(TAG, "Couldn't write long " + secureSettingKey + re);
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
index 3c01c69..8368136 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.widget;
 
-import java.util.Locale;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index a3df291..b2c9dc5 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -21,9 +21,7 @@
 import android.inputmethodservice.Keyboard;
 import android.inputmethodservice.KeyboardView;
 import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
-import android.os.Handler;
 import android.os.SystemClock;
-import android.os.Vibrator;
 import android.provider.Settings;
 import android.util.Log;
 import android.view.HapticFeedbackConstants;
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
index b37adff..d27346b 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
@@ -29,11 +29,16 @@
     static final int KEYCODE_NEXT_LANGUAGE = -104;
 
     public PasswordEntryKeyboardView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
     }
 
-    public PasswordEntryKeyboardView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public PasswordEntryKeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public PasswordEntryKeyboardView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index d82831f..e339c44 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -31,11 +31,13 @@
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.view.WindowManagerPolicy.PointerEventListener;
 import android.view.MotionEvent.PointerCoords;
 
 import java.util.ArrayList;
 
-public class PointerLocationView extends View implements InputDeviceListener {
+public class PointerLocationView extends View implements InputDeviceListener,
+        PointerEventListener {
     private static final String TAG = "Pointer";
 
     // The system property key used to specify an alternate velocity tracker strategy
@@ -520,7 +522,8 @@
                 .toString());
     }
 
-    public void addPointerEvent(MotionEvent event) {
+    @Override
+    public void onPointerEvent(MotionEvent event) {
         final int action = event.getAction();
         int NP = mPointers.size();
 
@@ -648,7 +651,7 @@
     
     @Override
     public boolean onTouchEvent(MotionEvent event) {
-        addPointerEvent(event);
+        onPointerEvent(event);
 
         if (event.getAction() == MotionEvent.ACTION_DOWN && !isFocused()) {
             requestFocus();
@@ -660,7 +663,7 @@
     public boolean onGenericMotionEvent(MotionEvent event) {
         final int source = event.getSource();
         if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-            addPointerEvent(event);
+            onPointerEvent(event);
         } else if ((source & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
             logMotionEvent("Joystick", event);
         } else if ((source & InputDevice.SOURCE_CLASS_POSITION) != 0) {
diff --git a/core/java/com/android/internal/widget/RotarySelector.java b/core/java/com/android/internal/widget/RotarySelector.java
index 4e405f4..f856027 100644
--- a/core/java/com/android/internal/widget/RotarySelector.java
+++ b/core/java/com/android/internal/widget/RotarySelector.java
@@ -24,7 +24,6 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Matrix;
-import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 import android.os.Vibrator;
 import android.provider.Settings;
diff --git a/core/java/com/android/internal/widget/ScrollingTabContainerView.java b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
index fa29e6e1..d6bd1d6f 100644
--- a/core/java/com/android/internal/widget/ScrollingTabContainerView.java
+++ b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
@@ -23,7 +23,6 @@
 import android.app.ActionBar;
 import android.content.Context;
 import android.content.res.Configuration;
-import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 import android.text.TextUtils.TruncateAt;
diff --git a/core/java/com/android/internal/widget/SizeAdaptiveLayout.java b/core/java/com/android/internal/widget/SizeAdaptiveLayout.java
index ba113a3..72606565 100644
--- a/core/java/com/android/internal/widget/SizeAdaptiveLayout.java
+++ b/core/java/com/android/internal/widget/SizeAdaptiveLayout.java
@@ -79,17 +79,20 @@
     private int mModestyPanelTop;
 
     public SizeAdaptiveLayout(Context context) {
-        super(context);
-        initialize();
+        this(context, null);
     }
 
     public SizeAdaptiveLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        initialize();
+        this(context, attrs, 0);
     }
 
-    public SizeAdaptiveLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public SizeAdaptiveLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public SizeAdaptiveLayout(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initialize();
     }
 
diff --git a/core/java/com/android/internal/widget/SubtitleView.java b/core/java/com/android/internal/widget/SubtitleView.java
index 071193c..0b6790c 100644
--- a/core/java/com/android/internal/widget/SubtitleView.java
+++ b/core/java/com/android/internal/widget/SubtitleView.java
@@ -18,7 +18,6 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.res.Resources.Theme;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -33,7 +32,6 @@
 import android.text.TextPaint;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
-import android.util.TypedValue;
 import android.view.View;
 import android.view.accessibility.CaptioningManager.CaptionStyle;
 
@@ -79,12 +77,15 @@
         this(context, attrs, 0);
     }
 
-    public SubtitleView(Context context, AttributeSet attrs, int defStyle) {
+    public SubtitleView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public SubtitleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs);
 
-        final Theme theme = context.getTheme();
-        final TypedArray a = theme.obtainStyledAttributes(
-                    attrs, android.R.styleable.TextView, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                    attrs, android.R.styleable.TextView, defStyleAttr, defStyleRes);
 
         CharSequence text = "";
         int textSize = 15;
diff --git a/core/java/com/android/internal/widget/TextProgressBar.java b/core/java/com/android/internal/widget/TextProgressBar.java
index e898aa4..7ca07d4 100644
--- a/core/java/com/android/internal/widget/TextProgressBar.java
+++ b/core/java/com/android/internal/widget/TextProgressBar.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.os.SystemClock;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -59,9 +58,13 @@
 
     boolean mChronometerFollow = false;
     int mChronometerGravity = Gravity.NO_GRAVITY;
+
+    public TextProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
     
-    public TextProgressBar(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TextProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
     }
 
     public TextProgressBar(Context context, AttributeSet attrs) {
diff --git a/core/java/com/android/internal/widget/WaveView.java b/core/java/com/android/internal/widget/WaveView.java
index d33d50c..0c5993b 100644
--- a/core/java/com/android/internal/widget/WaveView.java
+++ b/core/java/com/android/internal/widget/WaveView.java
@@ -28,7 +28,6 @@
 import android.os.UserHandle;
 import android.os.Vibrator;
 import android.provider.Settings;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.MotionEvent;
diff --git a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
index 16bec16..5a4c441 100644
--- a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
+++ b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
@@ -18,7 +18,6 @@
 
 import android.content.res.Resources;
 import android.graphics.Canvas;
-import android.graphics.ColorFilter;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
 import android.util.Log;
diff --git a/core/java/com/android/server/net/BaseNetworkObserver.java b/core/java/com/android/server/net/BaseNetworkObserver.java
index fa54c5f..1e80a21 100644
--- a/core/java/com/android/server/net/BaseNetworkObserver.java
+++ b/core/java/com/android/server/net/BaseNetworkObserver.java
@@ -17,6 +17,7 @@
 package com.android.server.net;
 
 import android.net.INetworkManagementEventObserver;
+import android.net.LinkAddress;
 
 /**
  * Base {@link INetworkManagementEventObserver} that provides no-op
@@ -36,12 +37,12 @@
     }
 
     @Override
-    public void addressUpdated(String address, String iface, int flags, int scope) {
+    public void addressUpdated(LinkAddress address, String iface, int flags, int scope) {
         // default no-op
     }
 
     @Override
-    public void addressRemoved(String address, String iface, int flags, int scope) {
+    public void addressRemoved(LinkAddress address, String iface, int flags, int scope) {
         // default no-op
     }
 
@@ -64,4 +65,9 @@
     public void limitReached(String limitName, String iface) {
         // default no-op
     }
+
+    @Override
+    public void interfaceDnsServerInfo(String iface, long lifetime, String[] servers) {
+        // default no-op
+    }
 }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 5983120..ca519d1 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_CFLAGS += -DHAVE_CONFIG_H -DKHTML_NO_EXCEPTIONS -DGKWQ_NO_JAVA
 LOCAL_CFLAGS += -DNO_SUPPORT_JS_BINDING -DQT_NO_WHEELEVENT -DKHTML_NO_XBL
 LOCAL_CFLAGS += -U__APPLE__
+LOCAL_CFLAGS += -Wno-unused-parameter
 
 ifeq ($(TARGET_ARCH), arm)
 	LOCAL_CFLAGS += -DPACKED="__attribute__ ((packed))"
@@ -50,8 +51,8 @@
 	android_view_InputQueue.cpp \
 	android_view_KeyEvent.cpp \
 	android_view_KeyCharacterMap.cpp \
-	android_view_HardwareRenderer.cpp \
 	android_view_GraphicBuffer.cpp \
+	android_view_GLRenderer.cpp \
 	android_view_GLES20DisplayList.cpp \
 	android_view_GLES20Canvas.cpp \
 	android_view_MotionEvent.cpp \
@@ -114,6 +115,7 @@
 	android/graphics/TextLayout.cpp \
 	android/graphics/TextLayoutCache.cpp \
 	android/graphics/Typeface.cpp \
+	android/graphics/TypefaceImpl.cpp \
 	android/graphics/Utils.cpp \
 	android/graphics/Xfermode.cpp \
 	android/graphics/YuvToJpegEncoder.cpp \
@@ -206,7 +208,6 @@
 	libicuuc \
 	libicui18n \
 	libmedia \
-	libwpa_client \
 	libjpeg \
 	libusbhost \
 	libharfbuzz_ng \
@@ -216,6 +217,16 @@
 	LOCAL_SHARED_LIBRARIES += libhwui
 endif
 
+ifeq ($(USE_MINIKIN), true)
+	LOCAL_CFLAGS += -DUSE_MINIKIN
+	LOCAL_C_INCLUDES += frameworks/minikin/include \
+		external/freetype/include
+	LOCAL_SRC_FILES += 	android/graphics/MinikinSkia.cpp
+# note: the freetype include is spurious; minikin itself probably
+# shouldn't depend on it
+	LOCAL_SHARED_LIBRARIES += libminikin libstlport
+endif
+
 LOCAL_SHARED_LIBRARIES += \
 	libdl
 # we need to access the private Bionic header
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 09577da..783e794 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -122,7 +122,7 @@
 extern int register_android_view_GraphicBuffer(JNIEnv* env);
 extern int register_android_view_GLES20DisplayList(JNIEnv* env);
 extern int register_android_view_GLES20Canvas(JNIEnv* env);
-extern int register_android_view_HardwareRenderer(JNIEnv* env);
+extern int register_android_view_GLRenderer(JNIEnv* env);
 extern int register_android_view_Surface(JNIEnv* env);
 extern int register_android_view_SurfaceControl(JNIEnv* env);
 extern int register_android_view_SurfaceSession(JNIEnv* env);
@@ -447,6 +447,7 @@
     char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
     char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX];
     char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX];
+    char gctypeOptsBuf[sizeof("-Xgc:")-1 + PROPERTY_VALUE_MAX];
     char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];
     char jitcodecachesizeOptsBuf[sizeof("-Xjitcodecachesize:")-1 + PROPERTY_VALUE_MAX];
     char extraOptsBuf[PROPERTY_VALUE_MAX];
@@ -582,6 +583,13 @@
       mOptions.add(opt);
     }
 
+    strcpy(gctypeOptsBuf, "-Xgc:");
+    property_get("dalvik.vm.gctype", gctypeOptsBuf+5, "");
+    if (gctypeOptsBuf[5] != '\0') {
+        opt.optionString = gctypeOptsBuf;
+        mOptions.add(opt);
+    }
+
     /*
      * Enable or disable dexopt features, such as bytecode verification and
      * calculation of register maps for precise GC.
@@ -1022,7 +1030,8 @@
     void** args = (void**) malloc(3 * sizeof(void*));   // javaThreadShell must free
     int result;
 
-    assert(threadName != NULL);
+    if (!threadName)
+        threadName = "unnamed thread";
 
     args[0] = (void*) entryFunction;
     args[1] = userData;
@@ -1117,7 +1126,7 @@
     REG_JNI(register_android_view_GraphicBuffer),
     REG_JNI(register_android_view_GLES20DisplayList),
     REG_JNI(register_android_view_GLES20Canvas),
-    REG_JNI(register_android_view_HardwareRenderer),
+    REG_JNI(register_android_view_GLRenderer),
     REG_JNI(register_android_view_Surface),
     REG_JNI(register_android_view_SurfaceControl),
     REG_JNI(register_android_view_SurfaceSession),
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index eea9ee1..094129b 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -227,7 +227,7 @@
     do {

         *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]);

     } while (--width != 0);

-    ctable->unlockColors(false);

+    ctable->unlockColors();

 }

 

 static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,

@@ -240,7 +240,7 @@
         *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),

                                 SkGetPackedG32(c), SkGetPackedB32(c));

     } while (--width != 0);

-    ctable->unlockColors(false);

+    ctable->unlockColors();

 }

 

 static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,

@@ -253,7 +253,7 @@
         *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),

                                SkGetPackedB32(c));

     } while (--width != 0);

-    ctable->unlockColors(false);

+    ctable->unlockColors();

 }

 

 // can return NULL

@@ -543,14 +543,14 @@
     p->writeInt32(bitmap->rowBytes());

     p->writeInt32(density);

 

-    if (bitmap->getConfig() == SkBitmap::kIndex8_Config) {

+    if (bitmap->config() == SkBitmap::kIndex8_Config) {

         SkColorTable* ctable = bitmap->getColorTable();

         if (ctable != NULL) {

             int count = ctable->count();

             p->writeInt32(count);

             memcpy(p->writeInplace(count * sizeof(SkPMColor)),

                    ctable->lockColors(), count * sizeof(SkPMColor));

-            ctable->unlockColors(false);

+            ctable->unlockColors();

         } else {

             p->writeInt32(0);   // indicate no ctable

         }

diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index da6219f..80bd3e2 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -157,7 +157,7 @@
     virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
         // accounts for scale in final allocation, using eventual size and config
         const int bytesPerPixel = SkBitmap::ComputeBytesPerPixel(
-                configForScaledOutput(bitmap->getConfig()));
+                configForScaledOutput(bitmap->config()));
         const int requestedSize = bytesPerPixel *
                 int(bitmap->width() * mScale + 0.5f) *
                 int(bitmap->height() * mScale + 0.5f);
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index ee47ac4..d08abba 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -29,7 +29,6 @@
 #include "CreateJavaOutputStreamAdaptor.h"
 #include "Utils.h"
 #include "JNIHelp.h"
-#include "SkTScopedPtr.h"
 
 #include <android_runtime/AndroidRuntime.h>
 #include "android_util_Binder.h"
@@ -76,7 +75,7 @@
     int fHeight;
 };
 
-static jobject createBitmapRegionDecoder(JNIEnv* env, SkStream* stream) {
+static jobject createBitmapRegionDecoder(JNIEnv* env, SkStreamRewindable* stream) {
     SkImageDecoder* decoder = SkImageDecoder::Factory(stream);
     int width, height;
     if (NULL == decoder) {
@@ -108,7 +107,7 @@
         For now we just always copy the array's data if isShareable.
      */
     AutoJavaByteArray ar(env, byteArray);
-    SkStream* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
+    SkMemoryStream* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
 
     jobject brd = createBitmapRegionDecoder(env, stream);
     SkSafeUnref(stream); // the decoder now holds a reference
@@ -215,7 +214,7 @@
     region.fRight = start_x + width;
     region.fBottom = start_y + height;
     SkBitmap* bitmap = NULL;
-    SkTScopedPtr<SkBitmap> adb;
+    SkAutoTDelete<SkBitmap> adb;
 
     if (tileBitmap != NULL) {
         // Re-use bitmap.
@@ -246,7 +245,7 @@
     }
 
     // detach bitmap from its autodeleter, since we want to own it now
-    adb.release();
+    adb.detach();
 
     JavaPixelAllocator* allocator = (JavaPixelAllocator*) decoder->getAllocator();
     jbyteArray buff = allocator->getStorageObjAndReset();
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 813dd5a..9a00d538 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -27,8 +27,14 @@
 #include "SkShader.h"
 #include "SkTemplates.h"
 
+#ifdef USE_MINIKIN
+#include <minikin/Layout.h>
+#include "MinikinSkia.h"
+#endif
+
 #include "TextLayout.h"
 #include "TextLayoutCache.h"
+#include "TypefaceImpl.h"
 
 #include "unicode/ubidi.h"
 #include "unicode/ushape.h"
@@ -742,35 +748,83 @@
     }
 
 
-    static void drawText___CIIFFIPaint(JNIEnv* env, jobject, SkCanvas* canvas,
+    static void drawText___CIIFFIPaintTypeface(JNIEnv* env, jobject, SkCanvas* canvas,
                                       jcharArray text, int index, int count,
-                                      jfloat x, jfloat y, int flags, SkPaint* paint) {
+                                      jfloat x, jfloat y, int flags, SkPaint* paint,
+                                      TypefaceImpl *typeface) {
         jchar* textArray = env->GetCharArrayElements(text, NULL);
-        drawTextWithGlyphs(canvas, textArray + index, 0, count, x, y, flags, paint);
+        drawTextWithGlyphs(canvas, textArray + index, 0, count, x, y, flags, paint, typeface);
         env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
     }
 
-    static void drawText__StringIIFFIPaint(JNIEnv* env, jobject,
+    static void drawText__StringIIFFIPaintTypeface(JNIEnv* env, jobject,
                                           SkCanvas* canvas, jstring text,
                                           int start, int end,
-                                          jfloat x, jfloat y, int flags, SkPaint* paint) {
+                                          jfloat x, jfloat y, int flags, SkPaint* paint,
+                                          TypefaceImpl *typeface) {
         const jchar* textArray = env->GetStringChars(text, NULL);
-        drawTextWithGlyphs(canvas, textArray, start, end, x, y, flags, paint);
+        drawTextWithGlyphs(canvas, textArray, start, end, x, y, flags, paint, typeface);
         env->ReleaseStringChars(text, textArray);
     }
 
+#ifdef USE_MINIKIN
+    static void drawGlyphsToSkia(SkCanvas *canvas, SkPaint *paint, Layout *layout, float x, float y) {
+        size_t nGlyphs = layout->nGlyphs();
+        uint16_t *glyphs = new uint16_t[nGlyphs];
+        SkPoint *pos = new SkPoint[nGlyphs];
+        SkTypeface *lastFace = NULL;
+        SkTypeface *skFace = NULL;
+        size_t start = 0;
+
+        paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+        for (size_t i = 0; i < nGlyphs; i++) {
+            MinikinFontSkia *mfs = static_cast<MinikinFontSkia *>(layout->getFont(i));
+            skFace = mfs->GetSkTypeface();
+            glyphs[i] = layout->getGlyphId(i);
+            pos[i].fX = SkFloatToScalar(x + layout->getX(i));
+            pos[i].fY = SkFloatToScalar(y + layout->getY(i));
+            if (i > 0 && skFace != lastFace) {
+                paint->setTypeface(lastFace);
+                canvas->drawPosText(glyphs + start, (i - start) << 1, pos + start, *paint);
+                start = i;
+            }
+            lastFace = skFace;
+        }
+        if (skFace != NULL) {
+            paint->setTypeface(skFace);
+            canvas->drawPosText(glyphs + start, (nGlyphs - start) << 1, pos + start, *paint);
+        }
+        delete[] glyphs;
+        delete[] pos;
+    }
+#endif
+
     static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
             int start, int end,
-            jfloat x, jfloat y, int flags, SkPaint* paint) {
+            jfloat x, jfloat y, int flags, SkPaint* paint, TypefaceImpl* typeface) {
 
         jint count = end - start;
-        drawTextWithGlyphs(canvas, textArray + start, 0, count, count, x, y, flags, paint);
+        drawTextWithGlyphs(canvas, textArray + start, 0, count, count, x, y, flags, paint, typeface);
     }
 
     static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
             int start, int count, int contextCount,
-            jfloat x, jfloat y, int flags, SkPaint* paint) {
+            jfloat x, jfloat y, int flags, SkPaint* paint, TypefaceImpl* typeface) {
 
+#ifdef USE_MINIKIN
+        Layout layout;
+        TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
+        layout.setFontCollection(resolvedFace->fFontCollection);
+        FontStyle style = resolvedFace->fStyle;
+        char css[256];
+        sprintf(css, "font-size: %d; font-weight: %d; font-style: %s",
+            (int)paint->getTextSize(),
+            style.getWeight() * 100,
+            style.getItalic() ? "italic" : "normal");
+        layout.setProperties(css);
+        layout.doLayout(textArray + start, count);
+        drawGlyphsToSkia(canvas, paint, &layout, x, y);
+#else
         sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
                 textArray, start, count, contextCount, flags);
         if (value == NULL) {
@@ -786,6 +840,7 @@
         doDrawGlyphsPos(canvas, value->getGlyphs(), value->getPos(), 0, value->getGlyphsCount(), x, y, flags, paint);
         doDrawTextDecorations(canvas, x, y, value->getTotalAdvance(), paint);
         paint->setTextAlign(align);
+#endif
     }
 
 // Same values used by Skia
@@ -842,27 +897,29 @@
         delete[] posPtr;
     }
 
-    static void drawTextRun___CIIIIFFIPaint(
+    static void drawTextRun___CIIIIFFIPaintTypeface(
         JNIEnv* env, jobject, SkCanvas* canvas, jcharArray text, int index,
         int count, int contextIndex, int contextCount,
-        jfloat x, jfloat y, int dirFlags, SkPaint* paint) {
+        jfloat x, jfloat y, int dirFlags, SkPaint* paint,
+        TypefaceImpl* typeface) {
 
         jchar* chars = env->GetCharArrayElements(text, NULL);
         drawTextWithGlyphs(canvas, chars + contextIndex, index - contextIndex,
-                count, contextCount, x, y, dirFlags, paint);
+                count, contextCount, x, y, dirFlags, paint, typeface);
         env->ReleaseCharArrayElements(text, chars, JNI_ABORT);
     }
 
-    static void drawTextRun__StringIIIIFFIPaint(
+    static void drawTextRun__StringIIIIFFIPaintTypeface(
         JNIEnv* env, jobject obj, SkCanvas* canvas, jstring text, jint start,
         jint end, jint contextStart, jint contextEnd,
-        jfloat x, jfloat y, jint dirFlags, SkPaint* paint) {
+        jfloat x, jfloat y, jint dirFlags, SkPaint* paint,
+        TypefaceImpl* typeface) {
 
         jint count = end - start;
         jint contextCount = contextEnd - contextStart;
         const jchar* chars = env->GetStringChars(text, NULL);
         drawTextWithGlyphs(canvas, chars + contextStart, start - contextStart,
-                count, contextCount, x, y, dirFlags, paint);
+                count, contextCount, x, y, dirFlags, paint, typeface);
         env->ReleaseStringChars(text, chars);
     }
 
@@ -1070,14 +1127,14 @@
         (void*)SkCanvasGlue::drawBitmapMesh},
     {"nativeDrawVertices", "(III[FI[FI[II[SIII)V",
         (void*)SkCanvasGlue::drawVertices},
-    {"native_drawText","(I[CIIFFII)V",
-        (void*) SkCanvasGlue::drawText___CIIFFIPaint},
-    {"native_drawText","(ILjava/lang/String;IIFFII)V",
-        (void*) SkCanvasGlue::drawText__StringIIFFIPaint},
-    {"native_drawTextRun","(I[CIIIIFFII)V",
-        (void*) SkCanvasGlue::drawTextRun___CIIIIFFIPaint},
-    {"native_drawTextRun","(ILjava/lang/String;IIIIFFII)V",
-        (void*) SkCanvasGlue::drawTextRun__StringIIIIFFIPaint},
+    {"native_drawText","(I[CIIFFIII)V",
+        (void*) SkCanvasGlue::drawText___CIIFFIPaintTypeface},
+    {"native_drawText","(ILjava/lang/String;IIFFIII)V",
+        (void*) SkCanvasGlue::drawText__StringIIFFIPaintTypeface},
+    {"native_drawTextRun","(I[CIIIIFFIII)V",
+        (void*) SkCanvasGlue::drawTextRun___CIIIIFFIPaintTypeface},
+    {"native_drawTextRun","(ILjava/lang/String;IIIIFFIII)V",
+        (void*) SkCanvasGlue::drawTextRun__StringIIIIFFIPaintTypeface},
     {"native_drawPosText","(I[CII[FI)V",
         (void*) SkCanvasGlue::drawPosText___CII_FPaint},
     {"native_drawPosText","(ILjava/lang/String;[FI)V",
diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp
index dd1177b..26169e7 100644
--- a/core/jni/android/graphics/ColorFilter.cpp
+++ b/core/jni/android/graphics/ColorFilter.cpp
@@ -33,10 +33,10 @@
 class SkColorFilterGlue {
 public:
     static void finalizer(JNIEnv* env, jobject clazz, SkColorFilter* obj, SkiaColorFilter* f) {
-        SkSafeUnref(obj);
+        if (obj) SkSafeUnref(obj);
         // f == NULL when not !USE_OPENGL_RENDERER, so no need to delete outside the ifdef
 #ifdef USE_OPENGL_RENDERER
-        if (android::uirenderer::Caches::hasInstance()) {
+        if (f && android::uirenderer::Caches::hasInstance()) {
             android::uirenderer::Caches::getInstance().resourceCache.destructor(f);
         } else {
             delete f;
@@ -112,7 +112,7 @@
 };
 
 static JNINativeMethod colorfilter_methods[] = {
-    {"finalizer", "(II)V", (void*) SkColorFilterGlue::finalizer}
+    {"destroyFilter", "(II)V", (void*) SkColorFilterGlue::finalizer}
 };
 
 static JNINativeMethod porterduff_methods[] = {
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 8cb152d..38a9ba3 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -174,6 +174,12 @@
 static jfieldID gRegion_nativeInstanceID;
 static jmethodID gRegion_constructorMethodID;
 
+static jclass    gByte_class;
+static jobject   gVMRuntime;
+static jclass    gVMRuntime_class;
+static jmethodID gVMRuntime_newNonMovableArray;
+static jmethodID gVMRuntime_addressOf;
+
 ///////////////////////////////////////////////////////////////////////////////
 
 void GraphicsJNI::get_jrect(JNIEnv* env, jobject obj, int* L, int* T, int* R, int* B)
@@ -529,8 +535,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-extern "C" jbyte* jniGetNonMovableArrayElements(C_JNIEnv* env, jarray arrayObj);
-
 jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
                                              SkColorTable* ctable) {
     Sk64 size64 = bitmap->getSize64();
@@ -539,20 +543,24 @@
                           "bitmap size exceeds 32bits");
         return NULL;
     }
-
     size_t size = size64.get32();
-    jbyteArray arrayObj = env->NewByteArray(size);
-    if (arrayObj) {
-        // TODO: make this work without jniGetNonMovableArrayElements
-        jbyte* addr = jniGetNonMovableArrayElements(&env->functions, arrayObj);
-        if (addr) {
-            SkPixelRef* pr = new AndroidPixelRef(env, (void*) addr, size, arrayObj, ctable);
-            bitmap->setPixelRef(pr)->unref();
-            // since we're already allocated, we lockPixels right away
-            // HeapAllocator behaves this way too
-            bitmap->lockPixels();
-        }
+    jbyteArray arrayObj = (jbyteArray) env->CallObjectMethod(gVMRuntime,
+                                                             gVMRuntime_newNonMovableArray,
+                                                             gByte_class, size);
+    if (env->ExceptionCheck() != 0) {
+        return NULL;
     }
+    SkASSERT(arrayObj);
+    jbyte* addr = (jbyte*) env->CallLongMethod(gVMRuntime, gVMRuntime_addressOf, arrayObj);
+    if (env->ExceptionCheck() != 0) {
+        return NULL;
+    }
+    SkASSERT(addr);
+    SkPixelRef* pr = new AndroidPixelRef(env, (void*) addr, size, arrayObj, ctable);
+    bitmap->setPixelRef(pr)->unref();
+    // since we're already allocated, we lockPixels right away
+    // HeapAllocator behaves this way too
+    bitmap->lockPixels();
 
     return arrayObj;
 }
@@ -601,7 +609,7 @@
 {
     jclass c = env->FindClass(classname);
     SkASSERT(c);
-    return (jclass)env->NewGlobalRef(c);
+    return (jclass) env->NewGlobalRef(c);
 }
 
 static jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz,
@@ -663,5 +671,16 @@
     gRegion_constructorMethodID = env->GetMethodID(gRegion_class, "<init>",
         "(II)V");
 
+    c = env->FindClass("java/lang/Byte");
+    gByte_class = (jclass) env->NewGlobalRef(
+        env->GetStaticObjectField(c, env->GetStaticFieldID(c, "TYPE", "Ljava/lang/Class;")));
+
+    gVMRuntime_class = make_globalref(env, "dalvik/system/VMRuntime");
+    m = env->GetStaticMethodID(gVMRuntime_class, "getRuntime", "()Ldalvik/system/VMRuntime;");
+    gVMRuntime = env->NewGlobalRef(env->CallStaticObjectMethod(gVMRuntime_class, m));
+    gVMRuntime_newNonMovableArray = env->GetMethodID(gVMRuntime_class, "newNonMovableArray",
+                                                     "(Ljava/lang/Class;I)Ljava/lang/Object;");
+    gVMRuntime_addressOf = env->GetMethodID(gVMRuntime_class, "addressOf", "(Ljava/lang/Object;)J");
+
     return 0;
 }
diff --git a/core/jni/android/graphics/MinikinSkia.cpp b/core/jni/android/graphics/MinikinSkia.cpp
new file mode 100644
index 0000000..622c935
--- /dev/null
+++ b/core/jni/android/graphics/MinikinSkia.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <SkTypeface.h>
+#include <SkPaint.h>
+#include <SkFP.h>
+
+#define LOG_TAG "Minikin"
+#include <cutils/log.h>
+
+#include <minikin/MinikinFont.h>
+#include "MinikinSkia.h"
+
+namespace android {
+
+MinikinFontSkia::MinikinFontSkia(SkTypeface *typeface) :
+    mTypeface(typeface) {
+}
+
+MinikinFontSkia::~MinikinFontSkia() {
+    SkSafeUnref(mTypeface);
+}
+
+bool MinikinFontSkia::GetGlyph(uint32_t codepoint, uint32_t *glyph) const {
+    SkPaint paint;
+    paint.setTypeface(mTypeface);
+    paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
+    uint16_t glyph16;
+    paint.textToGlyphs(&codepoint, sizeof(codepoint), &glyph16);
+    *glyph  = glyph16;
+    return !!glyph;
+}
+
+float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id,
+    const MinikinPaint &paint) const {
+    SkPaint skpaint;
+    skpaint.setTypeface(mTypeface);
+    skpaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    // TODO: set more paint parameters from Minikin
+    skpaint.setTextSize(paint.size);
+    uint16_t glyph16 = glyph_id;
+    SkScalar skWidth;
+    SkRect skBounds;
+    skpaint.getTextWidths(&glyph16, sizeof(glyph16), &skWidth, &skBounds);
+    // TODO: get bounds information
+    return SkScalarToFP(skWidth);
+}
+
+bool MinikinFontSkia::GetTable(uint32_t tag, uint8_t *buf, size_t *size) {
+    if (buf == NULL) {
+        const size_t tableSize = mTypeface->getTableSize(tag);
+        *size = tableSize;
+        return tableSize != 0;
+    } else {
+        const size_t actualSize = mTypeface->getTableData(tag, 0, *size, buf);
+        *size = actualSize;
+        return actualSize != 0;
+    }
+}
+
+SkTypeface *MinikinFontSkia::GetSkTypeface() {
+    return mTypeface;
+}
+
+int32_t MinikinFontSkia::GetUniqueId() const {
+    return mTypeface->uniqueID();
+}
+
+}
diff --git a/core/jni/android/graphics/MinikinSkia.h b/core/jni/android/graphics/MinikinSkia.h
new file mode 100644
index 0000000..0edb557
--- /dev/null
+++ b/core/jni/android/graphics/MinikinSkia.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+namespace android {
+
+class MinikinFontSkia : public MinikinFont {
+public:
+    explicit MinikinFontSkia(SkTypeface *typeface);
+
+    ~MinikinFontSkia();
+
+    bool GetGlyph(uint32_t codepoint, uint32_t *glyph) const;
+
+    float GetHorizontalAdvance(uint32_t glyph_id,
+        const MinikinPaint &paint) const;
+
+    // If buf is NULL, just update size
+    bool GetTable(uint32_t tag, uint8_t *buf, size_t *size);
+
+    int32_t GetUniqueId() const;
+
+    SkTypeface *GetSkTypeface();
+
+private:
+    SkTypeface *mTypeface;
+
+};
+
+}  // namespace android
\ No newline at end of file
diff --git a/core/jni/android/graphics/NinePatchImpl.cpp b/core/jni/android/graphics/NinePatchImpl.cpp
index 01e7e3e..d43c1be 100644
--- a/core/jni/android/graphics/NinePatchImpl.cpp
+++ b/core/jni/android/graphics/NinePatchImpl.cpp
@@ -38,7 +38,7 @@
 #include <utils/Log.h>
 
 static bool getColor(const SkBitmap& bitmap, int x, int y, SkColor* c) {
-    switch (bitmap.getConfig()) {
+    switch (bitmap.config()) {
         case SkBitmap::kARGB_8888_Config:
             *c = SkUnPreMultiply::PMColorToColor(*bitmap.getAddr32(x, y));
             break;
diff --git a/core/jni/android/graphics/NinePatchPeeker.cpp b/core/jni/android/graphics/NinePatchPeeker.cpp
index df996af..d3482da 100644
--- a/core/jni/android/graphics/NinePatchPeeker.cpp
+++ b/core/jni/android/graphics/NinePatchPeeker.cpp
@@ -40,15 +40,14 @@
         // now update our host to force index or 32bit config
         // 'cause we don't want 565 predithered, since as a 9patch, we know
         // we will be stretched, and therefore we want to dither afterwards.
-        static const SkBitmap::Config gNo565Pref[] = {
-            SkBitmap::kIndex8_Config,
-            SkBitmap::kIndex8_Config,
-            SkBitmap::kARGB_8888_Config,
-            SkBitmap::kARGB_8888_Config,
-            SkBitmap::kARGB_8888_Config,
-            SkBitmap::kARGB_8888_Config,
-        };
-        fHost->setPrefConfigTable(gNo565Pref);
+        SkImageDecoder::PrefConfigTable table;
+        table.fPrefFor_8Index_NoAlpha_src   = SkBitmap::kIndex8_Config;
+        table.fPrefFor_8Index_YesAlpha_src  = SkBitmap::kIndex8_Config;
+        table.fPrefFor_8Gray_src            = SkBitmap::kARGB_8888_Config;
+        table.fPrefFor_8bpc_NoAlpha_src     = SkBitmap::kARGB_8888_Config;
+        table.fPrefFor_8bpc_YesAlpha_src    = SkBitmap::kARGB_8888_Config;
+
+        fHost->setPrefConfigTable(table);
     } else if (strcmp("npLb", tag) == 0 && length == sizeof(int) * 4) {
         fLayoutBounds = new int[4];
         memcpy(fLayoutBounds, data, sizeof(int) * 4);
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 40e0731..1ca3f3a 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -245,7 +245,12 @@
     }
 
     static SkTypeface* setTypeface(JNIEnv* env, jobject clazz, SkPaint* obj, SkTypeface* typeface) {
+#ifndef USE_MINIKIN
         return obj->setTypeface(typeface);
+#else
+        // TODO(raph): not yet implemented
+        return NULL;
+#endif
     }
 
     static SkRasterizer* setRasterizer(JNIEnv* env, jobject clazz, SkPaint* obj, SkRasterizer* rasterizer) {
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index ab7f1dc..97a7de6 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -28,6 +28,8 @@
 #include "pathops/SkPathOps.h"
 
 #include <Caches.h>
+#include <vector>
+#include <map>
 
 namespace android {
 
@@ -265,6 +267,196 @@
     static jboolean op(JNIEnv* env, jobject clazz, SkPath* p1, SkPath* p2, SkPathOp op, SkPath* r) {
          return Op(*p1, *p2, op, r);
      }
+
+
+    typedef SkPoint (*bezierCalculation)(float t, const SkPoint* points);
+
+    static void addMove(std::vector<SkPoint>& segmentPoints, std::vector<float>& lengths,
+            const SkPoint& point) {
+        float length = 0;
+        if (!lengths.empty()) {
+            length = lengths.back();
+        }
+        segmentPoints.push_back(point);
+        lengths.push_back(length);
+    }
+
+    static void addLine(std::vector<SkPoint>& segmentPoints, std::vector<float>& lengths,
+            const SkPoint& toPoint) {
+        if (segmentPoints.empty()) {
+            segmentPoints.push_back(SkPoint::Make(0, 0));
+            lengths.push_back(0);
+        } else if (segmentPoints.back() == toPoint) {
+            return; // Empty line
+        }
+        float length = lengths.back() + SkPoint::Distance(segmentPoints.back(), toPoint);
+        segmentPoints.push_back(toPoint);
+        lengths.push_back(length);
+    }
+
+    static float cubicCoordinateCalculation(float t, float p0, float p1, float p2, float p3) {
+        float oneMinusT = 1 - t;
+        float oneMinusTSquared = oneMinusT * oneMinusT;
+        float oneMinusTCubed = oneMinusTSquared * oneMinusT;
+        float tSquared = t * t;
+        float tCubed = tSquared * t;
+        return (oneMinusTCubed * p0) + (3 * oneMinusTSquared * t * p1)
+                + (3 * oneMinusT * tSquared * p2) + (tCubed * p3);
+    }
+
+    static SkPoint cubicBezierCalculation(float t, const SkPoint* points) {
+        float x = cubicCoordinateCalculation(t, points[0].x(), points[1].x(),
+            points[2].x(), points[3].x());
+        float y = cubicCoordinateCalculation(t, points[0].y(), points[1].y(),
+            points[2].y(), points[3].y());
+        return SkPoint::Make(x, y);
+    }
+
+    static float quadraticCoordinateCalculation(float t, float p0, float p1, float p2) {
+        float oneMinusT = 1 - t;
+        return oneMinusT * ((oneMinusT * p0) + (t * p1)) + t * ((oneMinusT * p1) + (t * p2));
+    }
+
+    static SkPoint quadraticBezierCalculation(float t, const SkPoint* points) {
+        float x = quadraticCoordinateCalculation(t, points[0].x(), points[1].x(), points[2].x());
+        float y = quadraticCoordinateCalculation(t, points[0].y(), points[1].y(), points[2].y());
+        return SkPoint::Make(x, y);
+    }
+
+    // Subdivide a section of the Bezier curve, set the mid-point and the mid-t value.
+    // Returns true if further subdivision is necessary as defined by errorSquared.
+    static bool subdividePoints(const SkPoint* points, bezierCalculation bezierFunction,
+            float t0, const SkPoint &p0, float t1, const SkPoint &p1,
+            float& midT, SkPoint &midPoint, float errorSquared) {
+        midT = (t1 + t0) / 2;
+        float midX = (p1.x() + p0.x()) / 2;
+        float midY = (p1.y() + p0.y()) / 2;
+
+        midPoint = (*bezierFunction)(midT, points);
+        float xError = midPoint.x() - midX;
+        float yError = midPoint.y() - midY;
+        float midErrorSquared = (xError * xError) + (yError * yError);
+        return midErrorSquared > errorSquared;
+    }
+
+    // Divides Bezier curves until linear interpolation is very close to accurate, using
+    // errorSquared as a metric. Cubic Bezier curves can have an inflection point that improperly
+    // short-circuit subdivision. If you imagine an S shape, the top and bottom points being the
+    // starting and end points, linear interpolation would mark the center where the curve places
+    // the point. It is clearly not the case that we can linearly interpolate at that point.
+    // doubleCheckDivision forces a second examination between subdivisions to ensure that linear
+    // interpolation works.
+    static void addBezier(const SkPoint* points,
+            bezierCalculation bezierFunction, std::vector<SkPoint>& segmentPoints,
+            std::vector<float>& lengths, float errorSquared, bool doubleCheckDivision) {
+        typedef std::map<float, SkPoint> PointMap;
+        PointMap tToPoint;
+
+        tToPoint[0] = (*bezierFunction)(0, points);
+        tToPoint[1] = (*bezierFunction)(1, points);
+
+        PointMap::iterator iter = tToPoint.begin();
+        PointMap::iterator next = iter;
+        ++next;
+        while (next != tToPoint.end()) {
+            bool needsSubdivision = true;
+            SkPoint midPoint;
+            do {
+                float midT;
+                needsSubdivision = subdividePoints(points, bezierFunction, iter->first,
+                    iter->second, next->first, next->second, midT, midPoint, errorSquared);
+                if (!needsSubdivision && doubleCheckDivision) {
+                    SkPoint quarterPoint;
+                    float quarterT;
+                    needsSubdivision = subdividePoints(points, bezierFunction, iter->first,
+                        iter->second, midT, midPoint, quarterT, quarterPoint, errorSquared);
+                    if (needsSubdivision) {
+                        // Found an inflection point. No need to double-check.
+                        doubleCheckDivision = false;
+                    }
+                }
+                if (needsSubdivision) {
+                    next = tToPoint.insert(iter, PointMap::value_type(midT, midPoint));
+                }
+            } while (needsSubdivision);
+            iter = next;
+            next++;
+        }
+
+        // Now that each division can use linear interpolation with less than the allowed error
+        for (iter = tToPoint.begin(); iter != tToPoint.end(); ++iter) {
+            addLine(segmentPoints, lengths, iter->second);
+        }
+    }
+
+    static void createVerbSegments(SkPath::Verb verb, const SkPoint* points,
+        std::vector<SkPoint>& segmentPoints, std::vector<float>& lengths, float errorSquared) {
+        switch (verb) {
+            case SkPath::kMove_Verb:
+                addMove(segmentPoints, lengths, points[0]);
+                break;
+            case SkPath::kClose_Verb:
+            case SkPath::kLine_Verb:
+                addLine(segmentPoints, lengths, points[1]);
+                break;
+            case SkPath::kQuad_Verb:
+                addBezier(points, quadraticBezierCalculation, segmentPoints, lengths,
+                    errorSquared, false);
+                break;
+            case SkPath::kCubic_Verb:
+                addBezier(points, cubicBezierCalculation, segmentPoints, lengths,
+                    errorSquared, true);
+                break;
+            default:
+                // Leave element as NULL, Conic sections are not supported.
+                break;
+        }
+    }
+
+    // Returns a float[] with each point along the path represented by 3 floats
+    // * fractional length along the path that the point resides
+    // * x coordinate
+    // * y coordinate
+    // Note that more than one point may have the same length along the path in
+    // the case of a move.
+    // NULL can be returned if the Path is empty.
+    static jfloatArray approximate(JNIEnv* env, jclass, SkPath* path, float acceptableError)
+    {
+        SkASSERT(path);
+        SkPath::Iter pathIter(*path, false);
+        SkPath::Verb verb;
+        SkPoint points[4];
+        std::vector<SkPoint> segmentPoints;
+        std::vector<float> lengths;
+        float errorSquared = acceptableError * acceptableError;
+
+        while ((verb = pathIter.next(points)) != SkPath::kDone_Verb) {
+            createVerbSegments(verb, points, segmentPoints, lengths, errorSquared);
+        }
+
+        if (segmentPoints.empty()) {
+            return NULL;
+        }
+
+        size_t numPoints = segmentPoints.size();
+        size_t approximationArraySize = numPoints * 3;
+
+        float* approximation = new float[approximationArraySize];
+        float totalLength = lengths.back();
+
+        int approximationIndex = 0;
+        for (int i = 0; i < numPoints; i++) {
+            const SkPoint& point = segmentPoints[i];
+            approximation[approximationIndex++] = lengths[i] / totalLength;
+            approximation[approximationIndex++] = point.x();
+            approximation[approximationIndex++] = point.y();
+        }
+
+        jfloatArray result = env->NewFloatArray(approximationArraySize);
+        env->SetFloatArrayRegion(result, 0, approximationArraySize, approximation);
+        delete[] approximation;
+        return result;
+    }
 };
 
 static JNINativeMethod methods[] = {
@@ -305,7 +497,8 @@
     {"native_setLastPoint","(IFF)V", (void*) SkPathGlue::setLastPoint},
     {"native_transform","(III)V", (void*) SkPathGlue::transform__MatrixPath},
     {"native_transform","(II)V", (void*) SkPathGlue::transform__Matrix},
-    {"native_op","(IIII)Z", (void*) SkPathGlue::op}
+    {"native_op","(IIII)Z", (void*) SkPathGlue::op},
+    {"native_approximate", "(IF)[F", (void*) SkPathGlue::approximate},
 };
 
 int register_android_graphics_Path(JNIEnv* env) {
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 92d253f..144ac39 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -20,6 +20,7 @@
 
 #include "TextLayoutCache.h"
 #include "TextLayout.h"
+#include "SkGlyphCache.h"
 #include "SkTypeface_android.h"
 #include "HarfBuzzNGFaceSkia.h"
 #include <unicode/unistr.h>
@@ -757,8 +758,8 @@
             outPos->add(ypos);
             totalAdvance += xAdvance;
 
-            // TODO: consider using glyph cache
-            const SkGlyph& metrics = mShapingPaint.getGlyphMetrics(glyphId, NULL);
+            SkAutoGlyphCache autoCache(mShapingPaint, NULL, NULL);
+            const SkGlyph& metrics = autoCache.getCache()->getGlyphIDMetrics(glyphId);
             outBounds->join(xpos + metrics.fLeft, ypos + metrics.fTop,
                     xpos + metrics.fLeft + metrics.fWidth, ypos + metrics.fTop + metrics.fHeight);
 
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index ccd75d5..04f9fe1 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -1,9 +1,26 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 #include "jni.h"
 #include <android_runtime/AndroidRuntime.h>
 
 #include "GraphicsJNI.h"
 #include "SkStream.h"
 #include "SkTypeface.h"
+#include "TypefaceImpl.h"
 #include <android_runtime/android_util_AssetManager.h>
 #include <androidfw/AssetManager.h>
 
@@ -27,112 +44,46 @@
     const char* fCStr;
 };
 
-static SkTypeface* Typeface_create(JNIEnv* env, jobject, jstring name,
+static TypefaceImpl* Typeface_create(JNIEnv* env, jobject, jstring name,
                                    SkTypeface::Style style) {
-    SkTypeface* face = NULL;
+    TypefaceImpl* face = NULL;
 
     if (NULL != name) {
         AutoJavaStringToUTF8    str(env, name);
-        face = SkTypeface::CreateFromName(str.c_str(), style);
-        // Try to find the closest matching font, using the standard heuristic
-        if (NULL == face) {
-            face = SkTypeface::CreateFromName(str.c_str(), (SkTypeface::Style)(style ^ SkTypeface::kItalic));
-        }
-        for (int i = 0; NULL == face && i < 4; i++) {
-            face = SkTypeface::CreateFromName(str.c_str(), (SkTypeface::Style)i);
-        }
+        face = TypefaceImpl_createFromName(str.c_str(), style);
     }
 
     // return the default font at the best style if no exact match exists
     if (NULL == face) {
-        face = SkTypeface::CreateFromName(NULL, style);
+        face = TypefaceImpl_createFromName(NULL, style);
     }
     return face;
 }
 
-static SkTypeface* Typeface_createFromTypeface(JNIEnv* env, jobject, SkTypeface* family, int style) {
-    SkTypeface* face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)style);
+static TypefaceImpl* Typeface_createFromTypeface(JNIEnv* env, jobject, TypefaceImpl* family, int style) {
+    TypefaceImpl* face = TypefaceImpl_createFromTypeface(family, (SkTypeface::Style)style);
     // Try to find the closest matching font, using the standard heuristic
     if (NULL == face) {
-        face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)(style ^ SkTypeface::kItalic));
+        face = TypefaceImpl_createFromTypeface(family, (SkTypeface::Style)(style ^ SkTypeface::kItalic));
     }
     for (int i = 0; NULL == face && i < 4; i++) {
-        face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)i);
+        face = TypefaceImpl_createFromTypeface(family, (SkTypeface::Style)i);
     }
     if (NULL == face) {
-        face = SkTypeface::CreateFromName(NULL, (SkTypeface::Style)style);
+        face = TypefaceImpl_createFromName(NULL, (SkTypeface::Style)style);
     }
     return face;
 }
 
-static void Typeface_unref(JNIEnv* env, jobject obj, SkTypeface* face) {
-    SkSafeUnref(face);
+static void Typeface_unref(JNIEnv* env, jobject obj, TypefaceImpl* face) {
+    TypefaceImpl_unref(face);
 }
 
-static int Typeface_getStyle(JNIEnv* env, jobject obj, SkTypeface* face) {
-    return face->style();
+static int Typeface_getStyle(JNIEnv* env, jobject obj, TypefaceImpl* face) {
+    return TypefaceImpl_getStyle(face);
 }
 
-class AssetStream : public SkStream {
-public:
-    AssetStream(Asset* asset, bool hasMemoryBase) : fAsset(asset)
-    {
-        fMemoryBase = hasMemoryBase ? fAsset->getBuffer(false) : NULL;
-    }
-
-    virtual ~AssetStream()
-    {
-        delete fAsset;
-    }
-
-    virtual const void* getMemoryBase()
-    {
-        return fMemoryBase;
-    }
-
-	virtual bool rewind()
-    {
-        off64_t pos = fAsset->seek(0, SEEK_SET);
-        return pos != (off64_t)-1;
-    }
-
-	virtual size_t read(void* buffer, size_t size)
-    {
-        ssize_t amount;
-
-        if (NULL == buffer)
-        {
-            if (0 == size)  // caller is asking us for our total length
-                return fAsset->getLength();
-
-            // asset->seek returns new total offset
-            // we want to return amount that was skipped
-
-            off64_t oldOffset = fAsset->seek(0, SEEK_CUR);
-            if (-1 == oldOffset)
-                return 0;
-            off64_t newOffset = fAsset->seek(size, SEEK_CUR);
-            if (-1 == newOffset)
-                return 0;
-
-            amount = newOffset - oldOffset;
-        }
-        else
-        {
-            amount = fAsset->read(buffer, size);
-        }
-
-        if (amount < 0)
-            amount = 0;
-        return amount;
-    }
-
-private:
-    Asset*      fAsset;
-    const void* fMemoryBase;
-};
-
-static SkTypeface* Typeface_createFromAsset(JNIEnv* env, jobject,
+static TypefaceImpl* Typeface_createFromAsset(JNIEnv* env, jobject,
                                             jobject jassetMgr,
                                             jstring jpath) {
 
@@ -150,21 +101,15 @@
         return NULL;
     }
 
-    SkStream* stream = new AssetStream(asset, true);
-    SkTypeface* face = SkTypeface::CreateFromStream(stream);
-    // SkTypeFace::CreateFromStream calls ref() on the stream, so we
-    // need to unref it here or it won't be freed later on
-    stream->unref();
-
-    return face;
+    return TypefaceImpl_createFromAsset(asset);
 }
 
-static SkTypeface* Typeface_createFromFile(JNIEnv* env, jobject, jstring jpath) {
+static TypefaceImpl* Typeface_createFromFile(JNIEnv* env, jobject, jstring jpath) {
     NPE_CHECK_RETURN_ZERO(env, jpath);
 
     AutoJavaStringToUTF8 str(env, jpath);
 
-    return SkTypeface::CreateFromFile(str.c_str());
+    return TypefaceImpl_createFromFile(str.c_str());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/core/jni/android/graphics/TypefaceImpl.cpp b/core/jni/android/graphics/TypefaceImpl.cpp
new file mode 100644
index 0000000..8874db8
--- /dev/null
+++ b/core/jni/android/graphics/TypefaceImpl.cpp
@@ -0,0 +1,256 @@
+/*
+ * 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.
+ */
+
+/**
+ * This is the implementation of the Typeface object. Historically, it has
+ * just been SkTypeface, but we are migrating to Minikin. For the time
+ * being, that choice is hidden under the USE_MINIKIN compile-time flag.
+ */
+
+#include "SkStream.h"
+#include "SkTypeface.h"
+
+#ifdef USE_MINIKIN
+#include <vector>
+#include <minikin/FontCollection.h>
+#include <minikin/FontFamily.h>
+#include <minikin/Layout.h>
+#include "MinikinSkia.h"
+#endif
+
+#include "TypefaceImpl.h"
+
+namespace android {
+
+class AssetStream : public SkStream {
+public:
+    AssetStream(Asset* asset, bool hasMemoryBase) : fAsset(asset)
+    {
+        fMemoryBase = hasMemoryBase ? fAsset->getBuffer(false) : NULL;
+    }
+
+    virtual ~AssetStream()
+    {
+        delete fAsset;
+    }
+
+    virtual const void* getMemoryBase()
+    {
+        return fMemoryBase;
+    }
+
+    virtual bool rewind()
+    {
+        off64_t pos = fAsset->seek(0, SEEK_SET);
+        return pos != (off64_t)-1;
+    }
+
+    virtual size_t read(void* buffer, size_t size)
+    {
+        ssize_t amount;
+
+        if (NULL == buffer)
+        {
+            if (0 == size)  // caller is asking us for our total length
+                return fAsset->getLength();
+
+            // asset->seek returns new total offset
+            // we want to return amount that was skipped
+
+            off64_t oldOffset = fAsset->seek(0, SEEK_CUR);
+            if (-1 == oldOffset)
+                return 0;
+            off64_t newOffset = fAsset->seek(size, SEEK_CUR);
+            if (-1 == newOffset)
+                return 0;
+
+            amount = newOffset - oldOffset;
+        }
+        else
+        {
+            amount = fAsset->read(buffer, size);
+        }
+
+        if (amount < 0)
+            amount = 0;
+        return amount;
+    }
+
+private:
+    Asset*      fAsset;
+    const void* fMemoryBase;
+};
+
+#ifdef USE_MINIKIN
+
+// Any weight greater than or equal to this is considered "bold" for
+// legacy API.
+static const int kBoldThreshold = 6;
+
+static FontStyle styleFromSkiaStyle(SkTypeface::Style skiaStyle) {
+    int weight = (skiaStyle & SkTypeface::kBold) != 0 ? 7 : 4;
+    bool italic = (skiaStyle & SkTypeface::kItalic) != 0;
+    return FontStyle(weight, italic);
+}
+
+TypefaceImpl* gDefaultTypeface;
+pthread_once_t gDefaultTypefaceOnce = PTHREAD_ONCE_INIT;
+
+// TODO: this currently builds a font collection from hardcoded paths.
+// It will get replaced by an implementation that parses the XML files.
+static FontCollection *makeFontCollection() {
+    std::vector<FontFamily *>typefaces;
+    const char *fns[] = {
+        "/system/fonts/Roboto-Regular.ttf",
+        "/system/fonts/Roboto-Italic.ttf",
+        "/system/fonts/Roboto-BoldItalic.ttf",
+        "/system/fonts/Roboto-Light.ttf",
+        "/system/fonts/Roboto-Thin.ttf",
+        "/system/fonts/Roboto-Bold.ttf",
+        "/system/fonts/Roboto-ThinItalic.ttf",
+        "/system/fonts/Roboto-LightItalic.ttf"
+    };
+
+    FontFamily *family = new FontFamily();
+    for (size_t i = 0; i < sizeof(fns)/sizeof(fns[0]); i++) {
+        const char *fn = fns[i];
+        SkTypeface *skFace = SkTypeface::CreateFromFile(fn);
+        MinikinFont *font = new MinikinFontSkia(skFace);
+        family->addFont(font);
+    }
+    typefaces.push_back(family);
+
+    family = new FontFamily();
+    const char *fn = "/system/fonts/NotoSansDevanagari-Regular.ttf";
+    SkTypeface *skFace = SkTypeface::CreateFromFile(fn);
+    MinikinFont *font = new MinikinFontSkia(skFace);
+    family->addFont(font);
+    typefaces.push_back(family);
+
+    return new FontCollection(typefaces);
+}
+
+static void getDefaultTypefaceOnce() {
+    Layout::init();
+    gDefaultTypeface = new TypefaceImpl;
+    gDefaultTypeface->fFontCollection = makeFontCollection();
+    gDefaultTypeface->fStyle = FontStyle();
+}
+
+TypefaceImpl* TypefaceImpl_resolveDefault(TypefaceImpl* src) {
+    if (src == NULL) {
+        pthread_once(&gDefaultTypefaceOnce, getDefaultTypefaceOnce);
+        return gDefaultTypeface;
+    } else {
+        return src;
+    }
+}
+
+TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style) {
+    TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(src);
+    TypefaceImpl* result = new TypefaceImpl;
+    if (result != 0) {
+        result->fFontCollection = resolvedFace->fFontCollection;
+        result->fStyle = styleFromSkiaStyle(style);
+    }
+    return result;
+}
+
+static TypefaceImpl* createFromSkTypeface(SkTypeface* typeface) {
+    MinikinFont* minikinFont = new MinikinFontSkia(typeface);
+    std::vector<FontFamily *> typefaces;
+    FontFamily* family = new FontFamily();
+    family->addFont(minikinFont);
+    typefaces.push_back(family);
+    TypefaceImpl* result = new TypefaceImpl;
+    result->fFontCollection = new FontCollection(typefaces);
+    result->fStyle = FontStyle();  // TODO: improve
+    return result;
+}
+
+TypefaceImpl* TypefaceImpl_createFromName(const char* name, SkTypeface::Style style) {
+    // TODO: should create a font collection with all styles corresponding to
+    // the name
+    SkTypeface* face = SkTypeface::CreateFromName(name, style);
+    return createFromSkTypeface(face);
+}
+
+TypefaceImpl* TypefaceImpl_createFromFile(const char* filename) {
+    SkTypeface* face = SkTypeface::CreateFromFile(filename);
+    return createFromSkTypeface(face);
+}
+
+TypefaceImpl* TypefaceImpl_createFromAsset(Asset* asset) {
+    SkStream* stream = new AssetStream(asset, true);
+    SkTypeface* face = SkTypeface::CreateFromStream(stream);
+    // SkTypeFace::CreateFromStream calls ref() on the stream, so we
+    // need to unref it here or it won't be freed later on
+    stream->unref();
+    return createFromSkTypeface(face);
+}
+
+void TypefaceImpl_unref(TypefaceImpl* face) {
+    delete face;
+}
+
+int TypefaceImpl_getStyle(TypefaceImpl* face) {
+    FontStyle style = face->fStyle;
+    int result = style.getItalic() ? SkTypeface::kItalic : 0;
+    if (style.getWeight() >= kBoldThreshold) {
+        result |= SkTypeface::kBold;
+    }
+    return result;
+}
+
+#else  // USE_MINIKIN
+
+/* Just use SkTypeface instead. */
+
+typedef SkTypeface TypefaceImpl;
+
+TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style) {
+    return SkTypeface::CreateFromTypeface(src, style);
+}
+
+TypefaceImpl* TypefaceImpl_createFromName(const char* name, SkTypeface::Style style) {
+    return SkTypeface::CreateFromName(name, style);
+}
+
+TypefaceImpl* TypefaceImpl_createFromFile(const char* filename) {
+    return SkTypeface::CreateFromFile(filename);
+}
+
+TypefaceImpl* TypefaceImpl_createFromAsset(Asset* asset) {
+    SkStream* stream = new AssetStream(asset, true);
+    SkTypeface* face = SkTypeface::CreateFromStream(stream);
+    // SkTypeFace::CreateFromStream calls ref() on the stream, so we
+    // need to unref it here or it won't be freed later on
+    stream->unref();
+
+    return face;
+}
+
+void TypefaceImpl_unref(TypefaceImpl* face) {
+    SkSafeUnref(face);
+}
+
+int TypefaceImpl_getStyle(TypefaceImpl* face) {
+    return face->style();
+}
+
+#endif  // USE_MINIKIN
+
+}
diff --git a/core/jni/android/graphics/TypefaceImpl.h b/core/jni/android/graphics/TypefaceImpl.h
new file mode 100644
index 0000000..4c51bec
--- /dev/null
+++ b/core/jni/android/graphics/TypefaceImpl.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANDROID_TYPEFACE_IMPL_H
+#define ANDROID_TYPEFACE_IMPL_H
+
+#include <androidfw/AssetManager.h>
+
+#ifdef USE_MINIKIN
+#include <minikin/FontCollection.h>
+#endif
+
+namespace android {
+
+#ifdef USE_MINIKIN
+struct TypefaceImpl {
+    FontCollection *fFontCollection;
+    FontStyle fStyle;
+};
+
+// Note: it would be cleaner if the following functions were member
+// functions (static or otherwise) of the TypefaceImpl class. However,
+// that can't be easily accommodated in the case where TypefaceImpl
+// is just a pointer to SkTypeface, in the non-USE_MINIKIN case.
+// TODO: when #ifdef USE_MINIKIN is removed, move to member functions.
+
+TypefaceImpl* TypefaceImpl_resolveDefault(TypefaceImpl* src);
+#else
+typedef SkTypeface TypefaceImpl;
+#endif
+
+TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style);
+
+TypefaceImpl* TypefaceImpl_createFromName(const char* name, SkTypeface::Style style);
+
+TypefaceImpl* TypefaceImpl_createFromFile(const char* filename);
+
+TypefaceImpl* TypefaceImpl_createFromAsset(Asset* asset);
+
+void TypefaceImpl_unref(TypefaceImpl* face);
+
+int TypefaceImpl_getStyle(TypefaceImpl* face);
+
+}
+
+#endif  // ANDROID_TYPEFACE_IMPL_H
\ No newline at end of file
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 44af199..4bb091d 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -632,7 +632,7 @@
     SkBitmap const * nativeBitmap =
             (SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID);
     const SkBitmap& bitmap(*nativeBitmap);
-    SkBitmap::Config config = bitmap.getConfig();
+    SkBitmap::Config config = bitmap.config();
     return getInternalFormat(config);
 }
 
@@ -642,7 +642,7 @@
     SkBitmap const * nativeBitmap =
             (SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID);
     const SkBitmap& bitmap(*nativeBitmap);
-    SkBitmap::Config config = bitmap.getConfig();
+    SkBitmap::Config config = bitmap.config();
     return getType(config);
 }
 
@@ -653,7 +653,7 @@
     SkBitmap const * nativeBitmap =
             (SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID);
     const SkBitmap& bitmap(*nativeBitmap);
-    SkBitmap::Config config = bitmap.getConfig();
+    SkBitmap::Config config = bitmap.config();
     if (internalformat < 0) {
         internalformat = getInternalFormat(config);
     }
@@ -681,7 +681,7 @@
             SkColorTable* ctable = bitmap.getColorTable();
             memcpy(data, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
             memcpy(pixels, p, size);
-            ctable->unlockColors(false);
+            ctable->unlockColors();
             glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data);
             free(data);
         } else {
@@ -702,7 +702,7 @@
     SkBitmap const * nativeBitmap =
             (SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID);
     const SkBitmap& bitmap(*nativeBitmap);
-    SkBitmap::Config config = bitmap.getConfig();
+    SkBitmap::Config config = bitmap.config();
     if (format < 0) {
         format = getInternalFormat(config);
         if (format == GL_PALETTE8_RGBA8_OES)
diff --git a/core/jni/android_animation_PropertyValuesHolder.cpp b/core/jni/android_animation_PropertyValuesHolder.cpp
index 5991805..73347ea 100644
--- a/core/jni/android_animation_PropertyValuesHolder.cpp
+++ b/core/jni/android_animation_PropertyValuesHolder.cpp
@@ -47,6 +47,32 @@
     return mid;
 }
 
+static jmethodID getMultiparameterMethod(JNIEnv* env, jclass targetClass, jstring methodName,
+    jint parameterCount, char parameterType)
+{
+    const char *nativeString = env->GetStringUTFChars(methodName, 0);
+    char *signature = new char[parameterCount + 4];
+    signature[0] = '(';
+    memset(&(signature[1]), parameterType, parameterCount);
+    strcpy(&(signature[parameterCount + 1]), ")V");
+    jmethodID mid = env->GetMethodID(targetClass, nativeString, signature);
+    delete[] signature;
+    env->ReleaseStringUTFChars(methodName, nativeString);
+    return mid;
+}
+
+static jmethodID android_animation_PropertyValuesHolder_getMultipleFloatMethod(
+        JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName, jint parameterCount)
+{
+    return getMultiparameterMethod(env, targetClass, methodName, parameterCount, 'F');
+}
+
+static jmethodID android_animation_PropertyValuesHolder_getMultipleIntMethod(
+        JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName, jint parameterCount)
+{
+    return getMultiparameterMethod(env, targetClass, methodName, parameterCount, 'I');
+}
+
 static void android_animation_PropertyValuesHolder_callIntMethod(
         JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, int arg)
 {
@@ -59,15 +85,85 @@
     env->CallVoidMethod(target, methodID, arg);
 }
 
+static void android_animation_PropertyValuesHolder_callTwoFloatMethod(
+        JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, float arg1, float arg2)
+{
+    env->CallVoidMethod(target, methodID, arg1, arg2);
+}
+
+static void android_animation_PropertyValuesHolder_callFourFloatMethod(
+        JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, float arg1, float arg2,
+        float arg3, float arg4)
+{
+    env->CallVoidMethod(target, methodID, arg1, arg2, arg3, arg4);
+}
+
+static void android_animation_PropertyValuesHolder_callMultipleFloatMethod(
+        JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, jfloatArray arg)
+{
+    jsize parameterCount = env->GetArrayLength(arg);
+    jfloat *floatValues = env->GetFloatArrayElements(arg, NULL);
+    jvalue* values = new jvalue[parameterCount];
+    for (int i = 0; i < parameterCount; i++) {
+        values[i].f = floatValues[i];
+    }
+    env->CallVoidMethodA(target, methodID, values);
+    delete[] values;
+    env->ReleaseFloatArrayElements(arg, floatValues, JNI_ABORT);
+}
+
+static void android_animation_PropertyValuesHolder_callTwoIntMethod(
+        JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, int arg1, int arg2)
+{
+    env->CallVoidMethod(target, methodID, arg1, arg2);
+}
+
+static void android_animation_PropertyValuesHolder_callFourIntMethod(
+        JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, int arg1, int arg2,
+        int arg3, int arg4)
+{
+    env->CallVoidMethod(target, methodID, arg1, arg2, arg3, arg4);
+}
+
+static void android_animation_PropertyValuesHolder_callMultipleIntMethod(
+        JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, jintArray arg)
+{
+    jsize parameterCount = env->GetArrayLength(arg);
+    jint *intValues = env->GetIntArrayElements(arg, NULL);
+    jvalue* values = new jvalue[parameterCount];
+    for (int i = 0; i < parameterCount; i++) {
+        values[i].i = intValues[i];
+    }
+    env->CallVoidMethodA(target, methodID, values);
+    delete[] values;
+    env->ReleaseIntArrayElements(arg, intValues, JNI_ABORT);
+}
+
 static JNINativeMethod gMethods[] = {
     {   "nGetIntMethod", "(Ljava/lang/Class;Ljava/lang/String;)I",
             (void*)android_animation_PropertyValuesHolder_getIntMethod },
     {   "nGetFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;)I",
             (void*)android_animation_PropertyValuesHolder_getFloatMethod },
+    {   "nGetMultipleFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;I)I",
+            (void*)android_animation_PropertyValuesHolder_getMultipleFloatMethod },
+    {   "nGetMultipleIntMethod", "(Ljava/lang/Class;Ljava/lang/String;I)I",
+            (void*)android_animation_PropertyValuesHolder_getMultipleIntMethod },
     {   "nCallIntMethod", "(Ljava/lang/Object;II)V",
             (void*)android_animation_PropertyValuesHolder_callIntMethod },
     {   "nCallFloatMethod", "(Ljava/lang/Object;IF)V",
-            (void*)android_animation_PropertyValuesHolder_callFloatMethod }
+            (void*)android_animation_PropertyValuesHolder_callFloatMethod },
+    {   "nCallTwoFloatMethod", "(Ljava/lang/Object;IFF)V",
+            (void*)android_animation_PropertyValuesHolder_callTwoFloatMethod },
+    {   "nCallFourFloatMethod", "(Ljava/lang/Object;IFFFF)V",
+            (void*)android_animation_PropertyValuesHolder_callFourFloatMethod },
+    {   "nCallMultipleFloatMethod", "(Ljava/lang/Object;I[F)V",
+            (void*)android_animation_PropertyValuesHolder_callMultipleFloatMethod },
+    {   "nCallTwoIntMethod", "(Ljava/lang/Object;III)V",
+            (void*)android_animation_PropertyValuesHolder_callTwoIntMethod },
+    {   "nCallFourIntMethod", "(Ljava/lang/Object;IIIII)V",
+            (void*)android_animation_PropertyValuesHolder_callFourIntMethod },
+    {   "nCallMultipleIntMethod", "(Ljava/lang/Object;I[I)V",
+            (void*)android_animation_PropertyValuesHolder_callMultipleIntMethod },
 };
 
 int register_android_animation_PropertyValuesHolder(JNIEnv* env)
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 1c43cc5..03f94b7 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -175,7 +175,7 @@
     // compare the format against the Java constants
     if ((audioFormat != ENCODING_PCM_16BIT)
         && (audioFormat != ENCODING_PCM_8BIT)) {
-        ALOGE("Error creating AudioRecord: unsupported audio format.");
+        ALOGE("Error creating AudioRecord: unsupported audio format %d.", audioFormat);
         return AUDIORECORD_ERROR_SETUP_INVALIDFORMAT;
     }
 
@@ -191,7 +191,7 @@
     size_t frameCount = buffSizeInBytes / frameSize;
 
     if ((uint32_t(source) >= AUDIO_SOURCE_CNT) && (uint32_t(source) != AUDIO_SOURCE_HOTWORD)) {
-        ALOGE("Error creating AudioRecord: unknown source.");
+        ALOGE("Error creating AudioRecord: unknown source %d.", source);
         return AUDIORECORD_ERROR_SETUP_INVALIDSOURCE;
     }
 
@@ -237,8 +237,10 @@
         true,          // threadCanCallJava
         sessionId);
 
-    if (lpRecorder->initCheck() != NO_ERROR) {
-        ALOGE("Error creating AudioRecord instance: initialization check failed.");
+    const status_t status = lpRecorder->initCheck();
+    if (status != NO_ERROR) {
+        ALOGE("Error creating AudioRecord instance: initialization check failed with status %d.",
+                status);
         goto native_init_failure;
     }
 
diff --git a/core/jni/android_net_LocalSocketImpl.cpp b/core/jni/android_net_LocalSocketImpl.cpp
index b9ed28e..9f79f74 100644
--- a/core/jni/android_net_LocalSocketImpl.cpp
+++ b/core/jni/android_net_LocalSocketImpl.cpp
@@ -35,6 +35,7 @@
 
 #include <cutils/sockets.h>
 #include <netinet/tcp.h>
+#include <ScopedUtfChars.h>
 
 namespace android {
 
@@ -52,25 +53,22 @@
                         jobject fileDescriptor, jstring name, jint namespaceId)
 {
     int ret;
-    const char *nameUtf8;
     int fd;
 
-    nameUtf8 = env->GetStringUTFChars(name, NULL);
-
     fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
 
     if (env->ExceptionOccurred() != NULL) {
         return;
     }
 
+    ScopedUtfChars nameUtf8(env, name);
+
     ret = socket_local_client_connect(
                 fd,
-                nameUtf8,
+                nameUtf8.c_str(),
                 namespaceId,
                 SOCK_STREAM);
 
-    env->ReleaseStringUTFChars(name, nameUtf8);
-
     if (ret < 0) {
         jniThrowIOException(env, errno);
         return;
@@ -89,11 +87,10 @@
 {
     int ret;
     int fd;
-    const char *nameUtf8;
-
 
     if (name == NULL) {
         jniThrowNullPointerException(env, NULL);
+        return;
     }
 
     fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
@@ -102,11 +99,9 @@
         return;
     }
 
-    nameUtf8 = env->GetStringUTFChars(name, NULL);
+    ScopedUtfChars nameUtf8(env, name);
 
-    ret = socket_local_server_bind(fd, nameUtf8, namespaceId);
-
-    env->ReleaseStringUTFChars(name, nameUtf8);
+    ret = socket_local_server_bind(fd, nameUtf8.c_str(), namespaceId);
 
     if (ret < 0) {
         jniThrowIOException(env, errno);
@@ -451,6 +446,7 @@
             if (count < 0) {
                 jniThrowException(env, "java/io/IOException",
                     "invalid cmsg length");
+                return -1;
             }
 
             fdArray = env->NewObjectArray(count, class_FileDescriptor, NULL);
diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp
index 9bc69ae..db03b70 100644
--- a/core/jni/android_opengl_GLES20.cpp
+++ b/core/jni/android_opengl_GLES20.cpp
@@ -353,6 +353,7 @@
     const char* _nativename = 0;
 
     if (!name) {
+        _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
         _exceptionMessage = "name == null";
         goto exit;
@@ -2454,6 +2455,7 @@
     const char* _nativename = 0;
 
     if (!name) {
+        _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
         _exceptionMessage = "name == null";
         goto exit;
@@ -3602,6 +3604,7 @@
     const char* _nativename = 0;
 
     if (!name) {
+        _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
         _exceptionMessage = "name == null";
         goto exit;
diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp
index 832d643..4c62a75 100644
--- a/core/jni/android_opengl_GLES30.cpp
+++ b/core/jni/android_opengl_GLES30.cpp
@@ -2511,6 +2511,7 @@
     const char* _nativename = 0;
 
     if (!name) {
+        _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
         _exceptionMessage = "name == null";
         goto exit;
@@ -3361,6 +3362,7 @@
     const char* _nativeuniformBlockName = 0;
 
     if (!uniformBlockName) {
+        _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
         _exceptionMessage = "uniformBlockName == null";
         goto exit;
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 054ee4f6..a041693 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -675,6 +675,7 @@
     // loop until we have the block that represents this process
     do {
         if (fgets(line, 1024, fp) == 0) {
+            fclose(fp);
             return -1;
         }
     } while (strncmp(compare, line, len));
@@ -684,13 +685,16 @@
 
     do {
         if (fgets(line, 1024, fp) == 0) {
+            fclose(fp);
             return -1;
         }
     } while (strncmp(compare, line, len));
 
     // we have the line, now increment the line ptr to the value
     char* ptr = line + len;
-    return atoi(ptr);
+    jint result = atoi(ptr);
+    fclose(fp);
+    return result;
 }
 
 static jint android_os_Debug_getBinderSentTransactions(JNIEnv *env, jobject clazz)
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 8325217..cbed99f 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -344,23 +344,6 @@
     return pri;
 }
 
-jboolean android_os_Process_setOomAdj(JNIEnv* env, jobject clazz,
-                                      jint pid, jint adj)
-{
-#ifdef HAVE_OOM_ADJ
-    char text[64];
-    sprintf(text, "/proc/%d/oom_adj", pid);
-    int fd = open(text, O_WRONLY);
-    if (fd >= 0) {
-        sprintf(text, "%d", adj);
-        write(fd, text, strlen(text));
-        close(fd);
-    }
-    return true;
-#endif
-    return false;
-}
-
 jboolean android_os_Process_setSwappiness(JNIEnv *env, jobject clazz,
                                           jint pid, jboolean is_increased)
 {
@@ -422,7 +405,7 @@
     return *((const jint*)v1) - *((const jint*)v2);
 }
 
-static jlong getFreeMemoryImpl(const char* const sums[], const int sumsLen[], int num)
+static jlong getFreeMemoryImpl(const char* const sums[], const size_t sumsLen[], size_t num)
 {
     int fd = open("/proc/meminfo", O_RDONLY);
 
@@ -441,7 +424,7 @@
     }
     buffer[len] = 0;
 
-    int numFound = 0;
+    size_t numFound = 0;
     jlong mem = 0;
 
     char* p = buffer;
@@ -473,14 +456,14 @@
 static jlong android_os_Process_getFreeMemory(JNIEnv* env, jobject clazz)
 {
     static const char* const sums[] = { "MemFree:", "Cached:", NULL };
-    static const int sumsLen[] = { strlen("MemFree:"), strlen("Cached:"), 0 };
+    static const size_t sumsLen[] = { strlen("MemFree:"), strlen("Cached:"), 0 };
     return getFreeMemoryImpl(sums, sumsLen, 2);
 }
 
 static jlong android_os_Process_getTotalMemory(JNIEnv* env, jobject clazz)
 {
     static const char* const sums[] = { "MemTotal:", NULL };
-    static const int sumsLen[] = { strlen("MemTotal:"), 0 };
+    static const size_t sumsLen[] = { strlen("MemTotal:"), 0 };
     return getFreeMemoryImpl(sums, sumsLen, 1);
 }
 
@@ -745,7 +728,7 @@
 
         jsize end = -1;
         if ((mode&PROC_PARENS) != 0) {
-            while (buffer[i] != ')' && i < endIndex) {
+            while (i < endIndex && buffer[i] != ')') {
                 i++;
             }
             end = i;
@@ -757,7 +740,7 @@
             end = i;
             i++;
         }
-        while (buffer[i] != term && i < endIndex) {
+        while (i < endIndex && buffer[i] != term) {
             i++;
         }
         if (end < 0) {
@@ -767,7 +750,7 @@
         if (i < endIndex) {
             i++;
             if ((mode&PROC_COMBINE) != 0) {
-                while (buffer[i] == term && i < endIndex) {
+                while (i < endIndex && buffer[i] == term) {
                     i++;
                 }
             }
@@ -1023,7 +1006,6 @@
     {"setThreadGroup",      "(II)V", (void*)android_os_Process_setThreadGroup},
     {"setProcessGroup",     "(II)V", (void*)android_os_Process_setProcessGroup},
     {"getProcessGroup",     "(I)I", (void*)android_os_Process_getProcessGroup},
-    {"setOomAdj",   "(II)Z", (void*)android_os_Process_setOomAdj},
     {"setSwappiness",   "(IZ)Z", (void*)android_os_Process_setSwappiness},
     {"setArgV0",    "(Ljava/lang/String;)V", (void*)android_os_Process_setArgV0},
     {"setUid", "(I)I", (void*)android_os_Process_setUid},
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index b720e73..7a763ad 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -298,7 +298,7 @@
 
 static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom) {
-    return renderer->quickRejectNoScissor(left, top, right, bottom);
+    return renderer->quickRejectConservative(left, top, right, bottom);
 }
 
 static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz,
diff --git a/core/jni/android_view_HardwareRenderer.cpp b/core/jni/android_view_GLRenderer.cpp
similarity index 76%
rename from core/jni/android_view_HardwareRenderer.cpp
rename to core/jni/android_view_GLRenderer.cpp
index 479fbe2..7cf93d0 100644
--- a/core/jni/android_view_HardwareRenderer.cpp
+++ b/core/jni/android_view_GLRenderer.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "HardwareRenderer"
+#define LOG_TAG "GLRenderer"
 
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
@@ -60,7 +60,7 @@
 // Surface and display management
 // ----------------------------------------------------------------------------
 
-static jboolean android_view_HardwareRenderer_preserveBackBuffer(JNIEnv* env, jobject clazz) {
+static jboolean android_view_GLRenderer_preserveBackBuffer(JNIEnv* env, jobject clazz) {
     EGLDisplay display = eglGetCurrentDisplay();
     EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
 
@@ -75,7 +75,7 @@
     return error == EGL_SUCCESS;
 }
 
-static jboolean android_view_HardwareRenderer_isBackBufferPreserved(JNIEnv* env, jobject clazz) {
+static jboolean android_view_GLRenderer_isBackBufferPreserved(JNIEnv* env, jobject clazz) {
     EGLDisplay display = eglGetCurrentDisplay();
     EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
     EGLint value;
@@ -95,14 +95,14 @@
 // Tracing and debugging
 // ----------------------------------------------------------------------------
 
-static bool android_view_HardwareRenderer_loadProperties(JNIEnv* env, jobject clazz) {
+static bool android_view_GLRenderer_loadProperties(JNIEnv* env, jobject clazz) {
     if (uirenderer::Caches::hasInstance()) {
         return uirenderer::Caches::getInstance().initProperties();
     }
     return false;
 }
 
-static void android_view_HardwareRenderer_beginFrame(JNIEnv* env, jobject clazz,
+static void android_view_GLRenderer_beginFrame(JNIEnv* env, jobject clazz,
         jintArray size) {
 
     EGLDisplay display = eglGetCurrentDisplay();
@@ -124,7 +124,7 @@
     eglBeginFrame(display, surface);
 }
 
-static jlong android_view_HardwareRenderer_getSystemTime(JNIEnv* env, jobject clazz) {
+static jlong android_view_GLRenderer_getSystemTime(JNIEnv* env, jobject clazz) {
     if (uirenderer::Extensions::getInstance().hasNvSystemTime()) {
         return eglGetSystemTimeNV();
     }
@@ -137,7 +137,7 @@
 // Shaders
 // ----------------------------------------------------------------------------
 
-static void android_view_HardwareRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
+static void android_view_GLRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
         jstring diskCachePath) {
 
     const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
@@ -149,24 +149,24 @@
 // JNI Glue
 // ----------------------------------------------------------------------------
 
-const char* const kClassPathName = "android/view/HardwareRenderer";
+const char* const kClassPathName = "android/view/GLRenderer";
 
 static JNINativeMethod gMethods[] = {
 #ifdef USE_OPENGL_RENDERER
-    { "nIsBackBufferPreserved", "()Z",   (void*) android_view_HardwareRenderer_isBackBufferPreserved },
-    { "nPreserveBackBuffer",    "()Z",   (void*) android_view_HardwareRenderer_preserveBackBuffer },
-    { "nLoadProperties",        "()Z",   (void*) android_view_HardwareRenderer_loadProperties },
+    { "isBackBufferPreserved", "()Z",   (void*) android_view_GLRenderer_isBackBufferPreserved },
+    { "preserveBackBuffer",    "()Z",   (void*) android_view_GLRenderer_preserveBackBuffer },
+    { "loadProperties",        "()Z",   (void*) android_view_GLRenderer_loadProperties },
 
-    { "nBeginFrame",            "([I)V", (void*) android_view_HardwareRenderer_beginFrame },
+    { "beginFrame",            "([I)V", (void*) android_view_GLRenderer_beginFrame },
 
-    { "nGetSystemTime",         "()J",   (void*) android_view_HardwareRenderer_getSystemTime },
+    { "getSystemTime",         "()J",   (void*) android_view_GLRenderer_getSystemTime },
 #endif
 
-    { "nSetupShadersDiskCache", "(Ljava/lang/String;)V",
-            (void*) android_view_HardwareRenderer_setupShadersDiskCache },
+    { "setupShadersDiskCache", "(Ljava/lang/String;)V",
+            (void*) android_view_GLRenderer_setupShadersDiskCache },
 };
 
-int register_android_view_HardwareRenderer(JNIEnv* env) {
+int register_android_view_GLRenderer(JNIEnv* env) {
     return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/jni/com_android_internal_os_ZygoteInit.cpp b/core/jni/com_android_internal_os_ZygoteInit.cpp
index 44452f0..2233ee3 100644
--- a/core/jni/com_android_internal_os_ZygoteInit.cpp
+++ b/core/jni/com_android_internal_os_ZygoteInit.cpp
@@ -159,29 +159,6 @@
     }
 }
 
-static jlong com_android_internal_os_ZygoteInit_capgetPermitted (JNIEnv *env,
-    jobject clazz, jint pid)
-{
-    struct __user_cap_header_struct capheader;
-    struct __user_cap_data_struct capdata;
-    int err;
-
-    memset (&capheader, 0, sizeof(capheader));
-    memset (&capdata, 0, sizeof(capdata));
-
-    capheader.version = _LINUX_CAPABILITY_VERSION;
-    capheader.pid = pid;
-
-    err = capget (&capheader, &capdata);
-
-    if (err < 0) {
-        jniThrowIOException(env, errno);
-        return 0;
-    }
-
-    return (jlong) capdata.permitted;
-}
-
 static jint com_android_internal_os_ZygoteInit_selectReadable (
         JNIEnv *env, jobject clazz, jobjectArray fds)
 {
@@ -274,8 +251,6 @@
             (void *) com_android_internal_os_ZygoteInit_reopenStdio},
     { "setCloseOnExec", "(Ljava/io/FileDescriptor;Z)V",
         (void *)  com_android_internal_os_ZygoteInit_setCloseOnExec},
-    { "capgetPermitted", "(I)J",
-        (void *) com_android_internal_os_ZygoteInit_capgetPermitted },
     { "selectReadable", "([Ljava/io/FileDescriptor;)I",
         (void *) com_android_internal_os_ZygoteInit_selectReadable },
     { "createFileDescriptor", "(I)Ljava/io/FileDescriptor;",
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index b0c26c51..b3b0049 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -183,7 +183,7 @@
             if (array) {
                 releasePointer(_env, array, buf, 0);
             }
-            buf = buf + offset;
+            buf = (char*)buf + offset;
         } else {
             jniThrowException(_env, "java/lang/IllegalArgumentException",
                               "Must use a native order direct Buffer");
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e546117..c923e14 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2102,6 +2102,13 @@
         android:description="@string/permdesc_readFrameBuffer"
         android:protectionLevel="signature|system" />
 
+    <!-- Allows an application to use InputFlinger's low level features.
+    <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.ACCESS_INPUT_FLINGER"
+        android:label="@string/permlab_accessInputFlinger"
+        android:description="@string/permdesc_accessInputFlinger"
+        android:protectionLevel="signature" />
+
     <!-- Allows an application to configure and connect to Wifi displays
          @hide -->
     <permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY"
diff --git a/core/res/res/drawable-hdpi/notify_panel_notification_icon_bg.png b/core/res/res/drawable-hdpi/notify_panel_notification_icon_bg.png
deleted file mode 100644
index 6f37a22..0000000
--- a/core/res/res/drawable-hdpi/notify_panel_notification_icon_bg.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrollbar_handle_accelerated_anim2.9.png b/core/res/res/drawable-hdpi/scrollbar_handle_accelerated_anim2.9.png
index 6eddc3f..fb9e7aa 100644
--- a/core/res/res/drawable-hdpi/scrollbar_handle_accelerated_anim2.9.png
+++ b/core/res/res/drawable-hdpi/scrollbar_handle_accelerated_anim2.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrollbar_handle_accelerated_anim2.9.png b/core/res/res/drawable-ldpi/scrollbar_handle_accelerated_anim2.9.png
index 0562c03..a4ca3e0 100644
--- a/core/res/res/drawable-ldpi/scrollbar_handle_accelerated_anim2.9.png
+++ b/core/res/res/drawable-ldpi/scrollbar_handle_accelerated_anim2.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/notify_panel_notification_icon_bg.png b/core/res/res/drawable-mdpi/notify_panel_notification_icon_bg.png
deleted file mode 100644
index c286875..0000000
--- a/core/res/res/drawable-mdpi/notify_panel_notification_icon_bg.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrollbar_handle_accelerated_anim2.9.png b/core/res/res/drawable-mdpi/scrollbar_handle_accelerated_anim2.9.png
index 766e4c0..6d83bb4 100644
--- a/core/res/res/drawable-mdpi/scrollbar_handle_accelerated_anim2.9.png
+++ b/core/res/res/drawable-mdpi/scrollbar_handle_accelerated_anim2.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/notify_panel_notification_icon_bg.png b/core/res/res/drawable-xhdpi/notify_panel_notification_icon_bg.png
deleted file mode 100644
index 9128e62..0000000
--- a/core/res/res/drawable-xhdpi/notify_panel_notification_icon_bg.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrollbar_handle_accelerated_anim2.9.png b/core/res/res/drawable-xhdpi/scrollbar_handle_accelerated_anim2.9.png
index 3cf84a5..70856c0 100644
--- a/core/res/res/drawable-xhdpi/scrollbar_handle_accelerated_anim2.9.png
+++ b/core/res/res/drawable-xhdpi/scrollbar_handle_accelerated_anim2.9.png
Binary files differ
diff --git a/core/res/res/drawable/notify_panel_notification_icon_bg_tile.xml b/core/res/res/drawable/notify_panel_notification_icon_bg_tile.xml
deleted file mode 100644
index fa3c398..0000000
--- a/core/res/res/drawable/notify_panel_notification_icon_bg_tile.xml
+++ /dev/null
@@ -1,21 +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.
--->
-
-<bitmap
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tileMode="repeat"
-    android:src="@android:drawable/notify_panel_notification_icon_bg"
-    />
diff --git a/core/res/res/layout-land/time_picker_holo.xml b/core/res/res/layout-land/time_picker_holo.xml
new file mode 100644
index 0000000..f5ce1ec
--- /dev/null
+++ b/core/res/res/layout-land/time_picker_holo.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal"
+        android:focusable="true"
+        android:layout_marginLeft="@dimen/timepicker_minimum_margin_sides"
+        android:layout_marginRight="@dimen/timepicker_minimum_margin_sides"
+        android:layout_marginTop="@dimen/timepicker_minimum_margin_top_bottom"
+        android:layout_marginBottom="@dimen/timepicker_minimum_margin_top_bottom">
+    <LinearLayout
+            android:layout_width="@dimen/timepicker_left_side_width"
+            android:layout_height="match_parent"
+            android:orientation="vertical">
+        <FrameLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dip"
+                android:layout_weight="1"
+                android:background="?android:attr/timePickerHeaderBackgroundColor">
+            <include
+                    layout="@layout/time_header_label"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/timepicker_header_height"
+                    android:layout_gravity="center" />
+        </FrameLayout>
+        <LinearLayout
+                android:id="@+id/layout_buttons"
+                style="?android:attr/buttonBarStyle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:background="?android:attr/timePickerHeaderBackgroundColor"
+                android:divider="?android:attr/dividerHorizontal"
+                android:showDividers="beginning">
+            <Button
+                    android:id="@+id/done_button"
+                    style="?android:attr/buttonBarButtonStyle"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:minHeight="48dp"
+                    android:text="@string/done_label"
+                    android:textSize="@dimen/timepicker_done_label_size" />
+        </LinearLayout>
+    </LinearLayout>
+    <android.widget.RadialTimePickerView
+            android:id="@+id/radial_picker"
+            android:layout_width="@dimen/timepicker_radial_picker_dimen"
+            android:layout_height="match_parent"
+            android:layout_gravity="center"
+            android:focusable="true"
+            android:focusableInTouchMode="true" />
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/time_header_label.xml b/core/res/res/layout/time_header_label.xml
new file mode 100644
index 0000000..00cb81b
--- /dev/null
+++ b/core/res/res/layout/time_header_label.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2013 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:id="@+id/time_header"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_gravity="center" >
+
+    <TextView
+            android:id="@+id/hours"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toLeftOf="@+id/separator"
+            android:layout_alignBaseline="@+id/separator"
+            android:textAppearance="?android:attr/timePickerHeaderTimeLabelTextAppearance"/>
+
+    <TextView
+            android:id="@+id/separator"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="@dimen/timepicker_separator_padding"
+            android:paddingRight="@dimen/timepicker_separator_padding"
+            android:layout_centerInParent="true"
+            android:textAppearance="?android:attr/timePickerHeaderTimeLabelTextAppearance"
+            android:importantForAccessibility="no" />
+
+    <TextView
+            android:id="@+id/minutes"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toRightOf="@+id/separator"
+            android:layout_alignBaseline="@+id/separator"
+            android:textAppearance="?android:attr/timePickerHeaderTimeLabelTextAppearance" />
+
+    <TextView
+            android:id="@+id/ampm_label"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="@dimen/timepicker_ampm_left_padding"
+            android:paddingRight="@dimen/timepicker_ampm_left_padding"
+            android:layout_toRightOf="@+id/separator"
+            android:layout_alignBaseline="@+id/separator"
+            android:textAppearance="?android:attr/timePickerHeaderAmPmLabelTextAppearance"
+            android:importantForAccessibility="no" />
+
+</RelativeLayout>
diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_holo.xml
index c6b7d3a..0890fe5 100644
--- a/core/res/res/layout/time_picker_holo.xml
+++ b/core/res/res/layout/time_picker_holo.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 **
-** Copyright 2011, The Android Open Source Project
+** 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.
@@ -17,70 +17,38 @@
 */
 -->
 
-<!-- Layout of time picker -->
-
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/timePickerLayout"
-    android:orientation="horizontal"
-    android:layout_gravity="center_horizontal"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:paddingStart="8dip"
-    android:paddingEnd="8dip">
-
-    <LinearLayout android:orientation="horizontal"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:paddingStart="8dip"
-        android:paddingEnd="8dip"
-        android:layoutDirection="ltr">
-
-        <!-- hour -->
-        <NumberPicker
-            android:id="@+id/hour"
+          android:layout_width="wrap_content"
+          android:layout_height="match_parent"
+          android:orientation="vertical"
+          android:focusable="true" >
+    <include
+            layout="@layout/time_header_label"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/timepicker_header_height"
+            android:layout_gravity="center" />
+    <android.widget.RadialTimePickerView
+            android:id="@+id/radial_picker"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="16dip"
-            android:layout_marginBottom="16dip"
+            android:layout_height="@dimen/timepicker_radial_picker_dimen"
+            android:layout_gravity="center"
             android:focusable="true"
-            android:focusableInTouchMode="true"
-            />
-
-        <!-- divider -->
-        <TextView
-            android:id="@+id/divider"
-            android:layout_width="wrap_content"
+            android:focusableInTouchMode="true" />
+    <LinearLayout
+            android:id="@+id/layout_buttons"
+            style="?android:attr/buttonBarStyle"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginStart="6dip"
-            android:layout_marginEnd="6dip"
-            android:layout_gravity="center_vertical"
-            android:importantForAccessibility="no"
-            />
-
-        <!-- minute -->
-        <NumberPicker
-            android:id="@+id/minute"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="16dip"
-            android:layout_marginBottom="16dip"
-            android:focusable="true"
-            android:focusableInTouchMode="true"
-            />
-
+            android:orientation="vertical"
+            android:divider="?android:attr/dividerHorizontal"
+            android:showDividers="beginning">
+        <Button
+                android:id="@+id/done_button"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:minHeight="48dp"
+                android:text="@string/done_label"
+                android:textSize="@dimen/timepicker_done_label_size"
+                style="?android:attr/buttonBarButtonStyle" />
     </LinearLayout>
-
-    <!-- AM / PM -->
-    <NumberPicker
-        android:id="@+id/amPm"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="16dip"
-        android:layout_marginBottom="16dip"
-        android:layout_marginStart="8dip"
-        android:layout_marginEnd="8dip"
-        android:focusable="true"
-        android:focusableInTouchMode="true"
-        />
-
 </LinearLayout>
diff --git a/core/res/res/layout/time_picker.xml b/core/res/res/layout/time_picker_legacy.xml
similarity index 100%
rename from core/res/res/layout/time_picker.xml
rename to core/res/res/layout/time_picker_legacy.xml
diff --git a/core/res/res/layout/time_picker_legacy_holo.xml b/core/res/res/layout/time_picker_legacy_holo.xml
new file mode 100644
index 0000000..c6b7d3a
--- /dev/null
+++ b/core/res/res/layout/time_picker_legacy_holo.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** 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.
+*/
+-->
+
+<!-- Layout of time picker -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/timePickerLayout"
+    android:orientation="horizontal"
+    android:layout_gravity="center_horizontal"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:paddingStart="8dip"
+    android:paddingEnd="8dip">
+
+    <LinearLayout android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingStart="8dip"
+        android:paddingEnd="8dip"
+        android:layoutDirection="ltr">
+
+        <!-- hour -->
+        <NumberPicker
+            android:id="@+id/hour"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dip"
+            android:layout_marginBottom="16dip"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            />
+
+        <!-- divider -->
+        <TextView
+            android:id="@+id/divider"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="6dip"
+            android:layout_marginEnd="6dip"
+            android:layout_gravity="center_vertical"
+            android:importantForAccessibility="no"
+            />
+
+        <!-- minute -->
+        <NumberPicker
+            android:id="@+id/minute"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dip"
+            android:layout_marginBottom="16dip"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            />
+
+    </LinearLayout>
+
+    <!-- AM / PM -->
+    <NumberPicker
+        android:id="@+id/amPm"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dip"
+        android:layout_marginBottom="16dip"
+        android:layout_marginStart="8dip"
+        android:layout_marginEnd="8dip"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
+        />
+
+</LinearLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0358de3..049816e 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Laat die program toe om SurfaceFlinger se laevlak-kenmerke te gebruik."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lees raambuffer"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Laat die program toe om die inhoud van die raambuffer te lees."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"kry toegang tot InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Laat die program toe om InputFlinger se laevlak-kenmerke te gebruik."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"stel Wi-Fi-skerms op"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Laat die program toe om Wi-Fi-skerms op te stel en daaraan te koppel."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"beheer Wi-Fi-skerms"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Deel met"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Deel met <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Skyfievatsel. Raak en hou."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Gly op vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Gly af vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Gly links vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Gly regs vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Ontsluit"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Stil"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Klank aan"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Soek"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Sleep om te ontsluit."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Prop \'n kopfoon in om te hoor hoe wagwoordsleutels hardop gesê word."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punt."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Probeer later weer"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Swiep van bo af na onder om volskerm te verlaat."</string>
+    <string name="done_label" msgid="2093726099505892398">"Klaar"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Ure se sirkelglyer"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Minute se sirkelglyer"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Kies ure"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Kies minute"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Maandrooster van dae"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Jaarlys"</string>
+    <string name="select_day" msgid="7774759604701773332">"Kies maand en dag"</string>
+    <string name="select_year" msgid="7952052866994196170">"Kies jaar"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> gekies"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> uitgevee"</string>
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 2a7dae7..7b4ec63 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -271,10 +271,10 @@
     <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"መተግበሪያው ሌሎች የመልዕክት መላኪያ መተግበሪያዎች ለመጪ ጥሪዎች በመልዕክት-በኩል-ምላሽ-መስጠት ስራን እንዲይዙ ጥያቄዎች እንዲልክላቸው ያስችለዋል።"</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"የጽሑፍ መልዕክቶችዎን ያንብቡ (ኤስ.ኤም.ኤስ. ወይም ኤም.ኤም.ኤስ.)"</string>
     <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"መገለጫው በጡባዊ ቱኮህ ወይም በSIM ካርድህ የተከማቹ የኤስ.ኤም.ኤስ. መልእክቶችን እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው ይዘት ወይም ሚስጥራዊነትን ከግምት ሳያስገባ ሁሉንም የኤስ.ኤም.ኤስ. መልእክቶች እንዲያነብ ይፈቅድለታል።"</string>
-    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"መገለጫው በስልክህ ወይም በSIM ካርድህ የተከማቹ የኤስ.ኤም.ኤስ. መልእክቶችን እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው ይዘት ወይም ሚስጥራዊነትን ከግምት ሳያስገባ ሁሉንም የኤስ.ኤም.ኤስ. መልእክቶች እንዲያነብ ይፈቅድለታል።"</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"መገለጫው በስልክዎ ወይም በSIM ካርድዎ የተከማቹ የኤስ.ኤም.ኤስ. መልዕክቶችን እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው ይዘት ወይም ሚስጥራዊነትን ከግምት ሳያስገባ ሁሉንም የኤስ.ኤም.ኤስ. መልዕክቶች እንዲያነብ ይፈቅድለታል።"</string>
     <string name="permlab_writeSms" msgid="3216950472636214774">"የጽሑፍ መልዕክቶችህን አርትዕ (ኤስ.ኤም.ኤስ. ወይም ኤም.ኤም.ኤስ.)"</string>
     <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"በጡባዊ ተኮህ ወይም ሲም ካርድህ ላይ ኤስ ኤም ኤስ መልዕክቶችን ለመፃፍ ለመተግበሪያው ይፈቅዳሉ፡፡መልዕክቶችህን ተንኮል አዘል መተግበሪያዎች ሊሰርዙ ይችላሉ፡፡"</string>
-    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"በስልክህ ወይም ሲም ካርድህ ላይ ኤስ ኤም ኤስ መልዕክቶችን ለመፃፍ ለመተግበሪያው ይፈቅዳሉ፡፡መልዕክቶችህን ተንኮል አዘል መተግበሪያዎች ሊሰርዙ ይችላሉ፡፡"</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"በስልክዎ ወይም ሲም ካርድዎ ላይ ኤስ ኤም ኤስ መልዕክቶችን ለመፃፍ ለመተግበሪያው ይፈቅዳሉ። መልዕክቶችዎን ተንኮል አዘል መተግበሪያዎች ሊሰርዙ ይችላሉ።"</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"የፅሁፍ መልዕክቶችን ተቀበል (WAP)"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"መተግበሪያው የWAP መልእክቶችን እንዲያነብ እና እንዲያካሂድ ይፈቅዳል። ይህ ፈቃድ የተላኩልህን መልእክቶች ላንተ ሳያሳይህ የመቆጣጠር ወይም የመሰረዝ ብቃትን ያጠቃልላል።"</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"አሂድ መተግበሪያዎችን ሰርስረው ያውጡ"</string>
@@ -446,10 +446,10 @@
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"መተግበሪያው ስርጭቱ ከተጠናቀቀ በኋላ የሚቀሩ አጣባቂ ስርጭቶችን እንዲልክ ይፈቅድለታል። ከልክ በላይ መጠቀም ስልኩ ብዙ ማህደረ ትውስታን እንዲጠቀም በማድረግ ቀርፋፋ ወይም ያልተረጋጋ ሊያደርገው ይችላል።"</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"እውቂያዎችዎን ያንብቡ"</string>
     <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"መተግበሪያው በጡባዊ ተኮህ ስለተከማቹ ዕውቂያዎች ያሉትን ውሂቦች በሙሉ፤ ጥሪ ያደረግክበትን፣ ኢሜይል የላክበትን ወይም ከተወሰኑ ግለሰቦች ጋር በሌላ መንገድ የተገናኘህበትን ድግምግሞሽ ጨምሮ፣ እንዲያነብ ይፈቅድለታል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብህን እንዲያስቀምጡ የሚፈቅድላቸው ሲሆን ተንኮል አዘል መተግበሪያዎች የእውቂያህን ውሂብ ሳታውቀው ሊያጋሩት ይችላሉ።"</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"መተግበሪያው በስልክህ ስለተከማቹ ዕውቂያዎች ያሉትን ውሂቦች በሙሉ፤ ጥሪ ያደረግክበትን፣ ኢሜይል የላክበትን ወይም ከተወሰኑ ግለሰቦች ጋር በሌላ መንገድ የተገናኘህበትን ድግምግሞሽ ጨምሮ፣ እንዲያነብ ይፈቅድለታል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብህን እንዲያስቀምጡ የሚፈቅድላቸው ሲሆን ተንኮል አዘል መተግበሪያዎች የእውቂያህን ውሂብ ሳታውቀው ሊያጋሩት ይችላሉ።"</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"መተግበሪያው በስልክዎ ስለተከማቹ ዕውቂያዎች ያሉትን ውሂቦች በሙሉ፤ ጥሪ ያደረጉበትን፣ ኢሜይል የላኩበትን ወይም ከተወሰኑ ግለሰቦች ጋር በሌላ መንገድ የተገናኙበትን ድግምግሞሽ ጨምሮ፣ እንዲያነብ ይፈቅድለታል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብዎን እንዲያስቀምጡ የሚፈቅድላቸው ሲሆን ተንኮል አዘል መተግበሪያዎች የእውቂያዎን ውሂብ ሳያውቁት ሊያጋሩት ይችላሉ።"</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"ዕውቂያዎችዎን ያስተካክሉ"</string>
     <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"መተግበሪያው በጡባዊ ቱኮህ ስለተከማቹ የዕውቂያዎችህ ውሂብ በሙሉ፤ ጥሪ ያደረግክበትን፣ ኢሜይል የላክበትን ወይም ከተወሰኑ እውቂያዎች ጋር በሌላ መንገድ የተገናኘህበትን ድግምግሞሽ ጨምሮ፣ እንዲያስተካክል ይፈቅድለታል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብ እንዲሰርዙ ይፈቅድላቸዋል።"</string>
-    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"መተግበሪያው በስልክህ ስለተከማቹ የዕውቂያዎችህ ውሂብ በሙሉ፤ ጥሪ ያደረግክበትን፣ ኢሜይል የላክበትን ወይም ከተወሰኑ እውቂያዎች ጋር በሌላ መንገድ የተገናኘህበትን ድግምግሞሽ ጨምሮ፣ እንዲያስተካክል ይፈቅድለታል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብ እንዲሰርዙ ይፈቅድላቸዋል።"</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"መተግበሪያው በስልክዎ ስለተከማቹ የዕውቂያዎችዎ ውሂብ በሙሉ፤ ጥሪ ያደረጉበትን፣ ኢሜይል የላኩበትን ወይም ከተወሰኑ እውቂያዎች ጋር በሌላ መንገድ የተገናኙበትን ድግምግሞሽ ጨምሮ፣ እንዲያስተካክል ይፈቅድለታል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብ እንዲሰርዙ ይፈቅድላቸዋል።"</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"የጥሪ ምዝግብ ማስታወሻን አንብብ"</string>
     <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"መተግበሪያው ስለገቢና ወጪ ጥሪዎች ያለ ውሂብን ጨምሮ የጡባዊ ተኮህን የጥሪ ምዝግብ ማስታወሻ እንዲያነብ ይፈቅድለታል። ይህ ፈቃድ መተግበሪያው የጥሪ ምዝግብ ማስታወሻ ውሂብህን እንዲያስቀምጥ የሚፈቅድለት ሲሆን ተንኮል አዘል መተግበሪያዎች ሳታውቀው የጥሪ ምዝግብ ማስታወሻ ውሂብህን ሊያጋሩት ይችላሉ።"</string>
     <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"መተግበሪያው ስለገቢና ወጪ ጥሪዎች ያለ ውሂብን ጨምሮ የስልክህን የጥሪ ምዝግብ ማስታወሻ እንዲያነብ ይፈቅድለታል። ይህ ፈቃድ መተግበሪያው የጥሪ ምዝግብ ማስታወሻ ውሂብህን እንዲያስቀምጥ የሚፈቅድለት ሲሆን ተንኮል አዘል መተግበሪያዎች ሳታውቀው የጥሪ ምዝግብ ማስታወሻ ውሂብህን ሊያጋሩት ይችላሉ።"</string>
@@ -466,10 +466,10 @@
     <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"መተግበሪያው ከጓኞችህን ማህበራዊ ዝማኔዎችን እንዲያሳይ ይፈቅድለታል። መረጃ ስታጋራ ተጠንቀቅ -- ይህ መተግበሪያው ከጓደኛ የመጡ የሚመስሉ መልእክቶችን እንዲያዘጋጅ ይፈቅድለታል። ማስታወሻ፦ ይህ ፈቃድ በሁሉም ማህበራዊ አውታረ መረቦች ላይ ላይፈጸም ይችላል።"</string>
     <string name="permlab_readCalendar" msgid="5972727560257612398">"የቀን መቁጠሪያ ክስተቶች ተጨማሪ ሚስጥራዊ መረጃ አንብብ"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"መተግበሪያው የጓደኞችን ወይም የስራ ባልደረቦችን ጨምሮ ሁሉንም በጡባዊ ቱኮህ ላይ የተከማቹ የቀን መቁጠሪያ ክስተቶች እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው የቀን መቁጠሪያ ውሂብህን ሚስጥራዊቱን ከግምት ሳያስገባ እንዲያጋራ ወይም እንዲያስቀምጥ ሊፈቅድለት ይችላል።"</string>
-    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"መተግበሪያው የጓደኞችን ወይም የስራ ባልደረቦችን ጨምሮ ሁሉንም በስልክህ ላይ የተከማቹ የቀን መቁጠሪያ ክስተቶች እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው የቀን መቁጠሪያ ውሂብህን ሚስጥራዊቱን ከግምት ሳያስገባ እንዲያጋራ ወይም እንዲያስቀምጥ ሊፈቅድለት ይችላል።"</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"መተግበሪያው የጓደኞችን ወይም የስራ ባልደረቦችን ጨምሮ ሁሉንም በስልክዎ ላይ የተከማቹ የቀን መቁጠሪያ ክስተቶች እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው የቀን መቁጠሪያ ውሂብዎን ሚስጥራዊነቱን ከግምት ሳያስገባ እንዲያጋራ ወይም እንዲያስቀምጥ ሊፈቅድለት ይችላል።"</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"የቀን መቁጠሪያ ክስተቶችን ቀይር ወይም አክል እና ለእንግዶች ከባለቤቱ ዕውቅና ውጪ ላክ።"</string>
     <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"መተግበሪያው የጓደኞችህን እና የስራ ባልደረቦችህን ጨምሮ በጡባዊ ተኮህ ላይ ልታስተካክላቸው የምትችላቸውን ክስተቶች እንዲያክል፣ እንዲያስወግድ፣ እንዲለውጥ ይፈቅድለታል። ይህ መተግበሪያው ከቀን መቁጠሪያ ባለቤቶች የመጡ የሚመስሉ መልእክቶችን እንዲልክ ወይም ያለባለቤቱ እውቀት ክስተቶችን እንዲያስተካክል ሊፈቅድለት ይችላል።"</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"መተግበሪያው የጓደኞችህን እና የስራ ባልደረቦችህን ጨምሮ በስልክህ ላይ ልታስተካክላቸው የምትችላቸውን ክስተቶች እንዲያክል፣ እንዲያስወግድ፣ እንዲለውጥ ይፈቅድለታል። ይህ መተግበሪያው ከቀን መቁጠሪያ ባለቤቶች የመጡ የሚመስሉ መልእክቶችን እንዲልክ ወይም ያለባለቤቱ እውቀት ክስተቶችን እንዲያስተካክል ሊፈቅድለት ይችላል።"</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"መተግበሪያው የጓደኞችዎን እና የስራ ባልደረቦችዎን ጨምሮ በስልክዎ ላይ ሊያስተካክሏቸው የሚችሏቸውን ክስተቶች እንዲያክል፣ እንዲያስወግድ፣ እንዲለውጥ ይፈቅድለታል። ይህ መተግበሪያው ከቀን መቁጠሪያ ባለቤቶች የመጡ የሚመስሉ መልዕክቶችን እንዲልክ ወይም ያለባለቤቱ እውቀት ክስተቶችን እንዲያስተካክል ሊፈቅድለት ይችላል።"</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"ለሙከራ ጊዜያዊ ሥፍራ ፍጠር።"</string>
     <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"ለሙከራ የማስመሰል የመነሻ ምንጮችን ፍጠር ወይም አዲስ የአካባቢ አቅራቢ ጫን። ይህ መተግበሪያው አካባቢውን እና/ወይም እንደ GPS ወይም የአካባቢ አቅራቢዎች ባሉ ሌላ የመነሻ ምንጮች የተመለሱ ሁኔታዎችን ችላ እንዲል ይፈቅድለታል።"</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ተጨማሪ ሥፍራ አቅራቢ ትዕዛዞችን ድረስ።"</string>
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"መተግበሪያውን የSurfaceFlinger ዝቅተኛ ደረጃ ባህሪያትን ለመጠቀም ይፈቅዳል።"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"የንዑስ ክፈፍ ቋት አንብብ"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"የክፈፍ ቋት ይዘት ለማንበብ ለመተግበሪያው ይፈቅዳሉ።"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger ን መድረስ"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"መተግበሪያው ባለአነስተኛ የInputFlinger ባህሪያት እንዲጠቀም ይፈቅድለታል።"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"የWifi ማሳያዎችን አዋቅር"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"መተግበሪያው የWifi ማሳያዎችን እንዲያዋቅርና ከእነሱ ጋር እንዲገናኝ ይፈቅድለታል።"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"የWifi ማሳያዎችን ተቆጣጠር"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"ተጋራ ከ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ከ <xliff:g id="APPLICATION_NAME">%s</xliff:g> ጋር ተጋራ"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"ባለስላይድ መያዣ፡፡ ዳስ&amp;ያዝ፡፡"</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ላይ አንሸራትት።"</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ታች አንሸራትት።"</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ግራ አንሸራትት።"</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ቀኝ አንሸራትት።"</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"ክፈት"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"ካሜራ"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"ፀጥታ"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"ድምፅ አብራ"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"ፍለጋ"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"ላለመቆለፍ አንሸራት፡፡"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"የይለፍ ቃል ቁልፎች  ሲነገሩ ለመስማት የጆሮ ማዳመጫ ሰካ።"</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"ነጥብ."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"ቆይተው እንደገና ይሞክሩ"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"ከሙሉ ገጽ ማያ ለመውጣት ጣትዎን ከላይ ወደታች ያንሸራትቱ።"</string>
+    <string name="done_label" msgid="2093726099505892398">"ተከናውኗል"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"የሰዓታት ክብ ተንሸራታች"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"የደቂቃዎች ክብ ተንሸራታች"</string>
+    <string name="select_hours" msgid="6043079511766008245">"ሰዓታትን ይምረጡ"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"ደቂቃዎችን ይምረጡ"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"የቀናት የወር ፍርግርግ"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"የዓመት ዝርዝር"</string>
+    <string name="select_day" msgid="7774759604701773332">"ወር እና ቀን ይምረጡ"</string>
+    <string name="select_year" msgid="7952052866994196170">"ዓመት ይምረጡ"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ተመርጧል"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ተሰርዟል"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 18296ea..d936066 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"‏للسماح للتطبيق باستخدام ميزات SurfaceFlinger ذات المستوى المنخفض."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"قراءة المخزن المؤقت للإطارات"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"للسماح للتطبيق بقراءة محتوى المخزن المؤقت للإطارات."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"‏الدخول إلى InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"‏للسماح للتطبيق باستخدام ميزات InputFlinger ذات المستوى المنخفض."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"‏تهيئة شاشات Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"‏للسماح للتطبيق بتهيئة شاشات Wi-Fi والاتصال بها."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"‏التحكم في شاشات Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"مشاركة مع"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"مشاركة مع <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"مقبض التمرير. المس مع الاستمرار."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"تمرير لأعلى لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"تمرير لأسفل لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"تمرير لليسار لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"تمرير لليمين لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"إلغاء تأمين"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"الكاميرا"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"صامت"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"تشغيل الصوت"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"بحث"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"مرر بسرعة لإلغاء التأمين."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"يمكنك توصيل سماعة رأس لسماع مفاتيح كلمة المرور عندما يتم نطقها."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"نقطة"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"أعد المحاولة لاحقًا"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"مرر بسرعة من أعلى لأسفل للخروج من وضع ملء الشاشة."</string>
+    <string name="done_label" msgid="2093726099505892398">"تم"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"شريط التمرير الدائري للساعات"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"شريط التمرير الدائري للدقائق"</string>
+    <string name="select_hours" msgid="6043079511766008245">"تحديد الساعات"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"تحديد الدقائق"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"شبكة الشهر مكونة من الأيام"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"قائمة الأعوام"</string>
+    <string name="select_day" msgid="7774759604701773332">"تحديد الشهر واليوم"</string>
+    <string name="select_year" msgid="7952052866994196170">"تحديد العام"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"تم تحديد <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"تم حذف <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 7772887..479cfcf 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -314,7 +314,7 @@
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"tətbiqdən tətbiqə keçidin qarşısını almaq"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"İstifadəçinin başqa tətbiqə keçməsinin qarşısını alır."</string>
     <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"cari tətbiq informasiyası əldə etmək"</string>
-    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Sahibinə ekranda öndə olan cari tətbiq haqda gizli məlumatı almaq icazəsi verir."</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"Sahibə ekran önündə cari tətbiq və xidmətlər haqqında şəxsi məlumat əldə etməyə imkan verir."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"işə salınan bütün tətbiqləri izləyir və idarə edir"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Tətbiqə sistemin fəaliyyətləri necə başlatdığını nəzarət və kontrol etməyə imkan verir. Zərərli tətbiqlər sistemi tamamilə kompromis edə bilər. Bu icazə yalnız inkişaf üçündür, heç vaxt normal istifadə üçün deyil."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"qaldırılmış yayım paketini göndər"</string>
@@ -470,6 +470,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Tətbiqə aşağı səviyyəli SurfaceFnger özəlliklərini istifadə etməyə icazə verir."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"freym buferi oxuyur"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Tətbiqə freym buferinin kontentini oxumaq icazəsi verir."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger keçidi"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Tətbiqə aşağı səviyyəli InputFlinger funksiyalarını istifadə etməyə icazə verir."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi görüntülərini quraşdır"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tətbiqə Wifi görüntülərini quraşdırmağa və onlara qoşulmağa imkan verir."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WiFi görüntülərini dəyişir"</string>
@@ -1584,5 +1586,6 @@
     <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> saniyə sonra təkrar yoxlayın"</item>
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Daha sonra yenidən yoxlayın."</string>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"Paneli göstərmək üçün ekranın küncünü sürüşdürün"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Paneli göstərmək üçün ekranın küncünü sürüşdürün"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Sistem panelini göstərmək üçün ekranın küncündən sürüşdürün"</string>
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 82bf400..08e79bb 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -470,6 +470,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Tətbiqə aşağı səviyyəli SurfaceFnger özəlliklərini istifadə etməyə icazə verir."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"freym buferi oxuyur"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Tətbiqə freym buferinin kontentini oxumaq icazəsi verir."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger keçidi"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Tətbiqə aşağı səviyyəli InputFlinger funksiyalarını istifadə etməyə icazə verir."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi görüntülərini quraşdır"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tətbiqə Wifi görüntülərini quraşdırmağa və onlara qoşulmağa imkan verir."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WiFi görüntülərini dəyişir"</string>
@@ -1579,5 +1581,6 @@
     <item quantity="one" msgid="4835639969503729874">"Yanlış PİN. 1 saniyə sonra təkrar sınayın."</item>
     <item quantity="other" msgid="8030607343223287654">"Yanlış PİN. <xliff:g id="COUNT">%d</xliff:g> saniyə sonra təkrar sınayın."</item>
   </plurals>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"Paneli göstərmək üçün ekranın küncünü sürüşdürün"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Paneli göstərmək üçün ekranın küncünü sürüşdürün"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Sistem panelini göstərmək üçün ekranın küncündən sürüşdürün"</string>
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 652e4db..0e00f60 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -504,6 +504,10 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Дазваляе прыкладанням выкарыстоўваць нізкаўзроўневыя функцыі SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"чытаць буфер кадраў"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Дазваляе прыкладанням счытваць змесціва буферу кадра."</string>
+    <!-- no translation found for permlab_accessInputFlinger (5348635270689553857) -->
+    <skip />
+    <!-- no translation found for permdesc_accessInputFlinger (2104864941201226616) -->
+    <skip />
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"налада дысплеяў Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дазволiць прыкладанню наладжвацца i падключацца да дысплеяў Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"кіраванне дысплеямi Wi-Fi"</string>
@@ -1474,15 +1478,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Апублікаваць з дапамогай"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Адправiць з дапамогай прыкладання <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Ручка для перасоўвання. Націсніце і ўтрымлівайце."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Правядзіце пальцам уверх, каб атрымаць <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Правядзіце пальцам уніз, каб атрымаць <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Правядзіце пальцам улева, каб атрымаць <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Правядзіце пальцам управа, каб атрымаць <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Разблакаваць"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Ціхі рэжым"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Гук уключаны"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Пошук"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Прагартайце, каб разблакаваць."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Каб праслухаць паролi, падключыце гарнiтуру."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Кропка."</string>
@@ -1823,4 +1818,26 @@
     <!-- no translation found for immersive_mode_confirmation (7227416894979047467) -->
     <!-- no translation found for immersive_mode_confirmation (8554991488096662508) -->
     <skip />
+    <!-- no translation found for done_label (2093726099505892398) -->
+    <skip />
+    <!-- no translation found for hour_picker_description (6698199186859736512) -->
+    <skip />
+    <!-- no translation found for minute_picker_description (8606010966873791190) -->
+    <skip />
+    <!-- no translation found for select_hours (6043079511766008245) -->
+    <skip />
+    <!-- no translation found for select_minutes (3974345615920336087) -->
+    <skip />
+    <!-- no translation found for day_picker_description (8990847925961297968) -->
+    <skip />
+    <!-- no translation found for year_picker_description (5524331207436052403) -->
+    <skip />
+    <!-- no translation found for select_day (7774759604701773332) -->
+    <skip />
+    <!-- no translation found for select_year (7952052866994196170) -->
+    <skip />
+    <!-- no translation found for item_is_selected (949687401682476608) -->
+    <skip />
+    <!-- no translation found for deleted_key (7659477886625566590) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 0d1cdaf..44aca10 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Разрешава на приложението да използва функциите на SurfaceFlinger от ниско ниво."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"четене на кадровия буфер"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Разрешава на приложението да чете съдържанието на кадровия буфер."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"достъп до InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Разрешава на приложението да използва функциите на InputFlinger от ниско ниво."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"конфигуриране на дисплеите през WiFi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Разрешава на приложението да конфигурира и да се свързва с дисплеите през WiFi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"контролиране на дисплеите през WiFi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Споделяне със"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Споделяне със: <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Плъзгаща се дръжка. Докоснете и задръжте."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Плъзнете нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Плъзнете надолу за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Плъзнете наляво за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Плъзнете надясно за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Отключване"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Тих режим"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Включване на звука"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Търсене"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Прокарайте пръст, за да отключите."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Включете слушалки, за да чуете изговарянето на клавишите за паролата."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Точка."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Опитайте отново по-късно"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"За изход от цял екран прекарайте пръст отгоре надолу."</string>
+    <string name="done_label" msgid="2093726099505892398">"Готово"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Кръгов плъзгач за часовете"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Кръгов плъзгач за минутите"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Избиране на часове"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Избиране на минути"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Месечна таблица на дните"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Списък с години"</string>
+    <string name="select_day" msgid="7774759604701773332">"Избиране на месец и ден"</string>
+    <string name="select_year" msgid="7952052866994196170">"Избиране на година"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Избрахте <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Изтрихте <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index cf81367..6e3a106 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permet que l\'aplicació utilitzi funcions SurfaceFlinger de baix nivell."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"llegir la memòria intermèdia de marcs"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permet que l\'aplicació llegeixi el contingut de la memòria intermèdia de marcs."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"accedeix a InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permet que l\'aplicació utilitzi funcions de baix nivell d\'InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configuració de les pantalles Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permet a l\'aplicació configurar-se i connectar-se a les pantalles Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"control de les pantalles Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Comparteix amb"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Comparteix amb <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Llisca el dit. Mantén premut."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Fes lliscar el dit cap amunt per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Fes lliscar el dit cap avall per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Fes lliscar el dit cap a l\'esquerra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Fes lliscar el dit cap a la dreta per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Desbloqueja"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Càmera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Silenci"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Activa el so"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Cerca"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Llisca el dit per desbloquejar."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Connecta un auricular per escoltar les claus de la contrasenya en veu alta."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punt."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Torna-ho a provar més tard"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Fes lliscar el dit cap avall per sortir de la pantalla completa."</string>
+    <string name="done_label" msgid="2093726099505892398">"Fet"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Control circular de les hores"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Control circular dels minuts"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Selecciona les hores"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Selecciona els minuts"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Graella mensual de dies"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Llista anual"</string>
+    <string name="select_day" msgid="7774759604701773332">"Selecciona un mes i un dia"</string>
+    <string name="select_year" msgid="7952052866994196170">"Selecciona un any"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionat"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> suprimit"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 14d6dd5..b45e7a5 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Umožňuje aplikaci používat nízkoúrovňové funkce SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"čtení vyrovnávací paměti snímků"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Umožňuje aplikaci číst obsah vyrovnávací paměti snímků."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"přístup k funkci InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Umožňuje aplikaci používat nízkoúrovňové funkce InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurovat displeje přes Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Povoluje aplikaci připojit a konfigurovat displeje přes Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ovládat displeje přes Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Sdílet s"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Sdílet s aplikací <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvník. Dotkněte se a podržte."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Přejeďte prstem nahoru: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Přejeďte prstem dolů: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Přejeďte prstem doleva: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Přejeďte prstem doprava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Odemknout"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Fotoaparát"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Tichý"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Zapnout zvuk"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Vyhledávání"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Odemknete posunutím prstu."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Chcete-li slyšet, které klávesy jste při zadávání hesla stiskli, připojte sluchátka."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Tečka."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Zkuste to znovu později"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Režim celé obrazovky ukončíte přejetím dolů."</string>
+    <string name="done_label" msgid="2093726099505892398">"Hotovo"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kruhový posuvník hodin"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kruhový posuvník minut"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Zvolte hodiny"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Zvolte minuty"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Dny uspořádané po měsících"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Seznam roků"</string>
+    <string name="select_day" msgid="7774759604701773332">"Vyberte měsíc a den"</string>
+    <string name="select_year" msgid="7952052866994196170">"Vyberte rok"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Vybrána položka <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Číslice <xliff:g id="KEY">%1$s</xliff:g> byla smazána"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index d172d45..74058a3 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -235,13 +235,13 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Lagring"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Få adgang til USB-lager."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Få adgang til SD-kortet."</string>
-    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Tilgængelighedsfunktioner"</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Hjælpefunktioner"</string>
     <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Funktioner, som hjælpeteknologier kan anmode om."</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"hente indholdet i vinduet"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"undersøge indholdet i et vindue, du interagerer med."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"aktivere Udforsk ved berøring"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"De emner, der trykkes på, læses højt, og skærmen kan udforskes ved hjælp af bevægelser."</string>
-    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"aktivere forbedret webtilgængelighed"</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"aktivere forbedret webhjælpefunktioner"</string>
     <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Der installeres muligvis scripts for at gøre appindhold mere tilgængeligt."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"observere tekst, du skriver"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Dette omfatter personlige data såsom kreditkortnumre og adgangskoder."</string>
@@ -313,8 +313,8 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Tillader, at appen kan hente systemets interne tilstand. Ondsindede apps kan hente en lang række fortrolige og beskyttede oplysninger, som de normalt aldrig ville have brug for."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"hente skærmindhold"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Tillader, at appen kan hente indholdet i det aktive vindue. Ondsindede apps kan hente al indholdet i vinduet og undersøge al dens tekst med undtagelse af adgangskoder."</string>
-    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"aktivér tilgængelighed midlertidigt"</string>
-    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Tillader, at en applikation midlertidigt kan aktivere tilgængelighed på enheden. Skadelige apps kan muligvis aktivere tilgængelighed uden brugerens samtykke."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"aktivere hjælpefunktioner midlertidigt"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Tillader, at en app midlertidigt kan aktivere hjælpefunktioner på enheden. Skadelige apps kan muligvis aktivere hjælpefunktioner uden brugerens samtykke."</string>
     <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"hent oplysninger om vinduer"</string>
     <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Tillader, at en applikation henter oplysninger om vinduerne i vinduesadministratoren. Skadelige apps kan muligvis hente oplysninger, der er beregnet til intern systembrug."</string>
     <string name="permlab_filter_events" msgid="8675535648807427389">"filtrer begivenheder"</string>
@@ -368,8 +368,8 @@
     <string name="permdesc_readInputState" msgid="8387754901688728043">"Tillader, at appen kan se de taster, som du trykker på, selv i en anden app (såsom indtastning af adgangskode). Dette bør aldrig være nødvendigt for normale apps."</string>
     <string name="permlab_bindInputMethod" msgid="3360064620230515776">"forpligt til en inputmetode"</string>
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Tillader, at brugeren kan forpligter sig til en inputmetodes grænseflade på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
-    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"bind dig til en tilgængelighedstjeneste"</string>
-    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Tillader, at brugeren binder sig til en grænseflade for en tilgængelighedstjeneste på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"binde dig til en hjælpetjeneste"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Tillader, at appen kan binde sig til en grænseflade for en hjælpetjeneste på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"forbinde til en udskriftstjeneste"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Tillader, at brugeren forbinder til grænsefladen for en udskriftstjeneste på øverste niveau. Dette bør aldrig være nødvendigt for almindelige apps."</string>
     <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"forbinde til en udskriftsspoolertjeneste"</string>
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Tillader, at appen kan bruge SurfaceFlinger-funktioner på lavt niveau."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"læs rammebuffer"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Tillader, at appen kan læse indholdet fra rammebufferen."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"få adgang til InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Giver appen tilladelse til at bruge SurfaceFlinger-funktioner på lavt niveau."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurer Wi-Fi-skærme"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tillader, at appen konfigurerer og opretter forbindelse til Wi-Fi-skærme."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kontrollér Wi-Fi-skærme"</string>
@@ -686,11 +688,11 @@
     <string name="policylab_watchLogin" msgid="914130646942199503">"Overvåg forsøg på oplåsning af skærm"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Overvåg antallet af forkert indtastede adgangskoder, når du låser skærmen op, og lås din tablet, eller slet alle data i den, hvis der er indtastet for mange forkerte adgangskoder."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Overvåg antallet af forkerte adgangskoder ved oplåsning af skærmen, og lås telefonen eller slet alle data på telefonen, hvis der er indtastet for mange forkerte adgangskoder."</string>
-    <string name="policylab_resetPassword" msgid="2620077191242688955">"Skift adgangskode til oplåsning af skærm"</string>
-    <string name="policydesc_resetPassword" msgid="605963962301904458">"Skift adgangskode til oplåsning af skærmen."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Skifte adgangskode til oplåsning af skærm"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Skifter adgangskode til oplåsning af skærmen."</string>
     <string name="policylab_forceLock" msgid="2274085384704248431">"Lås skærmen"</string>
-    <string name="policydesc_forceLock" msgid="1141797588403827138">"Kontroller, hvordan og hvornår skærmen låses."</string>
-    <string name="policylab_wipeData" msgid="3910545446758639713">"Slet alle data"</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"Kontrollerer, hvordan og hvornår skærmen låses."</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"Slette alle data"</string>
     <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Slet din tablets data uden varsel ved at gendanne fabriksindstillingerne."</string>
     <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Slet telefonens data uden varsel ved at gendanne fabriksindstillingerne."</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Angiv enhedens globale proxy"</string>
@@ -1241,20 +1243,20 @@
     <string name="usb_storage_title" msgid="5901459041398751495">"USB er tilsluttet"</string>
     <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Du har fået forbindelse til din computer via USB. Tryk på knappen nedenfor, hvis du vil kopiere filer mellem din computer og din Androids USB-lager."</string>
     <string name="usb_storage_message" product="default" msgid="805351000446037811">"Du har fået forbindelse til din computer via USB. Tryk på knappen nedenfor, hvis du vil kopiere filer mellem din computer og din Androids SD-kort."</string>
-    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Slå USB-lagring til"</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Slå USB-lager til"</string>
     <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Der er et problem med at bruge dit USB-lager som USB-masselager."</string>
     <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Der er et problem med at bruge dit SD-kort som USB-masselager."</string>
     <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB er tilsluttet"</string>
     <string name="usb_storage_notification_message" msgid="939822783828183763">"Tryk for at kopiere filer til/fra din computer."</string>
     <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Slå USB-lagringen fra"</string>
-    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Tryk for at slå USB-lagring fra."</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Tryk for at slå USB-lager fra."</string>
     <string name="usb_storage_stop_title" msgid="660129851708775853">"USB-lager i brug"</string>
-    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Før du slår USB-lagring fra, skal du demontere din Androids USB-lager (\"skubbe enheden ud\") fra din computer."</string>
-    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Før du slår USB-lagring fra, skal du demontere din Androids SD-kort (\"skubbe enheden ud\") fra din computer."</string>
-    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Slå USB-lagring fra"</string>
-    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Der opstod et problem med at slå USB-lagring fra. Kontroller, at du har demonteret USB-værten, og prøv derefter igen."</string>
-    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Slå USB-lagring til"</string>
-    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Hvis du slår USB-lagring til, stoppes nogle af de apps, som du bruger, og de kan være utilgængelige, indtil du slår USB-lagring fra igen."</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Før du slår USB-lager fra, skal du demontere din Androids USB-lager (\"skubbe enheden ud\") fra din computer."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Før du slår USB-lager fra, skal du demontere din Androids SD-kort (\"skubbe enheden ud\") fra din computer."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Slå USB-lager fra"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Der opstod et problem med at slå USB-lager fra. Kontroller, at du har demonteret USB-værten, og prøv derefter igen."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Slå USB-lager til"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Hvis du slår USB-lager til, stoppes nogle af de apps, som du bruger, og de kan være utilgængelige, indtil du slår USB-lager fra igen."</string>
     <string name="dlg_error_title" msgid="7323658469626514207">"USB-handlingen mislykkedes"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
     <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Tilsluttet som en medieenhed"</string>
@@ -1332,7 +1334,7 @@
     <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Der er anmodet om tilladelse\nfor kontoen <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Inputmetode"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synkroniser"</string>
-    <string name="accessibility_binding_label" msgid="4148120742096474641">"Tilgængelighed"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Hjælpefunktioner"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapet"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Skift tapet"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"Underretningslytter"</string>
@@ -1370,7 +1372,7 @@
     <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Demonterer SD-kortet..."</string>
     <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Sletter USB-lageret..."</string>
     <string name="progress_erasing" product="default" msgid="6596988875507043042">"Sletter SD-kortet..."</string>
-    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Kunne ikke slette USB-lagring."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Kunne ikke slette USB-lager."</string>
     <string name="format_error" product="default" msgid="7315248696644510935">"Kunne ikke slette SD-kort."</string>
     <string name="media_bad_removal" msgid="7960864061016603281">"SD-kortet blev fjernet, før det blev demonteret."</string>
     <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB-lager bliver kontrolleret."</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Del med"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Del med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Glidende håndtag. Tryk og hold nede."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Glid op for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Glid ned for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Glid til venstre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Glid til højre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Lås op"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Lydløs"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Lyd slået til"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Søgning"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Glid hurtigt henover for at låse op."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Tilslut et headset for at høre tasterne blive læst højt ved angivelse af adgangskode."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punktum."</string>
@@ -1551,9 +1544,9 @@
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Fjern"</string>
     <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Skal lydstyrken være over det anbefalede niveau?\nDu kan skade din hørelse ved at lytte ved høj lydstyrke i længere tid."</string>
-    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hold fortsat to fingre nede for at aktivere tilgængelighed."</string>
-    <string name="accessibility_enabled" msgid="1381972048564547685">"Tilgængelighed aktiveret."</string>
-    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Tilgængelighed er annulleret."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Bliv ved med at holde to fingre nede for at aktivere hjælpefunktioner."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Hjælpefunktioner er aktiveret."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Hjælpefunktioner er annulleret."</string>
     <string name="user_switched" msgid="3768006783166984410">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Ejer"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fejl"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Prøv igen senere"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Stryg ned fra toppen for at afslutte fuld skærm"</string>
+    <string name="done_label" msgid="2093726099505892398">"Udfør"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Cirkulær timevælger"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Cirkulær minutvælger"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Vælg timer"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Vælg minutter"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Månedsgitter med dage"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Liste over år"</string>
+    <string name="select_day" msgid="7774759604701773332">"Vælg måned og dag"</string>
+    <string name="select_year" msgid="7952052866994196170">"Vælg år"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> er valgt"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> er slettet"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 34f28fc..e30d879 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Ermöglicht der App, die systemnahen SurfaceFlinger-Funktionen zu verwenden"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"Frame-Puffer lesen"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Ermöglicht der App, den Inhalt des Frame-Puffers zu lesen"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"Auf InputFlinger zugreifen"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Ermöglicht der App, die systemnahen InputFlinger-Funktionen zu verwenden"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"WLAN-Anzeigen konfigurieren"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Erlaubt der App, WLAN-Anzeigen zu konfigurieren und eine Verbindung zu diesen herzustellen"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WLAN-Anzeigen steuern"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Teilen mit"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Mit <xliff:g id="APPLICATION_NAME">%s</xliff:g> teilen"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Schieberegler: Berühren und halten"</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben schieben"</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach unten schieben"</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links schieben"</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach rechts schieben"</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Entsperren"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Lautlos"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Ton ein"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Suche"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Zum Entsperren den Finger über den Bildschirm ziehen"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Schließen Sie ein Headset an, um das Passwort gesprochen zu hören."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkt."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Später erneut versuchen"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Zum Schließen des Vollbilds von oben nach unten wischen"</string>
+    <string name="done_label" msgid="2093726099505892398">"Fertig"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kreisförmiger Schieberegler für Stunden"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kreisförmiger Schieberegler für Minuten"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Stunden auswählen"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Minuten auswählen"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Monatsraster mit einzelnen Tagen"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Jahresliste"</string>
+    <string name="select_day" msgid="7774759604701773332">"Monat und Tag auswählen"</string>
+    <string name="select_year" msgid="7952052866994196170">"Jahr auswählen"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ausgewählt"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> gelöscht"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index ee98ceb..4d5741d 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Επιτρέπει σε μια εφαρμογή να χρησιμοποιεί λειτουργίες SurfaceFlinger χαμηλού επιπέδου."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"ανάγνωση προσωρινής μνήμης πλαισίου"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Επιτρέπει στην εφαρμογή την ανάγνωση του περιεχομένου της προσωρινής μνήμης πλαισίου."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"πρόσβαση στο InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Επιτρέπει σε μια εφαρμογή να χρησιμοποιεί λειτουργίες InputFlinger χαμηλού επιπέδου."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"διαμόρφωση οθονών Wifi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Επιτρέπει τη διαμόρφωση της εφαρμογής και τη σύνδεσης σε οθόνες Wifi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"έλεγχος οθονών Wifi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Κοινή χρήση με"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Κοινή χρήση με <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Στοιχείο χειρισμού με δυνατότητα ολίσθησης. Αγγίξτε και πατήστε παρατεταμένα."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Κύλιση προς τα επάνω για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Κύλιση προς τα κάτω για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Κύλιση προς τα αριστερά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Κύλιση προς τα δεξιά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Ξεκλείδωμα"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Φωτογραφική μηχανή"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Αθόρυβο"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Ενεργοποίηση ήχου"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Αναζήτηση"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Σύρετε για ξεκλείδωμα."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Συνδέστε ακουστικά για να ακούσετε τα πλήκτρα του κωδικού πρόσβασης να εκφωνούνται."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Τελεία."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Δοκιμάστε ξανά αργότερα"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Σάρωση προς τα κάτω για έξοδο από πλήρη οθόνη"</string>
+    <string name="done_label" msgid="2093726099505892398">"Τέλος"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Κυκλικό ρυθμιστικό ωρών"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Κυκλικό ρυθμιστικό λεπτών"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Επιλογή ωρών"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Επιλογή λεπτών"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Πλέγμα ημερών του μήνα"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Λίστα ετών"</string>
+    <string name="select_day" msgid="7774759604701773332">"Επιλογή μήνα και ημέρας"</string>
+    <string name="select_year" msgid="7952052866994196170">"Επιλογή έτους"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Επιλέχτηκε το στοιχείο <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> διαγράφηκε"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index d2c53cc..3dc2064 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Allows the app to use SurfaceFlinger low-level features."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"read frame buffer"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Allows the app to read the content of the frame buffer."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"access InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Allows the app to use InputFlinger low-level features."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configure Wi-Fi displays"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Allows the app to configure and connect to Wi-Fi displays."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"control Wi-Fi displays"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Share with"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Share with <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Sliding handle. Touch &amp; hold."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Slide down for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Slide right for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Unlock"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Silent"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Sound on"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Swipe to unlock."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Plug in a headset to hear password keys spoken."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Try again later"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Swipe down from the top to exit full screen."</string>
+    <string name="done_label" msgid="2093726099505892398">"Finished"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Hours circular slider"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Minutes circular slider"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Select hours"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Select minutes"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Month grid of days"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Year list"</string>
+    <string name="select_day" msgid="7774759604701773332">"Select month and day"</string>
+    <string name="select_year" msgid="7952052866994196170">"Select year"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selected"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> deleted"</string>
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index d2c53cc..3dc2064 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Allows the app to use SurfaceFlinger low-level features."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"read frame buffer"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Allows the app to read the content of the frame buffer."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"access InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Allows the app to use InputFlinger low-level features."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configure Wi-Fi displays"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Allows the app to configure and connect to Wi-Fi displays."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"control Wi-Fi displays"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Share with"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Share with <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Sliding handle. Touch &amp; hold."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Slide down for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Slide right for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Unlock"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Silent"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Sound on"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Swipe to unlock."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Plug in a headset to hear password keys spoken."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Try again later"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Swipe down from the top to exit full screen."</string>
+    <string name="done_label" msgid="2093726099505892398">"Finished"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Hours circular slider"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Minutes circular slider"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Select hours"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Select minutes"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Month grid of days"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Year list"</string>
+    <string name="select_day" msgid="7774759604701773332">"Select month and day"</string>
+    <string name="select_year" msgid="7952052866994196170">"Select year"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selected"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> deleted"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 114f6f5..9a78369c 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permite que la aplicación utilice funciones de SurfaceFlinger de bajo nivel."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"leer el búfer de tramas"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permite que la aplicación lea el contenido del búfer de tramas."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"acceder a InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite que la aplicación utilice funciones de InputFlinger de bajo nivel."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurar pantallas Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que la aplicación configure y se conecte a pantallas Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar pantallas Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartir con"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartir con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Mantén presionado el controlador deslizante."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Desliza el dedo hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Desliza el dedo hacia la derecha para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Cámara"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Sonido activado"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Desliza el dedo para desbloquear."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conecta un auricular para escuchar las contraseñas."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punto"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Vuelve a intentar más tarde."</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Desliza el dedo hacia abajo para salir de la pantalla completa."</string>
+    <string name="done_label" msgid="2093726099505892398">"Listo"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Control deslizante circular de horas"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Control deslizante circular de minutos"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Seleccionar horas"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Seleccionar minutos"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Cuadrícula mensual de días"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Lista de años"</string>
+    <string name="select_day" msgid="7774759604701773332">"Seleccionar mes y día"</string>
+    <string name="select_year" msgid="7952052866994196170">"Seleccionar año"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionado"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> borrado"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index f758989..d25b4e3 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permite que la aplicación use funciones de SurfaceFlinger de nivel inferior."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"leer memoria de almacenamiento intermedio"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permite que la aplicación lea el contenido de la memoria de almacenamiento intermedio."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"acceder a InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite que la aplicación utilice funciones de bajo nivel de SurfaceFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurar pantallas Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que la aplicación configure pantallas Wi-Fi y se conecte a ellas."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar pantallas Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartir con"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartir con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Mantén pulsado el icono de desbloqueo y deslízalo."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Desliza el dedo hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Desliza el dedo hacia la derecha para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Cámara"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Silencio"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Sonido activado"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Desliza el dedo para desbloquear."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conecta un auricular para escuchar las contraseñas."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punto"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Volver a intentar más tarde"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Desliza el dedo hacia abajo para salir de la pantalla completa"</string>
+    <string name="done_label" msgid="2093726099505892398">"Listo"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Control deslizante circular de horas"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Control deslizante circular de minutos"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Seleccionar horas"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Seleccionar minutos"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Cuadrícula mensual de días"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Lista de años"</string>
+    <string name="select_day" msgid="7774759604701773332">"Seleccionar mes y día"</string>
+    <string name="select_year" msgid="7952052866994196170">"Seleccionar año"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionado"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string>
 </resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 39523ef..74f6e19 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Võimaldab rakendusel kasutada SurfaceFlingeri madalatasemelisi funktsioone."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"loe kaadripuhvrit"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Võimaldab rakendusel kaadripuhvri sisu lugeda."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"juurdepääs InputFlingerile"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Lubab rakendusel kasutada InputFlingeri madalatasemelisi funktsioone."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"WiFi-ekraanide seadistamine"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Lubab rakendusel seadistada WiFi-ekraane ja nendega ühendus luua."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WiFi-ekraanide juhtimine"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Jaga:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Jaga rakendusega <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Libistamispide. Puudutage ja hoidke all."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Lohistage üles: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Lohistage alla: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Lohistage vasakule: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Lohistage paremale: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Luku avamine"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kaamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Hääletu"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Heli on sees"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Otsing"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Avamiseks tõmmake sõrmega."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Paroolide kuulamiseks ühendage peakomplekt."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkt."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Proovige hiljem uuesti"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Täisekraanilt väljumiseks pühkige ülevalt alla."</string>
+    <string name="done_label" msgid="2093726099505892398">"Valmis"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Ringikujuline tunniliugur"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Ringikujuline minutiliugur"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Tundide valimine"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Minutite valimine"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Päevad kuu ruudustikus"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Aastate loend"</string>
+    <string name="select_day" msgid="7774759604701773332">"Kuu ja päeva valimine"</string>
+    <string name="select_year" msgid="7952052866994196170">"Aasta valimine"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> on valitud"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> on kustutatud"</string>
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index ec0d930..0694744 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1583,5 +1583,6 @@
     <item quantity="one" msgid="4835639969503729874">"Vale PIN-kood. Proovige 1 s pärast."</item>
     <item quantity="other" msgid="8030607343223287654">"Vale PIN-kood. Proovige <xliff:g id="COUNT">%d</xliff:g> s pärast."</item>
   </plurals>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"Riba kuvam. pühkige ekraani serva"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Riba kuvam. pühkige ekraani serva"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Süsteemiriba kuvamiseks pühkige ekraani servast"</string>
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 93a8eec..ce7e203 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"‏اجازه می‎دهد برنامه از ویژگی‌های سطح پایین SurfaceFlinger استفاده کند."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"خواندن بافر قاب"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"‏به برنامه اجازه می‎دهد تا محتوای بافر کادر را بخواند."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"‏دسترسی به InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"‏اجازه می‎دهد برنامه از قابلیت‌های سطح پایین InputFlinger استفاده کند."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"‏پیکربندی صفحه نمایش‌های Wi‑Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"‏به برنامه اجازه می‌دهد تا اتصال به صفحات نمایش Wi‑Fi را پیکربندی کند."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"‏کنترل صفحه نمایش‌های Wi‑Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"اشتراک‌گذاری با"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"اشتراک‌گذاری با <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"اهرم کنترل حرکت. لمس کرده و نگهدارید."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"لغزاندن به بالا برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"لغزاندن به پایین برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"لغزاندن به چپ برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"لغزاندن به راست برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"بازکردن قفل"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"دوربین"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"ساکت"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"صدا روشن"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"جستجو"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"برای بازگشایی قفل، بلغزانید."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"برای شنیدن کلیدهای گذرواژه که با صدای بلند خوانده می‌شوند، هدست را وصل کنید."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"نقطه."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"بعداً دوباره امتحان کنید"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"برای خروج از حالت تمام صفحه، انگشت خود را به تندی از بالای صفحه به پایین بکشید."</string>
+    <string name="done_label" msgid="2093726099505892398">"انجام شد"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"لغزنده دایره‌ای ساعت"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"لغزنده دایره‌ای دقیقه"</string>
+    <string name="select_hours" msgid="6043079511766008245">"انتخاب ساعت"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"انتخاب دقیقه"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"جدول روزها براساس ماه"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"لیست سال‌ها"</string>
+    <string name="select_day" msgid="7774759604701773332">"انتخاب ماه و روز"</string>
+    <string name="select_year" msgid="7952052866994196170">"انتخاب سال"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> انتخاب شد"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> حذف شد"</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index e4d4e3e..80ad52dd 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Antaa sovelluksen käyttää SurfaceFlingerin matalan tason ominaisuuksia."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lue kehyspuskuria"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Antaa sovelluksen lukea kehyspuskurin sisältöä."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlingerin käyttäminen"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Antaa sovelluksen käyttää InputFlingerin matalan tason ominaisuuksia."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"määritä wifi-näyttöjen asetukset"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Antaa sovelluksen määrittää wifi-näyttöjä ja muodostaa yhteyden niihin."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"hallitse wifi-näyttöjä"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Jaa seuraavien kanssa:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Jaa sovelluksessa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Liukuva valitsin. Kosketa pitkään."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Liu\'uta ylös ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Liu\'uta alas ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Liu\'uta vasemmalle ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Liu\'uta oikealle ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Poista lukitus"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Äänetön"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Ääni käytössä"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Haku"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Poista lukitus liu\'uttamalla."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Liitä kuulokkeet kuullaksesi, mitä näppäimiä painat kirjoittaessasi salasanaa."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Piste."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Yritä myöhemmin uudelleen"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Poistu koko näytön tilasta pyyhkäisemällä alas."</string>
+    <string name="done_label" msgid="2093726099505892398">"Valmis"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Tuntien ympyränmuotoinen liukusäädin"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Minuuttien ympyränmuotoinen liukusäädin"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Valitse tunnit"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Valitse minuutit"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Päiväruudukko kuukausittain"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Vuosiluettelo"</string>
+    <string name="select_day" msgid="7774759604701773332">"Valitse kuukausi ja päivä"</string>
+    <string name="select_year" msgid="7952052866994196170">"Valitse vuosi"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> on valittu"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> poistettiin"</string>
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 7c11f9a..c6806c1 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permet à l\'application d\'utiliser les fonctionnalités de bas niveau de SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lire la mémoire tampon graphique"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permet à l\'application de lire le contenu de la mémoire tampon graphique."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"accéder à InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permet à l\'application d\'utiliser les fonctionnalités de bas niveau de SurfaceFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurer les écrans Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permet à l\'application de configurer des écrans Wi-Fi et de s\'y connecter."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"contrôler les écrans Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Partagez avec"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Partager avec <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Poignée coulissante. Appuyez de manière prolongée."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Faire glisser le doigt vers le haut : <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Faire glisser le doigt vers le bas : <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Faites glisser votre doigt vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Faites glisser votre doigt vers la droite pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Déverrouiller"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Appareil photo"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Mode silencieux"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Son activé"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Recherche"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Faites glisser votre doigt pour déverrouiller l\'appareil."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Branchez des écouteurs pour entendre l\'énoncé des touches lors de la saisie du mot de passe."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Point."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Réessayez plus tard"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Balayez vers le bas pour quitter le mode plein écran"</string>
+    <string name="done_label" msgid="2093726099505892398">"Terminé"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Curseur circulaire des heures"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Curseur circulaire des minutes"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Sélectionnez les heures"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Sélectionnez les minutes"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Calendrier mensuel sous forme de grille"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Liste des années"</string>
+    <string name="select_day" msgid="7774759604701773332">"Sélectionnez un mois et un jour"</string>
+    <string name="select_year" msgid="7952052866994196170">"Sélectionnez une année"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"« <xliff:g id="ITEM">%1$s</xliff:g> » a été sélectionné"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"« <xliff:g id="KEY">%1$s</xliff:g> » a été supprimé"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 04a55f2..46b1f6a 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permet à l\'application d\'utiliser les fonctionnalités de bas niveau de SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"Lecture de la mémoire tampon graphique"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permet à l\'application de lire le contenu de la mémoire tampon graphique."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"accéder à InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permet à l\'application d\'utiliser les fonctionnalités de base d\'InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurer les écrans Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permet à l\'application de configurer des écrans Wi-Fi et de s\'y connecter."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"contrôler les écrans Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Partager avec"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Partager avec <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Poignée coulissante. Appuyez de manière prolongée."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Faites glisser vers le haut pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Faites glisser vers le bas pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Faites glisser vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Faites glisser vers la droite pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Déverrouiller"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Appareil photo"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Mode silencieux"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Son activé"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Rechercher"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Faites glisser votre doigt pour déverrouiller l\'appareil."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Branchez des écouteurs pour entendre l\'énoncé des touches lors de la saisie du mot de passe."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Point."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Veuillez réessayer ultérieurement."</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Faites glisser le doigt vers le bas pour quitter le mode plein écran."</string>
+    <string name="done_label" msgid="2093726099505892398">"OK"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Curseur circulaire des heures"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Curseur circulaire des minutes"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Sélectionner une heure"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Sélectionner des minutes"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Calendrier mensuel sous forme de grille"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Liste des années"</string>
+    <string name="select_day" msgid="7774759604701773332">"Sélectionner un mois et un jour"</string>
+    <string name="select_year" msgid="7952052866994196170">"Sélectionner une année"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"\"<xliff:g id="ITEM">%1$s</xliff:g>\" sélectionné"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"\"<xliff:g id="KEY">%1$s</xliff:g>\" supprimé"</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 2650108..69307aa 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"ऐप्स को SurfaceFlinger निम्‍न-स्‍तर सुविधाएं उपयोग करने देता है."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"फ़्रेम बफ़र पढ़ें"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"ऐप्स को फ़्रेम बफ़र की सामग्री पढ़ने देता है."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger एक्सेस करें"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"ऐप्स को InputFlinger निम्‍न-स्‍तर सुविधाओं का उपयोग करने देता है."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi डिस्प्ले को कॉन्फ़िगर करें"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"ऐप्स  को कॉन्फ़िगर करने देता है और Wifi डिस्प्ले से कनेक्ट करता है."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi डिस्प्ले को नियंत्रित करें"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"इसके साथ साझा करें:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> के साथ साझा करें"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"स्लाइडिंग हैंडल. स्पर्श करके रखें."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर स्‍लाइड करें."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए नीचे स्‍लाइड करें."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं स्‍लाइड करें."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए दाएं स्‍लाइड करें."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"अनलॉक करें"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"कैमरा"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"मौन"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"ध्‍वनि चालू करें"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"खोजें"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"अनलॉक करने के लिए स्‍वाइप करें."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"बोली गईं पासवर्ड कुंजियां सुनने के लिए हेडसेट प्‍लग इन करें."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"बिंदु."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"बाद में पुनः प्रयास करें"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"पूर्ण स्क्रीन से बाहर आने के लिए ऊपर से नीचे स्वाइप करें."</string>
+    <string name="done_label" msgid="2093726099505892398">"पूर्ण"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"घंटो का चक्राकार स्लाइडर"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"मिनटों का चक्राकार स्लाइडर"</string>
+    <string name="select_hours" msgid="6043079511766008245">"घंटे चुनें"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"मिनट चुनें"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"दिनों की माह ग्रिड"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"वर्ष की सूची"</string>
+    <string name="select_day" msgid="7774759604701773332">"माह और दिन चुनें"</string>
+    <string name="select_year" msgid="7952052866994196170">"वर्ष चुनें"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> चयनित"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> को हटा दिया गया"</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 829c03d..7c2261e 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Aplikaciji omogućuje upotrebu značajki niske razine SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"čitanje međuspremnika okvira"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Aplikaciji omogućuje čitanje sadržaja međuspremnika okvira."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"pristupi InputFlingeru"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Dopušta aplikaciji upotrebu značajki niske razine InputFlingera."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfiguriraj Wifi zaslone"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Omogućuje aplikaciji konfiguriranje i povezivanje s Wi-Fi zaslonima."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"upravljaj Wifi zaslonima"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Dijeljenje sa"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dijeli s aplikacijom <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Klizna ručka. Dodirnite i držite."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Kliznite prema gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Kliznite prema dolje za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Kliznite lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Kliznite desno za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Otključaj"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Bešumno"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Zvuk je uključen"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Pretraživanje"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Prijeđite prstima da biste otključali."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Priključite slušalice kako biste čuli izgovaranje tipki zaporke."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Točka."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Pokušajte ponovo kasnije"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Prijeđite prstom s vrha prema dolje za izlaz iz cijelog zaslona."</string>
+    <string name="done_label" msgid="2093726099505892398">"Gotovo"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kružni klizač sati"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kružni klizač minuta"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Odaberite sate"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Odaberite minute"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Mreža dana u mjesecu"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Popis godina"</string>
+    <string name="select_day" msgid="7774759604701773332">"Odaberite mjesec i dan"</string>
+    <string name="select_year" msgid="7952052866994196170">"Odaberite godinu"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Odabrana je stavka <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Izbrisan je broj <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 4c9f400..8d3ee31 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Lehetővé teszi az alkalmazás számára a SurfaceFlinger alacsony szintű funkciók használatát."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"keretpuffer olvasása"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Lehetővé teszi az alkalmazás számára a keretpuffer tartalmának olvasását."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"hozzáférés az InputFlingerhez"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Lehetővé teszi az alkalmazás számára az InputFlinger alacsony szintű funkciók használatát."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wi-Fi kijelzők konfigurálása"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Lehetővé teszi, hogy az alkalmazás Wi-Fi kijelzőket konfiguráljon, és csatlakozzon hozzájuk."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi kijelzők irányítása"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Megosztás a következővel:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Ossza meg a következő alkalmazással: <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Csúsztatható fogantyú. Érintse meg és tartsa."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa felfelé."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa lefelé."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa balra."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa jobbra."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Feloldás"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Némítás"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Hang bekapcsolása"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Keresés"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"A feloldásához húzza végig az ujját."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Csatlakoztasson egy fülhallgatót, ha hallani szeretné a jelszó betűit felolvasva."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Pont."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Próbálkozzon később"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"A teljes képernyős nézetből való kilépéshez húzza ujját a képernyő tetejétől lefelé."</string>
+    <string name="done_label" msgid="2093726099505892398">"Kész"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Óra kör alakú csúszkája"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Perc kör alakú csúszkája"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Óra kiválasztása"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Perc kiválasztása"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Napok havi leosztásban"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Évek listája"</string>
+    <string name="select_day" msgid="7774759604701773332">"Válassza ki a hónapot és a napot"</string>
+    <string name="select_year" msgid="7952052866994196170">"Válassza ki az évet"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> kiválasztva"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"A(z) <xliff:g id="KEY">%1$s</xliff:g> érték törölve"</string>
 </resources>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 85eedba..75221a8 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Թույլ է տալիս հավելվածին օգտագործել SurfaceFlinger ցածր մակարդակի գործառույթները:"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"կարդալ շրջանակի պահնակը"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Թույլ է տալիս հավելվածին կարդալ շրջանակի պահնակի բովանդակությունը:"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"մուտք գործել InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Թույլ է տալիս ծրագրին օգտագործել InputFlinger ցածր մակարդակի գործառույթները:"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"կարգավորել WiFi-ի ցուցադրումը"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Թույլ է տալիս հավելվածին կարգավորել և միանալ WiFi ցուցադրիչներին:"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"կառավարել Wifi-ի ցուցադրումը"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Տարածել"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Համօգտագործել <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ի հետ"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Սահող բռնակ: Հպել &amp; պահել:"</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Սահեցրեք վերև <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Սահեցրեք ցած <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Սահեցրեք ձախ` <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Սահեցրեք աջ` <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Ապակողպել"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Ֆոտոխցիկ"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Լուռ"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Ձայնը միացնել"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Որոնել"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Սահեցրեք` ապակողպելու համար:"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Միացրեք ականջակալները` արտասանվող գաղտնաբառը լսելու համար:"</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Կետ:"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Կրկին փորձեք մի փոքր ուշ"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Սահահարվածեք վերից վար՝ ամբողջական էկրանից դուրս գալու համար:"</string>
+    <string name="done_label" msgid="2093726099505892398">"Պատրաստ է"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Ժամերի ընտրություն թվատախտակից"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Րոպեների ընտրություն թվատախտակից"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Ընտրեք ժամը"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Ընտրեք րոպեն"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Ամսաթվի ընտրության պատուհան"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Տարիների ցանկ"</string>
+    <string name="select_day" msgid="7774759604701773332">"Ընտրեք ամիսն ու օրը"</string>
+    <string name="select_year" msgid="7952052866994196170">"Ընտրեք տարին"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Ընտրված է <xliff:g id="ITEM">%1$s</xliff:g> տարրը"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> թիվը ջնջված է"</string>
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 1b04923..60c5c55 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1581,5 +1581,6 @@
     <item quantity="one" msgid="4835639969503729874">"PIN-ը սխալ է: Փորձեք կրկին 1 վայրկյանից:"</item>
     <item quantity="other" msgid="8030607343223287654">"PIN-ը սխալ է: Փորձեք կրկին <xliff:g id="COUNT">%d</xliff:g> վայրկյանից:"</item>
   </plurals>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"Սահեցրեք էկրանի եզրով՝ գոտին բացելու համար"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Սահեցրեք էկրանի եզրով՝ գոտին բացելու համար"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Սահեցրեք էկրանի եզրով՝ համակարգային գոտին բացելու համար"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 633621a..4a7ee92 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Mengizinkan apl menggunakan fitur tingkat rendah SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"baca buffer frame"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Mengizinkan apl membaca konten penyangga frame."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"mengakses InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Memungkinkan aplikasi menggunakan fitur tingkat rendah InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"mengonfigurasi tampilan Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Izinkan aplikasi mengonfigurasi dan terhubung ke tampilan Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"mengontrol tampilan Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Berbagi dengan"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Berbagi dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Gagang geser. Sentuh &amp; tahan."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Geser ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Geser ke bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Geser ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Geser ke kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Membuka gembok"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Suara hidup"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Telusuri"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Gesek untuk membuka kunci."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Pasang headset untuk mendengar tombol sandi yang diucapkan."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Titik."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Coba lagi nanti"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Gesek dari atas ke bawah untuk keluar dari layar penuh."</string>
+    <string name="done_label" msgid="2093726099505892398">"Selesai"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Penggeser putar jam"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Penggeser putar menit"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Pilih jam"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Pilih menit"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Kisi hari pada bulan"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Daftar tahun"</string>
+    <string name="select_day" msgid="7774759604701773332">"Pilih bulan dan hari"</string>
+    <string name="select_year" msgid="7952052866994196170">"Pilih tahun"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> dipilih"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> dihapus"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 6bae95b..8ba843a 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Consente all\'applicazione l\'utilizzo di funzioni di basso livello SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lettura buffer di frame"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Consente all\'applicazione di leggere i contenuti del buffer di frame."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"accesso a InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Consente all\'applicazione di utilizzare funzioni di basso livello InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurazione di schermi Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Consente all\'applicazione di configurare schermi Wi-Fi e di collegarsi a essi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controllo di schermi Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Condividi con"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Condividi con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Maniglia scorrevole. Tocca e tieni premuto."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Su per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Giù per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"A sinistra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"A destra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Sblocca"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Fotocamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Silenzioso"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Audio attivato"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Ricerca"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Fai scorrere per sbloccare."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Collega gli auricolari per ascoltare la pronuncia dei tasti premuti per la password."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punto."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Riprova più tardi"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Scorri dall\'alto verso il basso per uscire dalla modalità schermo intero."</string>
+    <string name="done_label" msgid="2093726099505892398">"Fine"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Dispositivo di scorrimento circolare per le ore"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Dispositivo di scorrimento circolare per i minuti"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Seleziona le ore"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Seleziona i minuti"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Griglia di giorni per mese"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Elenco degli anni"</string>
+    <string name="select_day" msgid="7774759604701773332">"Seleziona mese e giorno"</string>
+    <string name="select_year" msgid="7952052866994196170">"Seleziona anno"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Elemento selezionato: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminato"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 1d42f65..7e821d2 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"‏מאפשר לאפליקציה להשתמש בתכונות ברמה הנמוכה של SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"אחסון זמני של מסגרת קריאה"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"מאפשר לאפליקציה לקרוא את התוכן של מאגר הנתונים הזמני של המסגרות."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"‏גישה אל InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"‏מאפשרת לאפליקציה להשתמש בתכונות ברמה נמוכה של InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"‏הגדר תצוגות Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"‏מאפשר לאפליקציה להגדיר ולהתחבר לתצוגות Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"‏שלוט בתצוגות Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"שתף עם"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"שתף עם <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"ידית להחלקה. גע והחזק."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"הסט למעלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"הסט למטה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"הסט שמאלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"הסט ימינה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"בטל נעילה"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"מצלמה"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"שקט"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"הקול פועל"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"חיפוש"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"החלק לביטול נעילה."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"חבר אוזניות כדי לשמוע הקראה של מפתחות סיסמה."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"נקודה."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"נסה שוב מאוחר יותר"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"החלק מטה מהחלק העליון כדי לצאת ממסך מלא."</string>
+    <string name="done_label" msgid="2093726099505892398">"בוצע"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"מחוון שעות מעגלי"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"מחוון דקות מעגלי"</string>
+    <string name="select_hours" msgid="6043079511766008245">"בחר שעות"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"בחר דקות"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"בחירת ימים בחודש בתצוגת רשת"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"רשימת שנים"</string>
+    <string name="select_day" msgid="7774759604701773332">"בחר חודש ויום"</string>
+    <string name="select_year" msgid="7952052866994196170">"בחר שנה"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> נבחר"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> נמחק"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 559d53f..92cb04c 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"SurfaceFlingerの低レベルの機能の使用をアプリに許可します。"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"フレームバッファの読み取り"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"フレームバッファの内容の読み取りをアプリに許可します。"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlingerへのアクセス"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"InputFlingerの低レベルの機能を使用することをアプリに許可します。"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wi-Fiディスプレイの設定"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Wi-Fiディスプレイを設定して接続することをアプリに許可します。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fiディスプレイの制御"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"共有"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>と共有"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"スライダーハンドルです。押し続けます。"</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"上にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"下にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"左にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"右にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"ロックを解除"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"カメラ"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"マナーモード"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"サウンドON"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"検索します"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"ロック解除するにはスワイプします。"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"パスワードのキーが音声出力されるのでヘッドセットを接続してください。"</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"ドット。"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"しばらくしてから再試行"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"全画面表示を終了するには、上から下にスワイプ"</string>
+    <string name="done_label" msgid="2093726099505892398">"完了"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"円形スライダー(時)"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"円形スライダー(分)"</string>
+    <string name="select_hours" msgid="6043079511766008245">"時間を選択"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"分を選択"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"日グリッド(月別)"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"年リスト"</string>
+    <string name="select_day" msgid="7774759604701773332">"月と日を選択"</string>
+    <string name="select_year" msgid="7952052866994196170">"年を選択"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g>を選択しました"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g>を削除しました"</string>
 </resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 7f4dc90..e175acf 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"აპს შეეძლება, გამოიყენოს SurfaceFlinger-ის დაბალი დონის ელემენტები."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"კადრის ბუფერის (ეკრანის შიგთავსის) წაკითხვა"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"აპს შეეძლება წაიკითხოს ბუფერული ჩარჩოს კონტენტი."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger-ზე წვდომა"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"აპს შეეძლება, გამოიყენოს InputFlinger-ის დაბალი დონის ფუნქციები."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi ეკრანის კონფიგურაცია"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"აპს შეეძლება Wifi ეკრანებთან დაკავშირება და დაკონფიგურირება."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi ეკრანების მართვა"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"გაზიარება"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"გაუზიარეთ <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ს"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"გასრიალებით მართვა. შეეხეთ &amp; არ აუშვათ."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"გაასრიალეთ ზემოთ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"გაასრიალეთ ქვემოთ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"გაასრიალეთ მარცხნივ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"გაასრიალეთ მარჯვნივ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"განბლოკვა"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"კამერა"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"უხმო"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"ხმის ჩართვა"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"ძიება"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"განბლოკვისათვის გადაფურცლეთ"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"შეაერთედ ყურსასმენები, პაროლის ღილაკები რომ გაიგოთ."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"წერტილი."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"სცადეთ მოგვიანებით"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"ჩამოასრიალეთ ზევიდან სრული ეკრანის დასახურად."</string>
+    <string name="done_label" msgid="2093726099505892398">"დასრულდა"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"საათების წრიული სლაიდერი"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"წუთების წრიული სლაიდერი"</string>
+    <string name="select_hours" msgid="6043079511766008245">"აირჩიეთ საათები"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"აირჩიეთ წუთები"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"დღეების ბადე თვეზე"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"წლის სია"</string>
+    <string name="select_day" msgid="7774759604701773332">"აირჩიეთ თვე და რიცხვი"</string>
+    <string name="select_year" msgid="7952052866994196170">"აირჩიეთ წელი"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"არჩეულია <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> წაიშალა"</string>
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index a7c16ed..94fb8d0 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1583,5 +1583,6 @@
     <item quantity="one" msgid="4835639969503729874">"არასწორი PIN. სცადეთ ისევ 1 წამში."</item>
     <item quantity="other" msgid="8030607343223287654">"არასწორი PIN. სცადეთ ისევ <xliff:g id="COUNT">%d</xliff:g> წამში."</item>
   </plurals>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"გაასრიალეთ ეკრანის კიდეზე ზოლის გამოსაჩენად"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"გაასრიალეთ ეკრანის კიდეზე ზოლის გამოსაჩენად"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"გაასრიალეთ ეკრანის კიდიდან სისტემის ზოლის გამოსაჩენად"</string>
 </resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 3bf648b..1576a1c 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"ឲ្យ​កម្មវិធី​ប្រើ​លក្ខណៈ​កម្រិត​ទាប​របស់ SurfaceFlinger ។"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"អាន​អង្គ​ចងចាំ​បណ្ដោះ​អាសន្ន"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"ឲ្យ​កម្មវិធី​អាន​មាតិកា​នៃ​អង្គ​ចងចាំ​បណ្ដោះ​អាសន្ន។"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"ចូល​ដំណើរការ InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"ឲ្យ​កម្មវិធី​ប្រើ​លក្ខណៈ​កម្រិត​ទាប InputFlinger ។"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"កំណត់​រចនាសម្ព័ន្ធ​ការ​បង្ហាញ​វ៉ាយហ្វាយ"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"ឲ្យ​កម្មវិធី​កំណត់​រចនាសម្ព័ន្ធ​ និង​ភ្ជាប់​ទៅ​ការ​បង្ហាញ​វ៉ាយហ្វាយ។"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ពិនិត្យ​ការ​បង្ហាញ​វ៉ាយហ្វាយ"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"ចែករំលែក​ជា​មួយ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ចែក​រំលែក​ជា​មួយ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"គ្រប់គ្រង​ការ​រុញ។ ប៉ះ &amp; សង្កត់។"</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"រុញ​ឡើង​លើ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"រុញ​ចុះក្រោម​សម្រាប់ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"រុញ​ទៅ​ឆ្វេង​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"រុញ​​ទៅ​ស្ដាំ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"ដោះ​​សោ"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"ម៉ាស៊ីន​ថត"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"ស្ងាត់"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"បើក​សំឡេង"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"អូស​ ដើម្បី​ដោះ​សោ។"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"ដោត​កាស​ដើម្បី​ស្ដាប់​ពាក្យ​សម្ងាត់​បាន​និយាយ។"</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"សូម​ព្យាយាម​ម្ដងទៀត​នៅ​ពេល​ក្រោយ។"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"អូស​​​​ពីលើ​ចុះក្រោម ដើម្បី​ចេញ​ពី​ការ​បង្ហាញ​ពេញ​អេក្រង់។"</string>
+    <string name="done_label" msgid="2093726099505892398">"រួចរាល់"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"គ្រាប់​រំកិល​រង្វង់​ម៉ោង"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"គ្រាប់​រំកិល​រង្វង់​នាទី"</string>
+    <string name="select_hours" msgid="6043079511766008245">"ជ្រើស​ម៉ោង"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"ជ្រើស​នាទី"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"ក្រឡា​​​ខែ​នៃ​ថ្ងៃ"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"បញ្ជី​ឆ្នាំ"</string>
+    <string name="select_day" msgid="7774759604701773332">"ជ្រើស​ខែ និង​ថ្ងៃ"</string>
+    <string name="select_year" msgid="7952052866994196170">"ជ្រើស​ឆ្នាំ"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"បាន​ជ្រើស <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"បាន​លុប <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 3d62d1a..e8c8bb4 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1583,5 +1583,6 @@
     <item quantity="one" msgid="4835639969503729874">"លេខ​កូដ​ PIN មិន​ត្រឹមត្រូវ។ ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល ១ វិនាទី។"</item>
     <item quantity="other" msgid="8030607343223287654">"លេខ​កូដ​ PIN មិន​ត្រឹមត្រូវ។ ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="COUNT">%d</xliff:g> វិនាទី​។"</item>
   </plurals>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"អូស​គែម​អេក្រង់ ដើម្បី​បង្ហាញ​របារ"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"អូស​គែម​អេក្រង់ ដើម្បី​បង្ហាញ​របារ"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"អូស​ពី​គែម​អេក្រង់ ដើម្បី​បង្ហាញ​របារ​ប្រព័ន្ធ"</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index d5eb619..fe04318 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"앱이 SurfaceFlinger의 하위 수준 기능을 사용할 수 있도록 허용합니다."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"프레임 버퍼 읽기"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"앱이 프레임 버퍼의 내용을 읽을 수 있도록 허용합니다."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger에 액세스"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"앱이 InputFlinger의 하위 수준 기능을 사용하도록 합니다."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wi-Fi 디스플레이 설정"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"앱이 Wi-Fi 디스플레이를 설정하고 연결하도록 허용합니다."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi 디스플레이 제어"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"공유 대상:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>와(과) 공유"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"슬라이딩 핸들을 길게 터치하세요."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 위로 슬라이드"</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 아래로 슬라이드"</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 왼쪽으로 슬라이드"</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 오른쪽으로 슬라이드"</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"잠금 해제"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"카메라"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"무음"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"사운드 켜기"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"검색"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"스와이프하여 잠급니다."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"비밀번호 키를 음성으로 들으려면 헤드셋을 연결하세요."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"점"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"나중에 다시 시도"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"전체화면을 종료하려면 위에서 아래로 스와이프하세요."</string>
+    <string name="done_label" msgid="2093726099505892398">"완료"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"시간 원형 슬라이더"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"분 원형 슬라이더"</string>
+    <string name="select_hours" msgid="6043079511766008245">"시간 선택"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"분 선택"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"월별 바둑판식 날짜 표시"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"년"</string>
+    <string name="select_day" msgid="7774759604701773332">"월/일 선택"</string>
+    <string name="select_year" msgid="7952052866994196170">"연도 선택"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g>이(가) 선택됨"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> 삭제됨"</string>
 </resources>
diff --git a/core/res/res/values-land/dimens.xml b/core/res/res/values-land/dimens.xml
index dc59f61..640ca1e 100644
--- a/core/res/res/values-land/dimens.xml
+++ b/core/res/res/values-land/dimens.xml
@@ -61,6 +61,10 @@
     Landscape's layout allows this to be smaller than for portrait. -->
     <dimen name="kg_squashed_layout_threshold">400dp</dimen>
 
+    <!-- New TimePicker dimensions. -->
+    <dimen name="timepicker_left_side_width">250dip</dimen>
+
     <!-- width of ImmersiveModeConfirmation (-1 for match_parent) -->
     <dimen name="immersive_mode_cling_width">380dp</dimen>
+
 </resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 8d88dfee9f..1769383 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"ອະນຸຍາດໃຫ້ແອັບຯນຳໃຊ້ຄວາມສາມາດລະດັບຕ່ຳ SurfaceFlinger"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"ອ່ານເຟຣມບັບເຟີ"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານເນື້ອຫາຂອງເຟຣມບັບເຟີ."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"ເຂົ້າເຖິງ InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"ອະນຸຍາດໃຫ້ແອັບຯນຳໃຊ້ຄວາມສາມາດ InputFlinger ລະດັບຕ່ຳ"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"ປັບຄ່າການສະແດງຜົນ WiFi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"ອະນຸຍາດໃຫ້ແອັບຯຕັ້ງຄ່າ ແລະເຊື່ອມຕໍ່ຈໍສະແດງຜົນ WiFi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ຄວບຄຸມການສະແດງ WiFi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"ແບ່ງປັນກັບ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ແບ່ງປັນໃຫ້ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"ເລື່ອນບ່ອນຖື ແລ້ວແຕະຄ້າງໄວ້."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"ເລື່ອນຂຶ້ນເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"ເລື່ອນລົງເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"ເລື່ອນໄປທາງຊ້າຍເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"ເລື່ອນໄປທາງຂວາເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"ປົດລັອກ"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"ກ້ອງ"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"ປິດສຽງ"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"ເປີດສຽງ"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"ຊອກຫາ"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"ປັດເພື່ອປົດລັອກ."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"ສຽບສາຍຫູຟັງເພື່ອຟັງລະຫັດຜ່ານ."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"ຈໍ້າເມັດ."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"ລອງໃໝ່ອີກຄັ້ງໃນພາຍຫລັງ."</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"ປັດລົງມາຈາກທາງເທິງເພື່ອອອກຈາກໂໝດເຕັມໜ້າຈໍ."</string>
+    <string name="done_label" msgid="2093726099505892398">"ແລ້ວໆ"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"ໂຕໝຸນປັບຊົ່ວໂມງ"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"ໂຕໝຸນປັບນາທີ"</string>
+    <string name="select_hours" msgid="6043079511766008245">"ເລືອກ​ຊົ່ວ​ໂມງ"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"ເລືອກນາ​ທີ"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"ຕາຕາລາງວັນທີເດືອນປີ"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"ລາຍການປີ"</string>
+    <string name="select_day" msgid="7774759604701773332">"ເລືອກເດືອນ ແລະ ວັນ"</string>
+    <string name="select_year" msgid="7952052866994196170">"ເລືອກ​ປີ"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ຖືກເລືອກແລ້ວ"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ຖືກລຶບແລ້ວ"</string>
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 68ece0f..9d07ae6 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1583,5 +1583,6 @@
     <item quantity="one" msgid="4835639969503729874">"PIN ​ບໍ່​ຖືກ​ຕ້ອງ​. ລອງໃໝ່ໃນອີກ 1 ວິນາທີ."</item>
     <item quantity="other" msgid="8030607343223287654">"PIN ບໍ່​ຖືກ​ຕ້ອງ​. ລອງໃໝ່ໃນອີກ <xliff:g id="COUNT">%d</xliff:g> ວິ​ນາ​ທີ​."</item>
   </plurals>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"ປັດຢູ່ຂອບຂອງໜ້າຈໍເພື່ອສະແດງແຖບ"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"ປັດຢູ່ຂອບຂອງໜ້າຈໍເພື່ອສະແດງແຖບ"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"ປັດຢູ່ຂອບຂອງໜ້າຈໍເພື່ອສະແດງແຖບຂອງລະບົບ"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 614bcd6..b759cf1 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Leidžiama programai naudoti „SurfaceFlinger“ žemo lygio funkcijas."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"skaityti kadrų buferį"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Leidžiama programai skaityti rėmelio buferio turinį."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"pasiekti „InputFlinger“"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Programai leidžiama naudoti „InputFlinger“ žemo lygio funkcijas."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigūruoti „Wi-Fi“ pateiktis"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Leidžiama programai konfigūruoti ir prisijungti prie „Wi-Fi“ pateikčių."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"valdyti „Wi-Fi“ pateiktis"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Bendrinti su"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Bendrinti su „<xliff:g id="APPLICATION_NAME">%s</xliff:g>“"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Slydimo valdymas. Palieskite ir laikykite."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Slyskite aukštyn link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Slyskite žemyn link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Slyskite į kairę link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Slyskite į dešinę link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Atrakinti"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Vaizdo kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Begarsis"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Garsas įjungtas"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Paieška"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Perbraukite pirštu, kad atrakintumėte."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Prijunkite ausines, kad išgirstumėte sakomus slaptažodžio klavišus."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Taškas."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Vėliau bandykite dar kartą"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Perbraukite nuo viršaus žemyn, kad išeitumėte iš viso ekrano režimo"</string>
+    <string name="done_label" msgid="2093726099505892398">"Atlikta"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Apskritas valandų slankiklis"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Apskritas minučių slankiklis"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Pasirinkite valandas"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Pasirinkite minutes"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Mėnesio dienų tinklelis"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Metų sąrašas"</string>
+    <string name="select_day" msgid="7774759604701773332">"Pasirinkite mėnesį ir dieną"</string>
+    <string name="select_year" msgid="7952052866994196170">"Pasirinkite metus"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Pasirinkta: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Ištrinta: <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 9f3cb53..48b01b6 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Ļauj lietotnei lietot SurfaceFlinger zema līmeņa funkcijas."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lasīt kadru buferi"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Ļauj lietotnei lasīt kadru bufera saturu."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"Piekļuve InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Ļauj lietotnei izmantot InputFlinger zema līmeņa funkcijas."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wi-Fi displeju konfigurēšana"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Ļauj lietotnei konfigurēt Wi-Fi displejus un veidot savienojumu ar tiem."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi displeju vadība"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Kopīgot ar:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Kopīgot ar lietojumprogrammu <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Bīdāms turis. Pieskarieties tam un turiet to nospiestu."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Velciet uz augšu, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Velciet uz leju, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Velciet pa kreisi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Velciet pa labi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Atbloķēt"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Klusums"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Skaņa ieslēgta"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Meklēt"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Velciet ar pirkstu, lai atbloķētu."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Pievienojiet austiņas, lai dzirdētu paroles taustiņu nosaukumus."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkts."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Vēlāk mēģiniet vēlreiz."</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Lai izietu no pilnekrāna režīma, velciet no augšas uz leju."</string>
+    <string name="done_label" msgid="2093726099505892398">"Gatavs"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Stundu apļveida slīdnis"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Minūšu apļveida slīdnis"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Atlasiet stundas."</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Atlasiet minūtes."</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Režģis ar mēneša dienām"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Gadu saraksts"</string>
+    <string name="select_day" msgid="7774759604701773332">"Atlasiet mēnesi un dienu."</string>
+    <string name="select_year" msgid="7952052866994196170">"Atlasiet gadu."</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Atlasīts: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> tika dzēsts."</string>
 </resources>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 252a959..568ca48 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Апп нь SurfaceFlinger доод-төвшиний функцийг ашиглах боломжтой."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"Фрэйм буферээс унших"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Апп нь фрэйм буферын контентыг унших боломжтой."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger-т хандалт хийх"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Апп-д SurfaceFlinger доод-түвшний функцуудыг ашиглах боломж олгоно."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi дэлгэцийг тохируулах"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Апп нь Wifi дэлгэцийг тохируулах болон холбогдох боломжтой."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi дэлгэцийг удирдах"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Хуваалцах"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>-тай хуваалцана уу"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Бариулыг гулсуулна. Хүрээд хүлээнэ."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-г гулсуулах."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх бол доош гулсуулах."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх зүүнлүү гулсуулах."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх бол баруунлуу гулсуулах."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Тайлах"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Камер"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Чимээгүй"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Дуунууд идэвхтэй"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Хайх"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Түгжээг тайлах бол татна уу"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Нууц үгний дуудлагыг сонсох бол чихэвчийг залгана уу."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Цэг."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Дараа дахин оролдоно уу"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Бүтэн дэлгэцээс гарахын тулд дээрээс нь доош шудрана уу."</string>
+    <string name="done_label" msgid="2093726099505892398">"Дууссан"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Цаг гүйлгэгч"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Минут гүйлгэгч"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Цаг сонгоно уу"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Минут сонгоно уу"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Өдрүүдийг сараар"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Жилийн жагсаалт"</string>
+    <string name="select_day" msgid="7774759604701773332">"Сар болон өдрийг сонгоно уу"</string>
+    <string name="select_year" msgid="7952052866994196170">"Жилийг сонгоно уу"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> сонгогдсон"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> устсан"</string>
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index e187320..e0c9478 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -470,6 +470,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Апп нь SurfaceFlinger доод-төвшиний функцийг ашиглах боломжтой."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"Фрэйм буферээс унших"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Апп нь фрэйм буферын контентыг унших боломжтой."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger-т хандалт хийх"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Апп-д SurfaceFlinger доод-түвшний функцуудыг ашиглах боломж олгоно."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi дэлгэцийг тохируулах"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Апп нь Wifi дэлгэцийг тохируулах болон холбогдох боломжтой."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi дэлгэцийг удирдах"</string>
@@ -1579,5 +1581,6 @@
     <item quantity="one" msgid="4835639969503729874">"Буруу PIN. 1 секундын дараа дахин оролдоно уу."</item>
     <item quantity="other" msgid="8030607343223287654">"Буруу PIN. <xliff:g id="COUNT">%d</xliff:g> секундын дараа дахин оролдоно уу."</item>
   </plurals>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"Баганыг харуулахын тулд дэлгэцийн ирмэгийг шудрана уу"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Баганыг харуулахын тулд дэлгэцийн ирмэгийг шудрана уу"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Системийн баганыг гаргахын тулд дэлгэцийн ирмэгээс шудрана уу"</string>
 </resources>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 284837a..c43de4e 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Membenarkan apl menggunakan ciri peringkat rendah SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"baca penimbal bingkai"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Membenarkan apl membaca kandungan penimbal bingkai."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"akses InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Membenarkan apl menggunakan ciri peringkat rendah InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurasikan paparan Wifi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Membenarkan apl mengkonfigurasi dan menyambung ke paparan Wifi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kawal paparan Wifi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Kongsi dengan"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Kongsi dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Pemegang gelongsor. Sentuh &amp; tahan."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Luncurkan ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Luncurkan ke bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Luncurkan ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Luncurkan ke kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Buka kunci"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Bunyi dihidupkan"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Carian"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Leret untuk membuka kunci."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Pasangkan set kepala untuk mendengar kekunci kata laluan disebutkan."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Titik."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Cuba sebentar lagi"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Leret ke bawah dari atas untuk keluar dari skrin penuh."</string>
+    <string name="done_label" msgid="2093726099505892398">"Selesai"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Penggelangsar bulatan jam"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Penggelangsar bulatan minit"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Pilih jam"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Pilih minit"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Grid hari bulanan"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Senarai tahun"</string>
+    <string name="select_day" msgid="7774759604701773332">"Pilih bulan dan hari"</string>
+    <string name="select_year" msgid="7952052866994196170">"Pilih tahun"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> dipilih"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> dipadamkan"</string>
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index f522a48..e6dc0ca 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1583,5 +1583,6 @@
     <item quantity="one" msgid="4835639969503729874">"PIN salah. Cuba lagi dalam masa 1 saat."</item>
     <item quantity="other" msgid="8030607343223287654">"PIN salah. Cuba lagi dalam masa <xliff:g id="COUNT">%d</xliff:g> saat."</item>
   </plurals>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"Leret bhg tepi skrin utk serlah bar"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Leret bhg tepi skrin utk serlah bar"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Leret dari tepi skrin untuk menampakkan bar sistem"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index d29972c..7310c38 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Lar appen bruke grunnleggende SurfaceFlinger-funksjoner."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lese skjermbufferen"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Lar appen lese innholdet i rammebufferen."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"tilgang til InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Lar appen bruke grunnleggende InputFlinger-funksjoner."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurere Wi-Fi-skjermer"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tillater appen å konfigurere og koble til Wi-Fi-skjermer."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kontrollere Wi-Fi-skjermer"</string>
@@ -1225,7 +1227,7 @@
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Aldri tillat"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"SIM-kort er fjernet"</string>
     <string name="sim_removed_message" msgid="2333164559970958645">"Det mobile nettverket forblir utilgjengelig inntil du starter på nytt med et gyldig SIM-kort."</string>
-    <string name="sim_done_button" msgid="827949989369963775">"Fullført"</string>
+    <string name="sim_done_button" msgid="827949989369963775">"Ferdig"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"SIM-kort er lagt til"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Start enheten på nytt for å få tilgang til det mobile nettverket."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Start på nytt"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Del med"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Del med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Glidebryter. Trykk og hold inne."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Dra opp for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Dra ned for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Dra til venstre for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Dra til høyre for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Lås opp"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Stille"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Lyd på"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Søk"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Sveip for å låse opp."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Koble til hodetelefoner for å høre opplesing av bokstavene i passordet."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punktum."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Prøv på nytt senere"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Sveip ned fra toppen av skjermen for å gå ut av fullskjermvisningen."</string>
+    <string name="done_label" msgid="2093726099505892398">"Ferdig"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Sirkulær glidebryter for timer"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Sirkulær glidebryter for minutter"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Angi timer"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Angi minutter"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Månedsrutenett med dager"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Årsliste"</string>
+    <string name="select_day" msgid="7774759604701773332">"Velg måneden og dagen"</string>
+    <string name="select_year" msgid="7952052866994196170">"Velg året"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> er valgt"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> er slettet"</string>
 </resources>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index fe6b669..8626897b 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -314,7 +314,7 @@
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"अनुप्रयोग स्विचहरू जोगाउनुहोस्"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"अन्य अनुप्रयोगमा स्विच गर्नबाट प्रयोगकर्ताहरूलाई रोक्छ।"</string>
     <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"वर्तमान अनुप्रयोगको जानकारी प्राप्त गर्नुहोस्"</string>
-    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"होल्डरलाई स्क्रिनको पृष्ठभूमिमा वर्तमान अनुप्रयोगको बारेमा व्यक्तिगत जानकारी पुनःप्राप्त गर्न अनुमति दिन्छ।"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"स्क्रिनको अग्र भागमा हालको अनुप्रयोग र सेवाहरूका बारे निजी जानकारी निकाल्न बाहकलाई अनुमति दिन्छ।"</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"सबै अनुप्रयोग सुरुवात गर्ने निरीक्षण र नियन्त्रण गर्नुहोस्"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"अनुप्रयोगलाई कसरी प्रणाली सुरुवात गतिहरू मोनिटर गर्न र नियन्त्रण गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले प्रणालीमा पूर्ण सहमत गर्न सक्दछ। यो अनुमति केवल विकासको लागि आवश्यक छ, साधारण प्रयोगको लागि कहिले होइन।"</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"प्याकेज हटाइएको प्रसारणलाई पठाउनुहोस्"</string>
@@ -470,6 +470,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"SurfaceFlinger कम-स्तर सुविधाहरू प्रयोग गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"फ्रेम बफर पढ्नुहोस्"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"अनुप्रयोगलाई फ्रेम बफरको सामग्री पढ्न अनुमति दिन्छ।"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger को पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"InputFlinger को कम-स्तर सुविधाहरू प्रयोग गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"वाइफाइ प्रदर्शनहरूलाई विन्यास गर्नुहोस"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"अनुप्रयोगलाई कन्फिगर गर्न र वाइफाइ प्रदर्शनहरूसँग जोड्न अनुमति दिन्छ।"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"वाइफाइ प्रदर्शनहरू नियन्त्रण गर्नुहोस्"</string>
@@ -1584,5 +1586,6 @@
     <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> सेकेन्डमा पुनः प्रयास गर्नुहोस्"</item>
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"पछि पुनः प्रयास गर्नुहोस्"</string>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"पट्टि देखिने बनाउन स्क्रिनको छेउमा स्वाइप गर्नुहोस्"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"पट्टि देखिने बनाउन स्क्रिनको छेउमा स्वाइप गर्नुहोस्"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"प्रणाली पट्टि देखिने बनाउन स्क्रिनको छेउबाट स्वाइप गर्नुहोस्"</string>
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 7ff8dae..b6e4fc3 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1583,5 +1583,6 @@
     <item quantity="one" msgid="4835639969503729874">"गलत PIN । १ सेकेन्डमा पुनः प्रयास गर्नुहोस्।"</item>
     <item quantity="other" msgid="8030607343223287654">"गलत PIN । <xliff:g id="COUNT">%d</xliff:g> सेकेन्डमा पुनः प्रयास गर्नुहोस्।"</item>
   </plurals>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"पट्टि देखिने बनाउन स्क्रिनको छेउमा स्वाइप गर्नुहोस्"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"पट्टि देखिने बनाउन स्क्रिनको छेउमा स्वाइप गर्नुहोस्"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"प्रणाली पट्टि देखिने बनाउन स्क्रिनको छेउबाट स्वाइप गर्नुहोस्"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index ba221cc..307dcbe 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Hiermee kan de app SurfaceFlinger-functies op laag niveau gebruiken."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"framebuffer lezen"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Hiermee kan de app de inhoud van de framebuffer lezen."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"toegang krijgen tot InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Hiermee kan de app InputFlinger-functies op laag niveau gebruiken."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"wifi-displays configureren"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"De app toestaan wifi-displays te configureren en hiermee verbinding te maken."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"wifi-displays beheren"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Delen met"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Delen met <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Schuifgreep. Tikken en blijven aanraken."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Veeg omhoog voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Veeg omlaag voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Veeg naar links voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Veeg naar rechts voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Ontgrendelen"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Stil"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Geluid aan"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Zoeken"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Vegen om te ontgrendelen"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Sluit een headset aan om wachtwoordtoetsen te laten voorlezen."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Stip."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Probeer het later opnieuw"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Veeg omlaag vanaf de bovenkant om het volledige scherm te sluiten."</string>
+    <string name="done_label" msgid="2093726099505892398">"Gereed"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Ronde schuifregelaar voor uren"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Ronde schuifregelaar voor minuten"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Uren selecteren"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Minuten selecteren"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Maandraster van dagen"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Jaarlijst"</string>
+    <string name="select_day" msgid="7774759604701773332">"Maand en dag selecteren"</string>
+    <string name="select_year" msgid="7952052866994196170">"Jaar selecteren"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> geselecteerd"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> verwijderd"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 217d2c9..9a83ef3 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -263,8 +263,8 @@
     <string name="permdesc_receiveMms" msgid="533019437263212260">"Pozwala aplikacji na odbieranie i przetwarzanie MMS-ów. To oznacza, że aplikacja będzie mogła bez Twojej wiedzy monitorować i usuwać wiadomości wysyłane do Twojego urządzenia."</string>
     <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"odbiór emisji alarmowych"</string>
     <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Pozwala aplikacji na odbieranie i przetwarzanie komunikatów transmisji alarmowych. To pozwolenie jest dostępne tylko dla aplikacji systemowych."</string>
-    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"odczyt wiadomości z sieci komórkowej"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Zezwala aplikacji na odczyt wiadomości z sieci komórkowej odebranych na urządzeniu. Alerty sieci komórkowej są dostarczane w niektórych lokalizacjach w celu ostrzeżenia Cię o sytuacjach alarmowych. Złośliwe aplikacje mogą wpływać na wydajność lub zakłócać działanie urządzenia po odebraniu wiadomości alarmowej z sieci komórkowej."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"odczyt komunikatów z sieci komórkowej"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Zezwala aplikacji na odczyt komunikatów z sieci komórkowej odebranych na urządzeniu. Komunikaty alarmowe z sieci komórkowej są dostarczane w niektórych lokalizacjach w celu ostrzeżenia Cię o sytuacjach zagrożenia. Złośliwe aplikacje mogą wpływać na wydajność lub zakłócać działanie urządzenia po odebraniu komunikatu alarmowego z sieci komórkowej."</string>
     <string name="permlab_sendSms" msgid="5600830612147671529">"wysyłanie wiadomości SMS"</string>
     <string name="permdesc_sendSms" msgid="7094729298204937667">"Pozwala aplikacji na wysyłanie SMS-ów. Może to skutkować nieoczekiwanymi opłatami. Złośliwe aplikacje mogą generować koszty, wysyłając wiadomości bez Twojego potwierdzenia."</string>
     <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"wysyłanie zdarzeń odpowiedzi przez SMS"</string>
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Pozwala aplikacji na wykorzystanie funkcji niskiego poziomu usługi SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"czytanie bufora ramki"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Pozwala aplikacji na odczyt zawartości bufora ramki."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"dostęp do InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Zezwala aplikacji na wykorzystanie niskopoziomowych funkcji usługi InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurowanie wyświetlaczy Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Zezwala aplikacji na konfigurację wyświetlaczy Wi-Fi i łączenie z nimi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"zarządzanie wyświetlaczami Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Udostępnij przez"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Udostępnij przez <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Uchwyt przesuwny. Dotknij i przytrzymaj."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Przesuń w górę: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Przesuń w dół: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Przesuń w lewo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Przesuń w prawo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Odblokuj"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Aparat"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Wyciszenie"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Włącz dźwięk"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Szukaj"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Przesuń, aby odblokować."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Podłącz zestaw słuchawkowy, aby wysłuchać znaków hasła wypowiadanych na głos."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Kropka"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Spróbuj ponownie później"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Przesuń z góry w dół, by zamknąć pełny ekran."</string>
+    <string name="done_label" msgid="2093726099505892398">"Gotowe"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kołowy suwak godzin"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kołowy suwak minut"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Wybierz godziny"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Wybierz minuty"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Siatka miesięczna z dniami"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Lista lat"</string>
+    <string name="select_day" msgid="7774759604701773332">"Wybierz miesiąc i dzień"</string>
+    <string name="select_year" msgid="7952052866994196170">"Wybierz rok"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Wybrałeś <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> usunięte"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 2d69f9c..afc51d0 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permite à aplicação utilizar funcionalidades de SurfaceFlinger de nível inferior."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"ler memória intermédia de fotogramas"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permite à aplicação ler o conteúdo da memória intermédia de fotogramas."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"aceder a InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite que a aplicação utilize funcionalidades de InputFlinger de nível inferior."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurar visores Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que a aplicação se configure e se ligue a visores Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar visores Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Partilhar com:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartilhar com <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Barra deslizante. Toque &amp; não solte."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Deslize para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Deslize para baixo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Deslize para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Deslize para a direita para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Câmara"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Som ativado"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Deslizar rapidamente para desbloquear."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Ligue os auscultadores com microfone integrado para ouvir as teclas da palavra-passe."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Ponto."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Tente novamente mais tarde"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Deslize rapidamente para baixo para sair do ecrã inteiro."</string>
+    <string name="done_label" msgid="2093726099505892398">"Concluído"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Controlo de deslize circular das horas"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Controlo de deslize circular dos minutos"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Selecionar horas"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Selecionar minutos"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Grelha de dias do mês"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Lista de anos"</string>
+    <string name="select_day" msgid="7774759604701773332">"Selecionar mês e dia"</string>
+    <string name="select_year" msgid="7952052866994196170">"Selecionar ano"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selecionado"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index f1ad4d7..fb83b88 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permite que o aplicativo use recursos com baixos níveis de SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"ler o buffer do frame"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permite que o aplicativo leia o conteúdo do buffer de frame."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"acessar InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite que o aplicativo use recursos com baixos níveis de InputFinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurar monitores Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que o aplicativo configure e conecte a monitores Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar monitores Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartilhar com"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartilhar com <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Recurso deslizante. Toque e segure."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para cima."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para baixo."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a esquerda."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a direita."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Câmera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Som ativado"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Deslize para desbloquear."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conecte um fone de ouvido para ouvir as teclas da senha."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Ponto final."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Tente novamente mais tarde"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Deslize de cima para baixo para sair da tela inteira"</string>
+    <string name="done_label" msgid="2093726099505892398">"Concluído"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Controle deslizante circular das horas"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Controle deslizante circular dos minutos"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Selecione as horas"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Selecione os minutos"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Grade mensal de dias"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Lista de anos"</string>
+    <string name="select_day" msgid="7774759604701773332">"Selecione o mês e o dia"</string>
+    <string name="select_year" msgid="7952052866994196170">"Selecione o ano"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selecionado"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> excluído"</string>
 </resources>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 6ea1e9e..3dfa786 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -791,6 +791,10 @@
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"leger il paraculp da frame"</string>
     <!-- no translation found for permdesc_readFrameBuffer (4937405521809454680) -->
     <skip />
+    <!-- no translation found for permlab_accessInputFlinger (5348635270689553857) -->
+    <skip />
+    <!-- no translation found for permdesc_accessInputFlinger (2104864941201226616) -->
+    <skip />
     <!-- no translation found for permlab_configureWifiDisplay (5595661694746742168) -->
     <skip />
     <!-- no translation found for permdesc_configureWifiDisplay (7916815158690218065) -->
@@ -2283,24 +2287,6 @@
     <skip />
     <!-- no translation found for content_description_sliding_handle (415975056159262248) -->
     <skip />
-    <!-- no translation found for description_direction_up (7169032478259485180) -->
-    <skip />
-    <!-- no translation found for description_direction_down (5087739728639014595) -->
-    <skip />
-    <!-- no translation found for description_direction_left (7207478719805562165) -->
-    <skip />
-    <!-- no translation found for description_direction_right (8034433242579600980) -->
-    <skip />
-    <!-- no translation found for description_target_unlock (2228524900439801453) -->
-    <skip />
-    <!-- no translation found for description_target_camera (969071997552486814) -->
-    <skip />
-    <!-- no translation found for description_target_silent (893551287746522182) -->
-    <skip />
-    <!-- no translation found for description_target_soundon (30052466675500172) -->
-    <skip />
-    <!-- no translation found for description_target_search (3091587249776033139) -->
-    <skip />
     <!-- no translation found for description_target_unlock_tablet (3833195335629795055) -->
     <skip />
     <!-- no translation found for keyboard_headset_required_to_hear_password (7011927352267668657) -->
@@ -2757,4 +2743,26 @@
     <!-- no translation found for immersive_mode_confirmation (7227416894979047467) -->
     <!-- no translation found for immersive_mode_confirmation (8554991488096662508) -->
     <skip />
+    <!-- no translation found for done_label (2093726099505892398) -->
+    <skip />
+    <!-- no translation found for hour_picker_description (6698199186859736512) -->
+    <skip />
+    <!-- no translation found for minute_picker_description (8606010966873791190) -->
+    <skip />
+    <!-- no translation found for select_hours (6043079511766008245) -->
+    <skip />
+    <!-- no translation found for select_minutes (3974345615920336087) -->
+    <skip />
+    <!-- no translation found for day_picker_description (8990847925961297968) -->
+    <skip />
+    <!-- no translation found for year_picker_description (5524331207436052403) -->
+    <skip />
+    <!-- no translation found for select_day (7774759604701773332) -->
+    <skip />
+    <!-- no translation found for select_year (7952052866994196170) -->
+    <skip />
+    <!-- no translation found for item_is_selected (949687401682476608) -->
+    <skip />
+    <!-- no translation found for deleted_key (7659477886625566590) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index c3f9157..f415e7c 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permite aplicaţiei să utilizeze funcţiile de nivel redus SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"citire zonă tampon de cadre"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permite aplicaţiei să citească conţinutul zonei-tampon a cadrului."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"acces la InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite aplicației să utilizeze funcțiile de nivel redus InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurează afişaje Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite aplicaţiei să configureze şi să se conecteze la afişaje Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlează afişaje Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Permiteţi accesul pentru"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Permiteţi accesul pentru <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Mâner glisant. Atingeţi şi ţineţi apăsat."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Glisaţi în sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Glisaţi în jos pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Glisaţi spre stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Glisaţi spre dreapta pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Deblocaţi"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Cameră foto"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Silenţios"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Sunet activat"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Căutaţi"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Glisaţi pentru a debloca."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conectaţi un set căşti-microfon pentru a auzi tastele apăsate când introduceţi parola."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punct."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Reîncercați mai târziu"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Glisați în jos pentru a ieși din ecran complet."</string>
+    <string name="done_label" msgid="2093726099505892398">"Terminat"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Selector circular pentru ore"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Selector circular pentru minute"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Selectați orele"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Selectați minutele"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Afișare pe luni"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Listă de ani"</string>
+    <string name="select_day" msgid="7774759604701773332">"Selectați luna și ziua"</string>
+    <string name="select_year" msgid="7952052866994196170">"Selectați anul"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selectat"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> a fost șters"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 13f18c3..58d3ab7 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Приложение сможет использовать низкоуровневые функции SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"Чтение данных в буфере кадров"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Приложение сможет считывать содержание буфера фреймов."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"Доступ к InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Приложение сможет использовать низкоуровневые функции InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"настраивать экраны, подключенные через Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Приложение сможет подключаться к экранам с помощью Wi-Fi и настраивать их."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Управление мониторами, подключенными через Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Открыть доступ:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Открыть доступ приложению \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\""</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Перетаскиваемый значок блокировки. Нажмите и удерживайте."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Проведите вверх, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Проведите вниз, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Проведите влево, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Проведите вправо, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Разблокировать"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Без звука"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Включить звук"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Поиск"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Проведите по экрану, чтобы разблокировать устройство."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Подключите гарнитуру, чтобы услышать пароль."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Точка"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Повторите попытку позже."</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Чтобы вернуться в обычный режим, проведите пальцем вниз."</string>
+    <string name="done_label" msgid="2093726099505892398">"Готово"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Выбор часов на циферблате"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Выбор минут на циферблате"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Выберите часы"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Выберите минуты"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Окно выбора даты"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Меню выбора года"</string>
+    <string name="select_day" msgid="7774759604701773332">"Выберите месяц и число"</string>
+    <string name="select_year" msgid="7952052866994196170">"Выберите год"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Выбран элемент <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Цифра <xliff:g id="KEY">%1$s</xliff:g> удалена"</string>
 </resources>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 367de51..0bbcd06 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -314,7 +314,7 @@
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"යෙදුම් මාරු වීම වැළක්වීම"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"වෙනත් යෙදුමක් වෙත පරිශීලකයාව මාරු වීම වළක්වයි."</string>
     <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"පවතින යෙදුමේ තොරතුරු ලබාගැනීම"</string>
-    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"තිරයේ පෙරබිම තුළ තිබෙන දැන් පවත්නා යෙදුමේ පෞද්ගලික තොරතුරු ලබාගැනීමට දරන්නාට අවසර දෙන්න."</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"තිරයේ පෙරබිම තුළ තිබෙන දැන් පවත්නා යෙදුමේ සහ සේවාවල පෞද්ගලික තොරතුරු ලබාගැනීමට දරන්නාට අවසර දෙන්න."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"සියලු යෙදුම් දියත් කිරීම් නිරීක්ෂණය සහ පාලනය කිරීම"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"පද්ධතිය ක්‍රියාකාරකම් දියත් කරන්නේ කෙසේදැයි නිරීක්ෂණයට සහ පාලනයට යෙදුමට අවසර දෙන්න. අනිෂ්ට යෙදුම් මගින් පද්ධතිය සම්පූර්ණයෙන්ම සම්මුතියකට එළඹිය හැක. වර්ධනය සඳහා පමණක් මෙම අවසරය අවශ්‍ය වෙයි, සාමාන්‍ය භාවිතය සඳහා කිසි විටෙකත් අවශ්‍ය නොවෙයි."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"පැකේජ ඉවත් කිරීමේ ප්‍රචාරණයක් යවන්න"</string>
@@ -470,6 +470,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"SurfaceFlinger පහල මට්ටමේ විශේෂාංග භාවිතයට යෙදුමට අවසර දෙයි."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"රාමු අන්තරාචය කියවීම"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"රාමු අන්තරාචයනයෙන් අන්තර්ගතයන් කියවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger වෙත පිවිසෙන්න"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"InputFlinger පහල මට්ටමේ විශේෂාංග භාවිතයට යෙදුමට අවසර දෙයි."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi සංදර්ශක වින්‍යාස කරන්න"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"වින්‍යාස කිරීමට සහ Wifi සංදර්ශක වෙත සම්බන්ධ වීමට යෙදුමට අවසර දෙන්න."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi සංදර්ශක පාලනය"</string>
@@ -1587,5 +1589,6 @@
     <item quantity="other" msgid="4730868920742952817">"තත්පර <xliff:g id="COUNT">%d</xliff:g> කින් නැවත උත්සහ කරන්න"</item>
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"පසුව නැවත උත්සාහ කරන්න"</string>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"තීරුව අනාවරණයට තිරයේ කෙලවර අදින්න"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"තීරුව අනාවරණයට තිරයේ කෙලවර අදින්න"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"පද්ධති තීරුව අනාවරණයට තිරයේ කෙලවරින් අදින්න"</string>
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 7e12eab..165163b 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1586,5 +1586,6 @@
     <item quantity="one" msgid="4835639969503729874">"වැරදි PIN. තත්පරයකින් නැවත උත්සහ කරන්න."</item>
     <item quantity="other" msgid="8030607343223287654">"වැරදි PIN. තත්පර <xliff:g id="COUNT">%d</xliff:g> කින් නැවත උත්සහ කරන්න."</item>
   </plurals>
-    <string name="immersive_mode_confirmation" msgid="8554991488096662508">"තීරුව අනාවරණයට තිරයේ කෙලවර අදින්න"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"තීරුව අනාවරණයට තිරයේ කෙලවර අදින්න"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"පද්ධති තීරුව අනාවරණයට තිරයේ කෙලවරින් අදින්න"</string>
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 3467b4d..87860f3 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Umožňuje aplikácii používať funkcie nízkej úrovne aplikácie SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"čítanie vyrovnávacej pamäte snímok"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Umožňuje aplikácii čítať obsah vyrovnávacej pamäte snímok."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"prístup k aplikácii InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Umožňuje aplikácii používať funkcie nízkej úrovne aplikácie InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurovať displeje cez sieť Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Umožňuje aplikácii konfigurovať displeje a pripojiť sa k nim cez siete Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ovládať displeje cez sieť Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Zdieľať s"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Zdieľať s aplikáciou <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvné tlačidlo. Dotknite sa a podržte."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Prejdite prstom nahor: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Prejdite prstom nadol: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Prejdite prstom doľava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Prejdite prstom doprava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Odomknúť"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Fotoaparát"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Tichý"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Zapnúť zvuk"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Vyhľadávanie"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Posunom odomknúť."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Ak si chcete vypočuť vyslovené klávesy hesla, pripojte náhlavnú súpravu."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Bodka."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Skúste to znova neskôr"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Režim celej obrazovky ukončíte posunutím nadol."</string>
+    <string name="done_label" msgid="2093726099505892398">"Hotovo"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kruhový posúvač hodín"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kruhový posúvač minút"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Vyberte hodiny"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Vyberte minúty"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Tabuľka dní v mesiaci"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Zoznam rokov"</string>
+    <string name="select_day" msgid="7774759604701773332">"Vyberte mesiac a deň"</string>
+    <string name="select_year" msgid="7952052866994196170">"Vyberte rok"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Bola vybratá položka <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Číslo <xliff:g id="KEY">%1$s</xliff:g> bolo odstránené"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 0d76bbf..fa49827 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Programu omogoča uporabo funkcij nizke ravni SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"branje grafičnega/slikovnega medpomnilnika"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Programu omogoča branje vsebine grafičnega/slikovnega medpomnilnika."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"dostop do funkcij InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Aplikaciji dovoljuje uporabo funkcij InputFlinger nizke ravni."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfiguriranje zaslonov Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Omogoča aplikaciji konfiguriranje zaslonov Wi-Fi in povezovanje z njimi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"nadzor zaslonov Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Delite z"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Delite s programom <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Drsna ročica. Dotaknite se in pridržite."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Povlecite navzgor za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Povlecite navzdol za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Povlecite v levo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Povlecite v desno za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Odkleni"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Tiho"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Vklopljen zvok"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Iskanje"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Povlecite, če želite odkleniti."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Priključite slušalke, če želite slišati izgovorjene tipke gesla."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Pika."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Poskusite znova pozneje"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Povlecite z vrha, da zaprete celozaslonski način."</string>
+    <string name="done_label" msgid="2093726099505892398">"Dokončano"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Okrogli drsnik za ure"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Okrogli drsnik za minute"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Izberite ure"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Izberite minute"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Mesečna mreža dni"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Seznam let"</string>
+    <string name="select_day" msgid="7774759604701773332">"Izberite mesec in dan"</string>
+    <string name="select_year" msgid="7952052866994196170">"Izberite leto"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Izbrano: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Številka <xliff:g id="KEY">%1$s</xliff:g> je izbrisana"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 6fb9ea2..e953180 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Дозвољава апликацији да користи SurfaceFlinger функције ниског нивоа."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"читање бафера кадрова"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Дозвољава апликацији да чита садржај међумеморије кадрова."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"приступ InputFlinger функцијама"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Дозвољава апликацији да користи InputFlinger функције ниског нивоа."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"конфигурисање Wi-Fi екрана"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дозвољава апликацији да конфигурише Wi-Fi екране и повезује се са њима."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"контрола Wi-Fi екрана"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Дели са"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Дели са апликацијом <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Клизна ручица. Додирните и задржите."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Превуците нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Превуците надоле за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Превуците улево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Превуците удесно за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Откључај"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Нечујно"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Укључи звук"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Претрага"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Превуците да бисте откључали."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Прикључите слушалице да бисте чули изговорене тастере за лозинку."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Тачка."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Покушајте поново касније"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Превуците прстом одозго надоле да бисте изашли из целог екрана."</string>
+    <string name="done_label" msgid="2093726099505892398">"Готово"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Кружни клизач за сате"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Кружни клизач за минуте"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Изаберите сате"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Изаберите минуте"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Приказ дана у месецу у виду мреже"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Листа година"</string>
+    <string name="select_day" msgid="7774759604701773332">"Изаберите месец и дан"</string>
+    <string name="select_year" msgid="7952052866994196170">"Изаберите годину"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Изабрали сте <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Избрисали сте <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index db7d7d0..5ef51ce 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Tillåter att appen använder lågnivåfunktioner i SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"läsa rambuffert"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Tillåter att appen läser innehållet i rambufferten."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"få tillgång till InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Tillåter att appen använder lågnivåfunktioner i InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurerar Wi-Fi-skärmar"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tillåter att appen konfigurerar och ansluter till Wi-Fi-skärmar."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kontrollerar Wi-Fi-skärmar"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Dela med"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dela med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Skärmlåsfunktion. Tryck och dra."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Dra uppåt för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Dra nedåt för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Dra åt vänster för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Dra åt höger för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Lås upp"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Tyst"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Ljud på"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Sök"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Lås upp genom att dra."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Anslut mikrofonlurar om du vill att lösenordet ska läsas upp."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkt."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Försök igen senare"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Dra nedåt om du vill avbryta fullskärmsläget."</string>
+    <string name="done_label" msgid="2093726099505892398">"Klart"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Cirkelreglage för timmar"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Cirkelreglage för minuter"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Välj timmar"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Välj minuter"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Rutnät för månad"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Lista över år"</string>
+    <string name="select_day" msgid="7774759604701773332">"Välj månad och dag"</string>
+    <string name="select_year" msgid="7952052866994196170">"Välj år"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> har markerats"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> har tagits bort"</string>
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index b48689e..2524102 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Inaruhusu programu kutumia vipengee vya kiwango cha chini vya SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"soma bafa ya fremu"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Inaruhusu programu kusoma maudhui ya fremu ya bafa."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"fikia InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Inaruhusu programu kutumia vipengele vya chini vya InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"sanidi maonyesho ya Wifi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Inaruhusu programu kusanidi na kuunganika kwenye maonyesho ya Wifi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"dhibiti maonyesho ya Wifi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Shiriki na"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Shiriki na <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Utambo unaosonga. Gusa &amp; shika"</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Sogeza juu kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Sogeza chini kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Sogeza kushoto kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Sogeza kulika kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Fungua"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Kimya"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Sauti imewashwa"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Tafuta"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Pitisha ili kufungua."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Chomeka kifaa cha sauti ili kusikiliza vibonye vya nenosiri vikizungumzwa."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Nukta."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Jaribu tena baadaye"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Telezesha kidole kwa kasi chini kuanzia juu ili uondoke kwenye skrini zima."</string>
+    <string name="done_label" msgid="2093726099505892398">"Imekamilika"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kitelezi cha mviringo wa saa"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kitelezi cha mviringo wa dakika"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Chagua saa"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Chagua dakika"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Gridi ya mwezi ya siku"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Orodha ya miaka"</string>
+    <string name="select_day" msgid="7774759604701773332">"Chagua mwezi na siku"</string>
+    <string name="select_year" msgid="7952052866994196170">"Chagua mwaka"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> kimechaguliwa"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> kimefutwa"</string>
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index f298a8f..686f795 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"อนุญาตให้แอปพลิเคชันใช้คุณลักษณะระดับต่ำของ SurfaceFlinger"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"อ่านเฟรมบัฟเฟอร์"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"อนุญาตให้แอปพลิเคชันอ่านเนื้อหาในเฟรมบัฟเฟอร์"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"เข้าถึง InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"อนุญาตให้แอปใช้คุณลักษณะระดับต่ำของ InputFlinger"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"กำหนดค่าการแสดงผลด้วย WiFi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"อนุญาตให้แอปกำหนดค่าและเชื่อมต่อกับจอแสดงผล WiFi ได้"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ควบคุมการแสดงผลด้วย WiFi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"แบ่งปันกับ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"แบ่งปันด้วย <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"ที่จับสำหรับเลื่อน แตะค้างไว้"</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"เลื่อนขึ้นเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"เลื่อนลงเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"เลื่อนไปทางซ้ายเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"เลื่อนไปทางขวาเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"ปลดล็อก"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"กล้อง"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"ปิดเสียง"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"เปิดเสียง"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"ค้นหา"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"กวาดเพื่อปลดล็อก"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"เสียบชุดหูฟังเพื่อฟังเสียงเมื่อพิมพ์รหัสผ่าน"</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"เครื่องหมายจุด"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"ลองอีกครั้งในภายหลัง"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"กวาดนิ้วจากบนลงล่างเพื่อออกจากโหมดเต็มหน้าจอ"</string>
+    <string name="done_label" msgid="2093726099505892398">"เสร็จสิ้น"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"ตัวเลื่อนหมุนระบุชั่วโมง"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"ตัวเลื่อนหมุนระบุนาที"</string>
+    <string name="select_hours" msgid="6043079511766008245">"เลือกชั่วโมง"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"เลือกนาที"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"ตารางเดือนของวัน"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"รายการปี"</string>
+    <string name="select_day" msgid="7774759604701773332">"เลือกเดือนและวัน"</string>
+    <string name="select_year" msgid="7952052866994196170">"เลือกปี"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"เลือก <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"ลบ <xliff:g id="KEY">%1$s</xliff:g> แล้ว"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 85dd968..1b6bc78 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Pinapayagan ang app na gamitin ang mababang antas na mga tampok ng SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"basahin ang buffer ng frame"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Pinapayagan ang app na basahin ang nilalaman ng buffer ng frame."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"i-access ang InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Nagbibigay-daan sa app na gumamit ng mga tampok ng InputFlinger sa mababang antas."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"mag-configure ng mga Wifi display"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Pinapayagan ang app na mag-configure at kumonekta sa mga Wifi display."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"magkontrol ng mga Wifi display"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Ibahagi sa"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Ibahagi sa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Hawakan sa pag-slide. Pindutin nang matagal."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Mag-slide pataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Mag-slide pababa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Mag-slide pakaliwa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Mag-slide pakanan para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"I-unlock"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Tahimik"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"I-on ang tunog"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Maghanap"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Mag-swipe upang i-unlock."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Mag-plug in ng isang headset upang marinig ang mga password key na binabanggit."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Subukang muli sa ibang pagkakataon"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Mag-swipe pababa mula sa itaas upang lumabas sa full screen."</string>
+    <string name="done_label" msgid="2093726099505892398">"Tapos na"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Pabilog na slider ng mga oras"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Pabilog na slider ng mga minuto"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Pumili ng mga oras"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Pumili ng mga minuto"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Grid ng mga araw ayon sa buwan"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Listahan ng taon"</string>
+    <string name="select_day" msgid="7774759604701773332">"Pumili ng buwan at araw"</string>
+    <string name="select_year" msgid="7952052866994196170">"Pumili ng taon"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Napili ang <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Tinanggal ang <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 9ca752e..c05a684 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Uygulamaya, SurfaceFlinger\'a ait düşük düzey özellikleri kullanma izni verir."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"çerçeve arabelleğini oku"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Uygulamaya, çerçeve arabelleğinin içeriğini okuma izni verir."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger\'a eriş"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Uygulamaya, alt düzey InputFlinger özelliklerini kullanma izni verir."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Kablosuz ekranları yapılandır"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Uygulamaya kablosuz ekranları yapılandırma ve bunlara bağlanma izni verir."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Kablosuz ekranları denetle"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Şununla paylaş:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ile paylaş"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Kayan tutma yeri. Dokunun ve basılı tutun."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için yukarı kaydırın."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için aşağı kaydırın."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sola kaydırın."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sağa kaydırın."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Kilidi aç"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Sessiz"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Ses açık"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Ara"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Kilidi açmak için kaydırın."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Şifre tuşlarının sesli okunmasını dinlemek için mikrofonlu kulaklık takın."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Nokta."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Daha sonra tekrar deneyin"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Tam ekrandan çıkmak için yukarıdan aşağıya hızlıca kaydırın."</string>
+    <string name="done_label" msgid="2093726099505892398">"Bitti"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Saat kaydırma çemberi"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Dakika kaydırma çemberi"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Saati seçin"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Dakikayı seçin"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Ayın günleri tablosu"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Yıl listesi"</string>
+    <string name="select_day" msgid="7774759604701773332">"Ayı ve günü seçin"</string>
+    <string name="select_year" msgid="7952052866994196170">"Yılı seçin"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seçildi"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> silindi"</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 556b35b..bc3f45b 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Дозволяє програмі використовувати низькорівневі функції SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"читати фрейм-буфер"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Дозволяє програмі читати вміст буфера кадрів."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"отримувати доступ до InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Дозволяє програмі використовувати низькорівневі функції InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"налаштувати екрани Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дозволяє програмі налаштовувати екрани Wi-Fi і під’єднуватися до них."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"керувати екранами Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Надіслати через"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Надіслати через <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Вказівник-повзунок. Торкніться й утримуйте."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Проведіть пальцем угору, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Проведіть пальцем униз, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Проведіть пальцем ліворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Проведіть пальцем праворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Розблокувати"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Без звуку"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Увімкнути звук"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Пошук"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Гортайте, щоб розблокувати."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Підключіть гарнітуру, щоб прослухати відтворені вголос символи пароля."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Крапка."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Спробуйте пізніше"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Проведіть пальцем зверху вниз, щоб вийти з повноекранного режиму."</string>
+    <string name="done_label" msgid="2093726099505892398">"Готово"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Вибір годин на циферблаті"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Вибір хвилин на циферблаті"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Виберіть години"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Виберіть хвилини"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Вікно вибору дати"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Меню вибору року"</string>
+    <string name="select_day" msgid="7774759604701773332">"Виберіть місяць і день"</string>
+    <string name="select_year" msgid="7952052866994196170">"Виберіть рік"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Вибрано: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> видалено"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index c8f5014..bd9656e 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Cho phép ứng dụng sử dụng các tính năng SurfaceFlinger cấp độ thấp."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"đọc bộ đệm khung"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Cho phép ứng dụng đọc nội dung của bộ đệm khung."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"truy cập InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Cho phép ứng dụng sử dụng các tính năng InputFlinger cấp độ thấp."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"định cấu hình màn hình Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Cho phép ứng dụng định cấu hình và kết nối với màn hình Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kiểm soát màn hình Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Chia sẻ với"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Chia sẻ với <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Tay trượt. Chạm &amp; giữ."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Trượt lên để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Trượt xuống để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Trượt sang trái để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Trượt sang phải để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Mở khóa"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Máy ảnh"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Im lặng"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Bật âm thanh"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Tìm kiếm"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Trượt để mở khóa."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Cắm tai nghe để nghe các khóa mật khẩu được đọc."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dấu chấm."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Hãy thử lại sau"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Vuốt từ trên xuống để thoát toàn màn hình."</string>
+    <string name="done_label" msgid="2093726099505892398">"Xong"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Thanh trượt giờ hình tròn"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Thanh trượt phút hình tròn"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Chọn giờ"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Chọn phút"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Lưới ngày theo tháng"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Danh sách năm"</string>
+    <string name="select_day" msgid="7774759604701773332">"Chọn tháng và ngày"</string>
+    <string name="select_year" msgid="7952052866994196170">"Chọn năm"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Đã chọn <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Đã xóa <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index ba226af8..794caa6 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"允许应用使用 SurfaceFlinger 低级功能。"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"读取帧缓冲区"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"允许应用读取帧缓冲区的内容。"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"使用 InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"允许应用使用 InputFlinger 底层功能。"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"配置 WLAN 显示设备"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允许应用配置并连接到 WLAN 显示设备。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 WLAN 显示设备"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"分享方式"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"使用<xliff:g id="APPLICATION_NAME">%s</xliff:g>分享"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"滑动手柄。触摸并按住。"</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"向上滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"向下滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"向左滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"向右滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"解锁"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"相机"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"静音"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"打开声音"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"搜索"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"滑动解锁。"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"需要插入耳机才能听到密码的按键声。"</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"点。"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"稍后重试"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"从顶部向下滑动即可退出全屏模式。"</string>
+    <string name="done_label" msgid="2093726099505892398">"完成"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"小时转盘"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"分钟转盘"</string>
+    <string name="select_hours" msgid="6043079511766008245">"选择小时"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"选择分钟"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"按月份划分的日期网格"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"年份列表"</string>
+    <string name="select_day" msgid="7774759604701773332">"选择月份和日期"</string>
+    <string name="select_year" msgid="7952052866994196170">"选择年份"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"已选择<xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"已删除<xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index ab8ceed..9b28306 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"允許應用程式使用 SurfaceFlinger 的低層功能。"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"讀取框架緩衝區"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"允許應用程式讀取畫面緩衝區的內容。"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"存取 InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"允許應用程式使用 InputFlinger 的低階功能。"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"設定 WiFi Display"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允許應用程式設定及連接 WiFi Display。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 WiFi Display"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"分享給"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"與「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」分享"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"滑動控制。持續輕觸。"</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"向下滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"向右滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"解鎖"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"相機"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"靜音"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"音效已開啟"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"滑動即可解鎖。"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"插上耳機即可聽到系統朗讀密碼鍵。"</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"點。"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"稍後再試"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"由頂端往下快速滑動即可離開全螢幕。"</string>
+    <string name="done_label" msgid="2093726099505892398">"完成"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"小時環形滑桿"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"分鐘環形滑桿"</string>
+    <string name="select_hours" msgid="6043079511766008245">"選取小時"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"選取分鐘"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"顯示每日的月曆方格"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"年份清單"</string>
+    <string name="select_day" msgid="7774759604701773332">"選取月份和日期"</string>
+    <string name="select_year" msgid="7952052866994196170">"選取年份"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"已選取<xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> 已刪除"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 40d6260..532af0a 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"允許應用程式使用 SurfaceFlinger 的低階功能。"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"讀取框架緩衝"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"允許應用程式讀取畫面緩衝區的內容。"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"存取 InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"允許應用程式使用 InputFlinger 的低階功能。"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"設定 Wi-Fi 顯示裝置"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允許應用程式設定及連接 Wi-Fi 顯示裝置。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 Wi-Fi 顯示裝置"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"分享對象:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"與「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」分享"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"滑動控制。持續輕觸。"</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"向下滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"向右滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"解除鎖定"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"相機"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"靜音"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"開啟音效"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"滑動即可解鎖。"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"連接耳機即可聽取系統朗讀密碼按鍵。"</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"點。"</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"稍後再試"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"從頂端往下滑動即可退出全螢幕模式。"</string>
+    <string name="done_label" msgid="2093726099505892398">"完成"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"小時數環狀滑桿"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"分鐘數環狀滑桿"</string>
+    <string name="select_hours" msgid="6043079511766008245">"選取小時數"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"選取分鐘數"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"日期網格 (按月顯示)"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"年份清單"</string>
+    <string name="select_day" msgid="7774759604701773332">"選取月份和日期"</string>
+    <string name="select_year" msgid="7952052866994196170">"選取年份"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"已選取 <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"已刪除 <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 563cb3f..d902314 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -484,6 +484,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Ivumela uhlelo lokusebenza ukuthi isebenzise okuqukethwe i-SurfaceFlinger okusezingeni eliphansi."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"funda isikhumbuli sesikhashana sendikimba"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Ivumela uhlelo lokusebenza ukuthi ifunde okuqukethwe ifreyimu yebhafa."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"finyelela ku-InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Ivumela uhlelo lokusebenza ukuthi lusebenzise izici zezinga eliphansi ze-InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"lungisa ukubukwa kwe-Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Ivumela uhlelo lokusebenza ukulungisa nokuxhuma ekubukisweni kwe-Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"lawula ukubukwa kwe-Wi-Fi"</string>
@@ -1425,15 +1427,6 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Yabelana no"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Yabelana no <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Ihaambis isibambo. Thinta &amp; ubambe."</string>
-    <string name="description_direction_up" msgid="7169032478259485180">"Shelelisela ngenhla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="5087739728639014595">"Shelelisela ngezansi ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Shelelisela ngakwesokunxele ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="8034433242579600980">"Shelelisela ngakwesokudla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_target_unlock" msgid="2228524900439801453">"Vula"</string>
-    <string name="description_target_camera" msgid="969071997552486814">"Ikhamera"</string>
-    <string name="description_target_silent" msgid="893551287746522182">"Thulile"</string>
-    <string name="description_target_soundon" msgid="30052466675500172">"Umsindo uvuliwe"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Sesha"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Swayipha ukuze uvule."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Plaka ku-headset ukuze uzwe okhiye bephasiwedi ezindlebeni zakho bezwakala kakhulu."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Icashazi."</string>
@@ -1664,4 +1657,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Zama futhi emva kwesikhathi"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Swayiphela phansi kusukela phezulu ukuze uphume kusikrini esigcwele."</string>
+    <string name="done_label" msgid="2093726099505892398">"Kwenziwe"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Amahora weslayidi esiyindingilizi"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Amaminithi weslayidi esiyindingilizi"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Khetha amahora"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Khetha amaminithi"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Igridi yenyanga yezinsuku"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Uhlu lonyaka"</string>
+    <string name="select_day" msgid="7774759604701773332">"Khetha inyanga nosuku"</string>
+    <string name="select_year" msgid="7952052866994196170">"Khetha unyaka"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"I-<xliff:g id="ITEM">%1$s</xliff:g> ekhethiwe"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"I-<xliff:g id="KEY">%1$s</xliff:g> isusiwe"</string>
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 42e3b50..5ba749a 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -447,6 +447,15 @@
              to {@link android.view.WindowManager.LayoutParams#FLAG_TRANSLUCENT_NAVIGATION}. -->
         <attr name="windowTranslucentNavigation" format="boolean" />
 
+        <!-- Flag indicating whether this window requests that content changes be performed
+             as scene changes with transitions. Corresponds to
+             {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS}. -->
+        <attr name="windowContentTransitions" format="boolean" />
+
+        <!-- Reference to a TransitionManager XML resource defining the desired
+             transitions between different window content. -->
+        <attr name="windowContentTransitionManager" format="reference" />
+
         <!-- ============ -->
         <!-- Alert Dialog styles -->
         <!-- ============ -->
@@ -607,6 +616,8 @@
         <attr name="popupMenuStyle" format="reference" />
         <!-- Default StackView style. -->
         <attr name="stackViewStyle" format="reference" />
+        <!-- Default style for the FragmentBreadCrumbs widget. -->
+        <attr name="fragmentBreadCrumbsStyle" format="reference" />
 
         <!-- NumberPicker style. -->
         <attr name="numberPickerStyle" format="reference" />
@@ -617,6 +628,18 @@
         <!-- The TimePicker style. -->
         <attr name="timePickerStyle" format="reference" />
 
+        <!-- The TimePicker Header background color . -->
+        <attr name="timePickerHeaderBackgroundColor" format="reference" />
+
+        <!-- The TimePicker Header time label text appearance -->
+        <attr name="timePickerHeaderTimeLabelTextAppearance" format="reference" />
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <attr name="timePickerHeaderAmPmLabelTextAppearance" format="reference" />
+
+        <!-- The TimePicker dialog theme. -->
+        <attr name="timePickerDialogTheme" format="reference" />
+
         <!-- The DatePicker style. -->
         <attr name="datePickerStyle" format="reference" />
 
@@ -1604,6 +1627,9 @@
         <attr name="windowCloseOnTouchOutside" />
         <attr name="windowTranslucentStatus" />
         <attr name="windowTranslucentNavigation" />
+        <attr name="windowContentTransitions" />
+        <attr name="windowContentTransitionManager" />
+
         <!-- The minimum width the window is allowed to be, along the major
              axis of the screen.  That is, when in landscape.  Can be either
              an absolute dimension or a fraction of the screen size in that
@@ -2725,6 +2751,8 @@
         <!-- Enables the fast scroll thumb that can be dragged to quickly scroll through
              the list. -->
         <attr name="fastScrollEnabled" format="boolean" />
+        <!-- Specifies the style of the fast scroll decorations. -->
+        <attr name="fastScrollStyle" format="reference" />
         <!-- When set to true, the list will use a more refined calculation
              method based on the pixels height of the items visible on screen. This
              property is set to true by default but should be set to false if your adapter
@@ -2793,6 +2821,36 @@
     </declare-styleable>
     <declare-styleable name="EditText">
     </declare-styleable>
+    <declare-styleable name="FastScroll">
+        <!-- Drawable used for the scroll bar thumb. -->
+        <attr name="thumbDrawable" format="reference" />
+        <!-- Minimum width of the thumb. -->
+        <attr name="thumbMinWidth" format="dimension" />
+        <!-- Minimum height of the thumb. -->
+        <attr name="thumbMinHeight" format="dimension" />
+        <!-- Drawable used for the scroll bar track. -->
+        <attr name="trackDrawable" format="reference" />
+        <!-- Drawable used for the section header preview when right-aligned. -->
+        <attr name="backgroundRight" format="reference" />
+        <!-- Drawable used for the section header preview when left-aligned. -->
+        <attr name="backgroundLeft" format="reference" />
+        <!-- Position of section header preview. -->
+        <attr name="position">
+            <!-- Floating at the top of the content. -->
+            <enum name="floating" value="0" />
+            <!-- Pinned alongside the thumb. -->
+            <enum name="atThumb" value="1" />
+        </attr>
+        <attr name="textAppearance" />
+        <attr name="textColor" />
+        <attr name="textSize" />
+        <!-- Minimum width of the section header preview. -->
+        <attr name="minWidth" />
+        <!-- Minimum height of the section header preview. -->
+        <attr name="minHeight" />
+        <!-- Padding for the section header preview. -->
+        <attr name="padding" />
+    </declare-styleable>
     <declare-styleable name="FrameLayout">
         <!-- Defines the drawable to draw over the content. This can be used as an overlay.
              The foreground drawable participates in the padding of the content if the gravity
@@ -3958,6 +4016,30 @@
     <declare-styleable name="TimePicker">
         <!-- @hide The layout of the time picker. -->
         <attr name="internalLayout" />
+        <!-- @hide The layout of the legacy time picker. -->
+        <attr name="legacyLayout" format="reference" />
+        <!-- @hide Enables or disable the use of the legacy layout for the TimePicker. -->
+        <attr name="legacyMode" format="boolean" />
+        <!-- @hide The color when the non legacy TimePicker is disabled. -->
+        <attr name="disabledColor" format="color|reference" />
+        <!-- @hide The color for selected text of the non legacy TimePicker. -->
+        <attr name="headerSelectedTextColor" format="color|reference" />
+        <!-- @hide The color for unselected text of the non legacy TimePicker. -->
+        <attr name="headerUnselectedTextColor" format="color|reference" />
+        <!-- @hide The background color for the header of the non legacy TimePicker. -->
+        <attr name="headerBackgroundColor" format="color|reference" />
+        <!-- @hide The color for the hours/minutes numbers of the non legacy TimePicker. -->
+        <attr name="numbersTextColor" format="color|reference" />
+        <!-- @hide The background color for the hours/minutes numbers of the non legacy TimePicker. -->
+        <attr name="numbersBackgroundColor" format="color|reference" />
+        <!-- @hide The color for the AM/PM selectors of the non legacy TimePicker. -->
+        <attr name="amPmTextColor" format="color|reference" />
+        <!-- @hide The background color for the AM/PM selectors of the non legacy TimePicker when unselected. -->
+        <attr name="amPmUnselectedBackgroundColor" format="color|reference" />
+        <!-- @hide The background color for the AM/PM selectors of the non legacy TimePicker when selected. -->
+        <attr name="amPmSelectedBackgroundColor" format="color|reference" />
+        <!-- @hide The color for the hours/minutes selector of the non legacy TimePicker. -->
+        <attr name="numbersSelectorColor" format="color|reference" />
     </declare-styleable>
 
     <!-- ========================= -->
@@ -4159,6 +4241,14 @@
         <!-- Indicates if the drawable needs to be mirrored when its layout direction is
              RTL (right-to-left). -->
         <attr name="autoMirrored" />
+        <!-- Indicates how layer padding should affect the bounds of subsequent layers.
+            The default value is nest. -->
+        <attr name="paddingMode">
+            <!-- Nest each layer inside the padding of the previous layer. -->
+            <enum name="nest" value="0" />
+            <!-- Stack each layer directly atop the previous layer. -->
+            <enum name="stack" value="1" />
+        </attr>
     </declare-styleable>
 
     <!-- Describes an item (or child) of a LayerDrawable. -->
@@ -4174,7 +4264,7 @@
         <!-- Drawable used to render the layer. -->
         <attr name="drawable" />
         <!-- Identifier of the layer. This can be used to retrieve the layer
-             from a drawbable container. -->
+             from a drawable container. -->
         <attr name="id" />
     </declare-styleable>
 
@@ -4605,6 +4695,14 @@
         <attr name="fromScene" format="reference" />
         <!-- The destination scene in this scene change. -->
         <attr name="toScene" format="reference" />
+        <!-- The name of the originating scene in this scene change.
+             Apps should treat this name as an API in the same sense
+             that an Intent action or extra key is. -->
+        <attr name="fromSceneName" format="string" />
+        <!-- The name of the destination scene in this scene change.
+             Apps should treat this name as an API in the same sense
+             that an Intent action or extra key is. -->
+        <attr name="toSceneName" format="string" />
     </declare-styleable>
 
     <!-- ========================== -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 28e7af7..55babfa 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -22,8 +22,6 @@
     <drawable name="screen_background_dark">#ff000000</drawable>
     <drawable name="status_bar_closed_default_background">#ff000000</drawable>
     <drawable name="status_bar_opened_default_background">#ff000000</drawable>
-    <drawable name="notification_item_background_color">#ff111111</drawable>
-    <drawable name="notification_item_background_color_pressed">#ff454545</drawable>
     <drawable name="search_bar_default_color">#ff000000</drawable>
     <drawable name="safe_mode_background">#60000000</drawable>
     <!-- Background drawable that can be used for a transparent activity to
@@ -202,5 +200,22 @@
     <color name="keyguard_avatar_frame_pressed_color">#ff35b5e5</color>
 
     <color name="accessibility_focus_highlight">#80ffff00</color>
+
+    <!-- New TimePicker colors -->
+    <color name="timepicker_default_background_holo_light">@android:color/white</color>
+    <color name="timepicker_default_background_holo_dark">#ff303030</color>
+
+    <color name="timepicker_default_text_color_holo_light">#8c8c8c</color>
+    <color name="timepicker_default_text_color_holo_dark">@android:color/white</color>
+
+    <color name="timepicker_default_disabled_color_holo_light">#7f000000</color>
+    <color name="timepicker_default_disabled_color_holo_dark">#7f08c8c8</color>
+
+    <color name="timepicker_default_ampm_selected_background_color_holo_light">@android:color/holo_blue_light</color>
+    <color name="timepicker_default_ampm_selected_background_color_holo_dark">@android:color/holo_blue_light</color>
+
+    <color name="timepicker_default_ampm_unselected_background_color_holo_light">@android:color/white</color>
+    <color name="timepicker_default_ampm_unselected_background_color_holo_dark">@android:color/transparent</color>
+
 </resources>
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b34c792..b1b1f42 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -508,6 +508,12 @@
         <item>40</item>
     </integer-array>
 
+    <!-- Vibrator pattern for feedback when selecting an hour/minute tick of a Clock -->
+    <integer-array name="config_clockTickVibePattern">
+        <item>125</item>
+        <item>5</item>
+    </integer-array>
+
     <!-- Vibrator pattern for feedback about booting with safe mode disabled -->
     <integer-array name="config_safeModeDisabledVibePattern">
         <item>0</item>
@@ -1304,4 +1310,12 @@
         <item>333</item>
         <item>353</item>
     </string-array>
+
+    <!-- Override the default detection behavior for the framework method
+         android.view.ViewConfiguration#hasPermanentMenuKey().
+         Valid settings are:
+         0 - No change. Use the default autodetection behavior.
+         1 - The device DOES have a permanent menu key; ignore autodetection.
+         2 - The device DOES NOT have a permanent menu key; ignore autodetection. -->
+    <integer name="config_overrideHasPermanentMenuKey">0</integer>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index f96195c..8c8c322 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -50,16 +50,6 @@
     <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
     <dimen name="status_bar_edge_ignore">5dp</dimen>
 
-    <!-- Minimum size of the fastscroll overlay -->
-    <dimen name="fastscroll_overlay_size">104dp</dimen>
-    <!-- Text size of the fastscroll overlay -->
-    <dimen name="fastscroll_overlay_text_size">52sp</dimen>
-    <!-- Padding of the fastscroll overlay -->
-    <dimen name="fastscroll_overlay_padding">16dp</dimen>
-    <!-- Width of the fastscroll thumb -->
-    <dimen name="fastscroll_thumb_width">64dp</dimen>
-    <!-- Height of the fastscroll thumb -->
-    <dimen name="fastscroll_thumb_height">52dp</dimen>
     <!-- Min width for a tablet device -->
     <dimen name="min_xlarge_screen_width">800dp</dimen>
 
@@ -77,18 +67,6 @@
     <!-- Size of lockscreen outerring on unsecure unlock LockScreen -->
     <dimen name="keyguard_lockscreen_outerring_diameter">270dp</dimen>
 
-    <!-- Default target placement radius for GlowPadView. Should be 1/2 of outerring diameter. -->
-    <dimen name="glowpadview_target_placement_radius">135dip</dimen>
-
-    <!-- Default glow radius for GlowPadView -->
-    <dimen name="glowpadview_glow_radius">75dip</dimen>
-
-    <!-- Default distance beyond which GlowPadView snaps to the matching target -->
-    <dimen name="glowpadview_snap_margin">40dip</dimen>
-
-    <!-- Default distance from each snap target that GlowPadView considers a "hit" -->
-    <dimen name="glowpadview_inner_radius">15dip</dimen>
-
     <!-- Preference activity side margins -->
     <dimen name="preference_screen_side_margin">0dp</dimen>
     <!-- Preference activity side margins negative-->
@@ -356,6 +334,32 @@
     <!-- Outline width for video subtitles. -->
     <dimen name="subtitle_outline_width">2dp</dimen>
 
+    <!-- New TimePicker dimensions. -->
+    <item name="timepicker_circle_radius_multiplier" format="float" type="string">0.82</item>
+    <item name="timepicker_circle_radius_multiplier_24HourMode" format="float" type="string">0.85</item>
+    <item name="timepicker_selection_radius_multiplier" format="float" type="string">0.16</item>
+    <item name="timepicker_ampm_circle_radius_multiplier" format="float" type="string">0.19</item>
+    <item name="timepicker_numbers_radius_multiplier_normal" format="float" type="string">0.81</item>
+    <item name="timepicker_numbers_radius_multiplier_inner" format="float" type="string">0.60</item>
+    <item name="timepicker_numbers_radius_multiplier_outer" format="float" type="string">0.83</item>
+    <item name="timepicker_text_size_multiplier_normal" format="float" type="string">0.17</item>
+    <item name="timepicker_text_size_multiplier_inner" format="float" type="string">0.14</item>
+    <item name="timepicker_text_size_multiplier_outer" format="float" type="string">0.11</item>
+    <item name="timepicker_transition_mid_radius_multiplier" format="float" type="string">0.95</item>
+    <item name="timepicker_transition_end_radius_multiplier" format="float" type="string">1.3</item>
+
+    <dimen name="timepicker_time_label_size">60sp</dimen>
+    <dimen name="timepicker_extra_time_label_margin">-30dp</dimen>
+    <dimen name="timepicker_ampm_label_size">16sp</dimen>
+    <dimen name="timepicker_done_label_size">14sp</dimen>
+    <dimen name="timepicker_ampm_left_padding">6dip</dimen>
+    <dimen name="timepicker_separator_padding">4dip</dimen>
+    <dimen name="timepicker_header_height">96dip</dimen>
+    <dimen name="timepicker_minimum_margin_sides">48dip</dimen>
+    <dimen name="timepicker_minimum_margin_top_bottom">24dip</dimen>
+    <dimen name="timepicker_radial_picker_dimen">270dip</dimen>
+
     <!-- width of ImmersiveModeConfirmation (-1 for match_parent) -->
     <dimen name="immersive_mode_cling_width">-1px</dimen>
+
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 8187939..090702d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2087,4 +2087,26 @@
   <public type="style" name="Theme.DeviceDefault.NoActionBar.TranslucentDecor" id="0x010301e3" />
   <public type="style" name="Theme.DeviceDefault.Light.NoActionBar.TranslucentDecor" id="0x010301e4" />
 
+<!-- ===============================================================
+     Resources added in version 20 of the platform
+     =============================================================== -->
+  <eat-comment />
+
+  <public type="attr" name="fragmentBreadCrumbsStyle" />
+  <public type="attr" name="fastScrollStyle" />
+  <public type="attr" name="windowContentTransitions" />
+  <public type="attr" name="windowContentTransitionManager" />
+
+  <public type="style" name="Widget.Holo.FragmentBreadCrumbs" />
+  <public type="style" name="Widget.Holo.Light.FragmentBreadCrumbs" />
+  <public type="style" name="Widget.DeviceDefault.FragmentBreadCrumbs" />
+  <public type="style" name="Widget.DeviceDefault.Light.FragmentBreadCrumbs" />
+  <public type="style" name="Widget.FastScroll" />
+  <public type="style" name="Widget.Holo.FastScroll" />
+  <public type="style" name="Widget.Holo.Light.FastScroll" />
+  <public type="style" name="Widget.DeviceDefault.FastScroll" />
+  <public type="style" name="Widget.DeviceDefault.Light.FastScroll" />
+
+  <public type="style" name="Theme.Quantum" />
+
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9025400a..b271471 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1431,6 +1431,11 @@
     <string name="permdesc_readFrameBuffer">Allows the app to read the content of the frame buffer.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_accessInputFlinger">access InputFlinger</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_accessInputFlinger">Allows the app to use InputFlinger low-level features.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_configureWifiDisplay">configure Wifi displays</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_configureWifiDisplay">Allows the app to configure and connect to Wifi displays.</string>
@@ -3921,26 +3926,6 @@
     <!-- Description of the sliding handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
     <string name="content_description_sliding_handle">"Sliding handle. Touch &amp; hold."</string>
 
-    <!-- Description of the up direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
-    <string name="description_direction_up">Slide up for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
-    <!-- Description of the down direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
-    <string name="description_direction_down">Slide down for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
-    <!-- Description of the left direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
-    <string name="description_direction_left">"Slide left for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
-    <!-- Description of the right direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
-    <string name="description_direction_right">Slide right for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
-
-    <!-- Description of the unlock target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
-    <string name="description_target_unlock">Unlock</string>
-    <!-- Description of the camera target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
-    <string name="description_target_camera">Camera</string>
-    <!-- Description of the silent target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
-    <string name="description_target_silent">Silent</string>
-    <!-- Description of the sound on target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
-    <string name="description_target_soundon">Sound on</string>
-    <!-- Description of the unlock target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
-    <string name="description_target_search">Search</string>
-
     <!-- Description of the unlock handle in the Slide unlock screen for tablets. [CHAR LIMIT=NONE] -->
     <string name="description_target_unlock_tablet">Swipe to unlock.</string>
 
@@ -4521,4 +4506,55 @@
     <!-- Cling help message when hiding the navigation bar entering immersive mode [CHAR LIMIT=none] -->
     <string name="immersive_mode_confirmation" msgid="8554991488096662508">Swipe down from the top to exit full screen.</string>
 
+    <!-- Label for button to confirm chosen date or time [CHAR LIMIT=30] -->
+    <string name="done_label">Done</string>
+    <!--
+         Content description for the hour selector in the time picker, which displays
+         selectable hours of the day along the inside edge of a circle, as in an analog clock.
+         [CHAR LIMIT=50]
+    -->
+    <string name="hour_picker_description">Hours circular slider</string>
+    <!--
+         Content description for the minute selector in the time picker, which displays
+         selectable five-minute intervals along the inside edge of a circle, as in an analog clock.
+         [CHAR LIMIT=50]
+    -->
+    <string name="minute_picker_description">Minutes circular slider</string>
+    <!-- Accessibility announcement for hour circular picker [CHAR LIMIT=NONE] -->
+    <string name="select_hours">Select hours</string>
+    <!-- Accessibility announcement for minute circular picker [CHAR LIMIT=NONE] -->
+    <string name="select_minutes">Select minutes</string>
+
+    <!--
+        Content description for the month and day selector in the date picker, which displays
+        a selectable grid of days laid out by month.
+        [CHAR LIMIT=50]
+     -->
+    <string name="day_picker_description">Month grid of days</string>
+    <!--
+        Content description for the year selector in the date picker, which displays
+        a scrolling, vertical list of years.
+        [CHAR LIMIT=50]
+     -->
+    <string name="year_picker_description">Year list</string>
+    <!-- Accessibility announcement for the day picker [CHAR LIMIT=NONE] -->
+    <string name="select_day">Select month and day</string>
+    <!-- Accessibility announcement for the year picker [CHAR LIMIT=NONE] -->
+    <string name="select_year">Select year</string>
+    <!-- Accessibility description for the item that is currently selected. -->
+    <string name="item_is_selected"><xliff:g id="item" example="2013">%1$s</xliff:g> selected</string>
+    <!-- Accessibility announcement when a number that had been typed in is deleted [CHAR_LIMIT=NONE] -->
+    <string name="deleted_key"><xliff:g id="key" example="4">%1$s</xliff:g> deleted</string>
+
+    <!-- DO NOT TRANSLATE -->
+    <string name="time_placeholder">--</string>
+
+    <!-- DO NOT TRANSLATE -->
+    <string name="radial_numbers_typeface">sans-serif</string>
+    <!-- DO NOT TRANSLATE -->
+    <string name="sans_serif">sans-serif</string>
+
+    <!-- DO NOT TRANSLATE -->
+    <string name="day_of_week_label_typeface">sans-serif</string>
+
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index cb2fd6d..3af5d6d 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -292,6 +292,7 @@
     <style name="Widget.AbsListView">
         <item name="android:scrollbars">vertical</item>
         <item name="android:fadingEdge">vertical</item>
+        <item name="android:fastScrollStyle">?android:attr/fastScrollStyle</item>
     </style>
 
     <style name="Widget.GestureOverlayView">
@@ -510,6 +511,11 @@
         <item name="android:childDivider">@android:drawable/divider_horizontal_bright_opaque</item>
     </style>
 
+    <style name="Widget.FragmentBreadCrumbs">
+        <item name="android:padding">4dp</item>
+        <item name="android:animateLayoutChanges">true</item>
+    </style>
+
     <style name="Widget.ImageWell">
         <item name="android:background">@android:drawable/panel_picture_frame_background</item>
     </style>
@@ -544,7 +550,7 @@
     </style>
 
     <style name="Widget.TimePicker">
-        <item name="android:internalLayout">@android:layout/time_picker</item>
+        <item name="android:legacyLayout">@android:layout/time_picker_legacy</item>
     </style>
 
     <style name="Widget.DatePicker">
@@ -681,12 +687,6 @@
         <item name="android:popupAnimationStyle">@android:style/Animation.PopupWindow</item>
     </style>
 
-    <!-- Default style for {@link android.app.FragmentBreadCrumbs} view. -->
-    <style name="Widget.FragmentBreadCrumbs">
-        <item name="android:padding">4dp</item>
-        <item name="android:animateLayoutChanges">true</item>
-    </style>
-
     <style name="Widget.KeyboardView" parent="android:Widget">
         <item name="android:background">@android:drawable/keyboard_background</item>
         <item name="android:keyBackground">@android:drawable/btn_keyboard_key</item>
@@ -1662,6 +1662,9 @@
     <style name="Widget.Holo.ExpandableListView.White">
     </style>
 
+    <style name="Widget.Holo.FragmentBreadCrumbs" parent="Widget.FragmentBreadCrumbs">
+    </style>
+
     <style name="Widget.Holo.Gallery" parent="Widget.Gallery">
     </style>
 
@@ -1698,7 +1701,18 @@
     </style>
 
     <style name="Widget.Holo.TimePicker" parent="Widget.TimePicker">
+        <item name="android:legacyLayout">@android:layout/time_picker_legacy_holo</item>
         <item name="android:internalLayout">@android:layout/time_picker_holo</item>
+        <item name="android:disabledColor">@android:color/timepicker_default_disabled_color_holo_dark</item>
+        <item name="android:headerSelectedTextColor">@android:color/holo_blue_light</item>
+        <item name="android:headerUnselectedTextColor">@android:color/timepicker_default_text_color_holo_dark</item>
+        <item name="android:headerBackgroundColor">@android:color/timepicker_default_background_holo_dark</item>
+        <item name="android:numbersTextColor">@android:color/timepicker_default_text_color_holo_dark</item>
+        <item name="android:numbersBackgroundColor">@android:color/timepicker_default_background_holo_dark</item>
+        <item name="android:amPmTextColor">@android:color/timepicker_default_text_color_holo_dark</item>
+        <item name="android:amPmUnselectedBackgroundColor">@android:color/timepicker_default_background_holo_dark</item>
+        <item name="android:amPmSelectedBackgroundColor">@android:color/holo_blue_light</item>
+        <item name="android:numbersSelectorColor">@android:color/holo_blue_light</item>
     </style>
 
     <style name="Widget.Holo.DatePicker" parent="Widget.DatePicker">
@@ -2091,6 +2105,9 @@
     <style name="Widget.Holo.Light.ExpandableListView.White">
     </style>
 
+    <style name="Widget.Holo.Light.FragmentBreadCrumbs" parent="Widget.FragmentBreadCrumbs">
+    </style>
+
     <style name="Widget.Holo.Light.Gallery" parent="Widget.Gallery">
     </style>
 
@@ -2116,7 +2133,19 @@
     <style name="Widget.Holo.Light.NumberPicker" parent="Widget.Holo.NumberPicker">
     </style>
 
-    <style name="Widget.Holo.Light.TimePicker" parent="Widget.Holo.TimePicker">
+    <style name="Widget.Holo.Light.TimePicker" parent="Widget.TimePicker">
+        <item name="android:legacyLayout">@android:layout/time_picker_legacy_holo</item>
+        <item name="android:internalLayout">@android:layout/time_picker_holo</item>
+        <item name="android:disabledColor">@android:color/timepicker_default_disabled_color_holo_light</item>
+        <item name="android:headerSelectedTextColor">@android:color/holo_blue_light</item>
+        <item name="android:headerUnselectedTextColor">@android:color/timepicker_default_text_color_holo_light</item>
+        <item name="android:headerBackgroundColor">@android:color/timepicker_default_background_holo_light</item>
+        <item name="android:numbersTextColor">@android:color/timepicker_default_text_color_holo_light</item>
+        <item name="android:numbersBackgroundColor">@android:color/timepicker_default_background_holo_light</item>
+        <item name="android:amPmTextColor">@android:color/timepicker_default_text_color_holo_light</item>
+        <item name="android:amPmUnselectedBackgroundColor">@android:color/timepicker_default_background_holo_light</item>
+        <item name="android:amPmSelectedBackgroundColor">@android:color/holo_blue_light</item>
+        <item name="android:numbersSelectorColor">@android:color/holo_blue_light</item>
     </style>
 
     <style name="Widget.Holo.Light.DatePicker" parent="Widget.Holo.DatePicker">
@@ -2379,6 +2408,16 @@
     <style name="Animation.Holo.Dialog" parent="Animation.Dialog">
     </style>
 
+    <style name="Animation.Quantum" parent="Animation.Holo">
+    </style>
+
+    <style name="Animation.Quantum.Activity" parent="Animation.Holo.Activity">
+        <item name="activityOpenEnterAnimation">@null</item>
+        <item name="activityOpenExitAnimation">@null</item>
+        <item name="activityCloseEnterAnimation">@null</item>
+        <item name="activityCloseExitAnimation">@anim/fade_out</item>
+    </style>
+
     <!-- Dialog styles -->
 
     <style name="AlertDialog.Holo" parent="AlertDialog">
@@ -2531,4 +2570,57 @@
         <item name="android:textColor">#80ffffff</item>
     </style>
 
+    <style name="TextAppearance.TimePicker.TimeLabel" parent="TextAppearance">
+    </style>
+
+    <style name="TextAppearance.TimePicker.AmPmLabel" parent="TextAppearance">
+    </style>
+
+    <style name="TextAppearance.Holo.TimePicker.TimeLabel" parent="TextAppearance.Holo">
+        <item name="android:textSize">@dimen/timepicker_time_label_size</item>
+        <item name="android:textColor">@android:color/timepicker_default_text_color_holo_dark</item>
+    </style>
+
+    <style name="TextAppearance.Holo.TimePicker.AmPmLabel" parent="TextAppearance.Holo">
+        <item name="android:textSize">@dimen/timepicker_ampm_label_size</item>
+        <item name="android:textAllCaps">true</item>
+        <item name="android:textColor">@android:color/timepicker_default_text_color_holo_dark</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+
+    <style name="TextAppearance.Holo.Light.TimePicker.TimeLabel" parent="TextAppearance.Holo.Light">
+        <item name="android:textSize">@dimen/timepicker_time_label_size</item>
+        <item name="android:textColor">@color/timepicker_default_text_color_holo_light</item>
+    </style>
+
+    <style name="TextAppearance.Holo.Light.TimePicker.AmPmLabel" parent="TextAppearance.Holo.Light">
+        <item name="android:textSize">@dimen/timepicker_ampm_label_size</item>
+        <item name="android:textAllCaps">true</item>
+        <item name="android:textColor">@color/timepicker_default_text_color_holo_light</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+
+    <style name="Widget.FastScroll">
+        <item name="android:thumbDrawable">?android:attr/fastScrollThumbDrawable</item>
+        <item name="android:trackDrawable">?android:attr/fastScrollTrackDrawable</item>
+        <item name="android:backgroundLeft">?android:attr/fastScrollPreviewBackgroundLeft</item>
+        <item name="android:backgroundRight">?android:attr/fastScrollPreviewBackgroundRight</item>
+        <item name="android:position">?android:attr/fastScrollOverlayPosition</item>
+        <item name="android:textColor">?android:attr/fastScrollTextColor</item>
+        <item name="android:thumbMinWidth">64dp</item>
+        <item name="android:thumbMinHeight">52dp</item>
+        <item name="android:textSize">52sp</item>
+        <item name="android:minWidth">72dp</item>
+        <item name="android:minHeight">72dp</item>
+        <item name="android:padding">16dp</item>
+    </style>
+
+    <style name="Widget.Holo.FastScroll" parent="Widget.FastScroll">
+        <item name="android:thumbMinWidth">0dp</item>
+        <item name="android:thumbMinHeight">0dp</item>
+    </style>
+
+    <style name="Widget.Holo.Light.FastScroll" parent="Widget.Holo.FastScroll">
+    </style>
+
 </resources>
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index edeba02..512c9b8 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -206,6 +206,12 @@
     <style name="Widget.DeviceDefault.ExpandableListView.White" parent="Widget.Holo.ExpandableListView.White">
 
     </style>
+    <style name="Widget.DeviceDefault.FastScroll" parent="Widget.Holo.FastScroll">
+
+    </style>
+    <style name="Widget.DeviceDefault.FragmentBreadCrumbs" parent="Widget.Holo.FragmentBreadCrumbs">
+
+    </style>
     <style name="Widget.DeviceDefault.Gallery" parent="Widget.Holo.Gallery">
 
     </style>
@@ -309,6 +315,12 @@
     <style name="Widget.DeviceDefault.Light.ExpandableListView" parent="Widget.Holo.Light.ExpandableListView" >
 
     </style>
+    <style name="Widget.DeviceDefault.Light.FastScroll" parent="Widget.Holo.Light.FastScroll">
+
+    </style>
+    <style name="Widget.DeviceDefault.Light.FragmentBreadCrumbs" parent="Widget.Holo.Light.FragmentBreadCrumbs">
+
+    </style>
     <style name="Widget.DeviceDefault.Light.GridView" parent="Widget.Holo.Light.GridView" >
 
     </style>
@@ -729,4 +741,22 @@
     <style name="Widget.DeviceDefault.MediaRouteButton" parent="Widget.Holo.MediaRouteButton" />
     <style name="Widget.DeviceDefault.Light.MediaRouteButton" parent="Widget.Holo.Light.MediaRouteButton" />
 
+    <style name="TextAppearance.DeviceDefault.TimePicker.TimeLabel" parent="TextAppearance.Holo.TimePicker.TimeLabel">
+    </style>
+
+    <style name="TextAppearance.DeviceDefault.Light.TimePicker.TimeLabel" parent="TextAppearance.Holo.Light.TimePicker.TimeLabel">
+    </style>
+
+    <style name="TextAppearance.DeviceDefault.TimePicker.AmPmLabel" parent="TextAppearance.Holo.TimePicker.AmPmLabel">
+    </style>
+
+    <style name="TextAppearance.DeviceDefault.Light.TimePicker.AmPmLabel" parent="TextAppearance.Holo.Light.TimePicker.AmPmLabel">
+    </style>
+
+    <style name="Theme.DeviceDefault.Dialog.TimePicker" parent="Theme.Holo.Dialog.TimePicker">
+    </style>
+
+    <style name="Theme.DeviceDefault.Light.Dialog.TimePicker" parent="Theme.Holo.Light.Dialog.TimePicker">
+    </style>
+
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6d90973..680fb4f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -224,6 +224,7 @@
 
   <java-symbol type="attr" name="actionModeShareDrawable" />
   <java-symbol type="attr" name="alertDialogCenterButtons" />
+  <java-symbol type="attr" name="fragmentBreadCrumbsStyle" />
   <java-symbol type="attr" name="gestureOverlayViewStyle" />
   <java-symbol type="attr" name="keyboardViewStyle" />
   <java-symbol type="attr" name="numberPickerStyle" />
@@ -319,6 +320,7 @@
   <java-symbol type="integer" name="config_mobile_mtu" />
   <java-symbol type="integer" name="config_volte_replacement_rat"/>
   <java-symbol type="integer" name="config_valid_wappush_index" />
+  <java-symbol type="integer" name="config_overrideHasPermanentMenuKey" />
 
   <java-symbol type="color" name="tab_indicator_text_v4" />
 
@@ -332,11 +334,6 @@
   <java-symbol type="dimen" name="default_gap" />
   <java-symbol type="dimen" name="dropdownitem_icon_width" />
   <java-symbol type="dimen" name="dropdownitem_text_padding_left" />
-  <java-symbol type="dimen" name="fastscroll_overlay_size" />
-  <java-symbol type="dimen" name="fastscroll_overlay_text_size" />
-  <java-symbol type="dimen" name="fastscroll_overlay_padding" />
-  <java-symbol type="dimen" name="fastscroll_thumb_height" />
-  <java-symbol type="dimen" name="fastscroll_thumb_width" />
   <java-symbol type="dimen" name="password_keyboard_spacebar_vertical_correction" />
   <java-symbol type="dimen" name="search_view_preferred_width" />
   <java-symbol type="dimen" name="textview_error_popup_default_width" />
@@ -1091,7 +1088,6 @@
   <java-symbol type="drawable" name="unlock_halo" />
   <java-symbol type="drawable" name="unlock_ring" />
   <java-symbol type="drawable" name="unlock_wave" />
-  <java-symbol type="drawable" name="ic_action_assist_generic" />
   <java-symbol type="drawable" name="notification_bg" />
   <java-symbol type="drawable" name="notification_bg_low" />
   <java-symbol type="drawable" name="notification_template_icon_bg" />
@@ -1179,7 +1175,7 @@
   <java-symbol type="layout" name="tab_content" />
   <java-symbol type="layout" name="tab_indicator_holo" />
   <java-symbol type="layout" name="textview_hint" />
-  <java-symbol type="layout" name="time_picker" />
+  <java-symbol type="layout" name="time_picker_legacy" />
   <java-symbol type="layout" name="time_picker_dialog" />
   <java-symbol type="layout" name="transient_notification" />
   <java-symbol type="layout" name="volume_adjust" />
@@ -1757,4 +1753,55 @@
   <java-symbol type="dimen" name="subtitle_shadow_radius" />
   <java-symbol type="dimen" name="subtitle_shadow_offset" />
   <java-symbol type="dimen" name="subtitle_outline_width" />
+
+  <!-- From the new TimePicker -->
+  <java-symbol type="attr" name="timePickerHeaderBackgroundColor" />
+  <java-symbol type="attr" name="timePickerDialogTheme" />
+  <java-symbol type="attr" name="headerSelectedTextColor" />
+  <java-symbol type="attr" name="headerUnselectedTextColor" />
+  <java-symbol type="attr" name="numbersTextColor" />
+  <java-symbol type="attr" name="numbersBackgroundColor" />
+  <java-symbol type="attr" name="amPmTextColor" />
+  <java-symbol type="attr" name="amPmUnselectedBackgroundColor" />
+  <java-symbol type="attr" name="amPmSelectedBackgroundColor" />
+  <java-symbol type="attr" name="numbersSelectorColor" />
+  <java-symbol type="attr" name="timePickerHeaderTimeLabelTextAppearance" />
+  <java-symbol type="style" name="TextAppearance.Holo.TimePicker.TimeLabel" />
+  <java-symbol type="layout" name="time_picker_holo" />
+  <java-symbol type="layout" name="time_header_label" />
+  <java-symbol type="id" name="time_header" />
+  <java-symbol type="id" name="hours" />
+  <java-symbol type="id" name="minutes" />
+  <java-symbol type="id" name="ampm_label" />
+  <java-symbol type="id" name="radial_picker" />
+  <java-symbol type="id" name="separator" />
+  <java-symbol type="id" name="layout_buttons" />
+  <java-symbol type="id" name="done_button" />
+  <java-symbol type="string" name="done_label" />
+  <java-symbol type="string" name="hour_picker_description" />
+  <java-symbol type="string" name="minute_picker_description" />
+  <java-symbol type="string" name="select_hours" />
+  <java-symbol type="string" name="select_minutes" />
+  <java-symbol type="string" name="time_placeholder" />
+  <java-symbol type="string" name="timepicker_circle_radius_multiplier" />
+  <java-symbol type="string" name="timepicker_circle_radius_multiplier_24HourMode" />
+  <java-symbol type="string" name="timepicker_ampm_circle_radius_multiplier" />
+  <java-symbol type="string" name="deleted_key" />
+  <java-symbol type="string" name="sans_serif" />
+  <java-symbol type="string" name="radial_numbers_typeface" />
+  <java-symbol type="string" name="timepicker_text_size_multiplier_inner" />
+  <java-symbol type="string" name="timepicker_text_size_multiplier_outer" />
+  <java-symbol type="string" name="timepicker_text_size_multiplier_normal" />
+  <java-symbol type="string" name="timepicker_numbers_radius_multiplier_outer" />
+  <java-symbol type="string" name="timepicker_selection_radius_multiplier" />
+  <java-symbol type="string" name="timepicker_numbers_radius_multiplier_inner" />
+  <java-symbol type="string" name="timepicker_numbers_radius_multiplier_normal" />
+  <java-symbol type="string" name="timepicker_transition_mid_radius_multiplier" />
+  <java-symbol type="string" name="timepicker_transition_end_radius_multiplier" />
+  <java-symbol type="color" name="timepicker_default_text_color_holo_light" />
+  <java-symbol type="color" name="timepicker_default_disabled_color_holo_light" />
+  <java-symbol type="color" name="timepicker_default_ampm_unselected_background_color_holo_light" />
+  <java-symbol type="color" name="timepicker_default_ampm_selected_background_color_holo_light" />
+  <java-symbol type="array" name="config_clockTickVibePattern" />
+
 </resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index c8d9fc6..0361df1 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -249,6 +249,7 @@
         <item name="editTextStyle">@android:style/Widget.EditText</item>
         <item name="expandableListViewStyle">@android:style/Widget.ExpandableListView</item>
         <item name="expandableListViewWhiteStyle">@android:style/Widget.ExpandableListView.White</item>
+        <item name="fastScrollStyle">@android:style/Widget.FastScroll</item>
         <item name="galleryStyle">@android:style/Widget.Gallery</item>
         <item name="gestureOverlayViewStyle">@android:style/Widget.GestureOverlayView</item>
         <item name="gridViewStyle">@android:style/Widget.GridView</item>
@@ -296,8 +297,8 @@
         <item name="listPopupWindowStyle">@android:style/Widget.ListPopupWindow</item>
         <item name="popupMenuStyle">@android:style/Widget.PopupMenu</item>
         <item name="activityChooserViewStyle">@android:style/Widget.ActivityChooserView</item>
-
         <item name="mediaRouteButtonStyle">@android:style/Widget.DeviceDefault.MediaRouteButton</item>
+        <item name="fragmentBreadCrumbsStyle">@android:style/Widget.FragmentBreadCrumbs</item>
 
         <!-- Preference styles -->
         <item name="preferenceScreenStyle">@android:style/Preference.PreferenceScreen</item>
@@ -382,6 +383,18 @@
         <!-- TimePicker style -->
         <item name="timePickerStyle">@style/Widget.TimePicker</item>
 
+        <!-- TimePicker background color -->
+        <item name="timePickerHeaderBackgroundColor">@android:color/darker_gray</item>
+
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@android:style/Theme.Dialog.TimePicker</item>
+
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.DatePicker</item>
 
@@ -391,7 +404,6 @@
         <item name="fastScrollPreviewBackgroundLeft">@android:drawable/menu_submenu_background</item>
         <item name="fastScrollOverlayPosition">floating</item>
         <item name="fastScrollTextColor">@android:color/primary_text_dark</item>
-
         <!-- Pointer style -->
         <item name="pointerStyle">@android:style/Pointer</item>
 
@@ -688,7 +700,15 @@
         <item name="textAppearanceListItem">@android:style/TextAppearance.Large.Inverse</item>
         <item name="textAppearanceListItemSmall">@android:style/TextAppearance.Large.Inverse</item>
     </style>
-    
+
+    <!-- Default heme for the TimePicker dialog windows, which is used by the
+         {@link android.app.TimePickerDialog} class. -->
+    <style name="Theme.Dialog.TimePicker">
+        <item name="windowBackground">@android:color/transparent</item>
+        <item name="windowTitleStyle">@android:style/DialogWindowTitle</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
     <!-- Default dark theme for panel windows (on API level 10 and lower).  This removes all
          extraneous window decorations, so you basically have an empty rectangle in which
          to place your content.  It makes the window floating, with a transparent
@@ -1088,6 +1108,7 @@
         <item name="editTextStyle">@android:style/Widget.Holo.EditText</item>
         <item name="expandableListViewStyle">@android:style/Widget.Holo.ExpandableListView</item>
         <item name="expandableListViewWhiteStyle">@android:style/Widget.Holo.ExpandableListView.White</item>
+        <item name="fastScrollStyle">@android:style/Widget.Holo.FastScroll</item>
         <item name="galleryStyle">@android:style/Widget.Holo.Gallery</item>
         <item name="gestureOverlayViewStyle">@android:style/Widget.Holo.GestureOverlayView</item>
         <item name="gridViewStyle">@android:style/Widget.Holo.GridView</item>
@@ -1135,6 +1156,7 @@
         <item name="popupMenuStyle">@android:style/Widget.Holo.PopupMenu</item>
         <item name="stackViewStyle">@android:style/Widget.Holo.StackView</item>
         <item name="activityChooserViewStyle">@android:style/Widget.Holo.ActivityChooserView</item>
+        <item name="fragmentBreadCrumbsStyle">@android:style/Widget.Holo.FragmentBreadCrumbs</item>
 
         <!-- Preference styles -->
         <item name="preferenceScreenStyle">@android:style/Preference.Holo.PreferenceScreen</item>
@@ -1202,6 +1224,18 @@
         <!-- TimePicker style -->
         <item name="timePickerStyle">@style/Widget.Holo.TimePicker</item>
 
+        <!-- TimePicker background color -->
+        <item name="timePickerHeaderBackgroundColor">@android:color/timepicker_default_background_holo_dark</item>
+
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Holo.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.Holo.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@android:style/Theme.Holo.Dialog.TimePicker</item>
+
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.Holo.DatePicker</item>
 
@@ -1403,6 +1437,7 @@
         <item name="editTextStyle">@android:style/Widget.Holo.Light.EditText</item>
         <item name="expandableListViewStyle">@android:style/Widget.Holo.Light.ExpandableListView</item>
         <item name="expandableListViewWhiteStyle">@android:style/Widget.Holo.Light.ExpandableListView.White</item>
+        <item name="fastScrollStyle">@android:style/Widget.Holo.Light.FastScroll</item>
         <item name="galleryStyle">@android:style/Widget.Holo.Light.Gallery</item>
         <item name="gestureOverlayViewStyle">@android:style/Widget.Holo.Light.GestureOverlayView</item>
         <item name="gridViewStyle">@android:style/Widget.Holo.Light.GridView</item>
@@ -1450,6 +1485,7 @@
         <item name="popupMenuStyle">@android:style/Widget.Holo.Light.PopupMenu</item>
         <item name="stackViewStyle">@android:style/Widget.Holo.StackView</item>
         <item name="activityChooserViewStyle">@android:style/Widget.Holo.Light.ActivityChooserView</item>
+        <item name="fragmentBreadCrumbsStyle">@android:style/Widget.Holo.Light.FragmentBreadCrumbs</item>
 
         <!-- Preference styles -->
         <item name="preferenceScreenStyle">@android:style/Preference.Holo.PreferenceScreen</item>
@@ -1517,6 +1553,18 @@
         <!-- TimePicker style -->
         <item name="timePickerStyle">@style/Widget.Holo.Light.TimePicker</item>
 
+        <!-- TimePicker Header background color -->
+        <item name="timePickerHeaderBackgroundColor">@android:color/timepicker_default_background_holo_light</item>
+
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Holo.Light.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.Holo.Light.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@android:style/Theme.Holo.Light.Dialog.TimePicker</item>
+
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.Holo.Light.DatePicker</item>
 
@@ -1729,6 +1777,14 @@
         <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
     </style>
 
+    <!-- Holo theme for the TimePicker dialog windows, which is used by the
+         {@link android.app.TimePickerDialog} class. -->
+    <style name="Theme.Holo.Dialog.TimePicker">
+        <item name="windowBackground">@android:color/transparent</item>
+        <item name="windowTitleStyle">@android:style/DialogWindowTitle.Holo</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
     <!-- Theme for a window that will be displayed either full-screen on
          smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
@@ -1844,6 +1900,14 @@
         <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
     </style>
 
+    <!-- Holo Light theme for the TimePicker dialog windows, which is used by the
+         {@link android.app.TimePickerDialog} class. -->
+    <style name="Theme.Holo.Light.Dialog.TimePicker">
+        <item name="windowBackground">@android:color/transparent</item>
+        <item name="windowTitleStyle">@android:style/DialogWindowTitle.Holo.Light</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
     <!-- Theme for a presentation window on a secondary display. -->
     <style name="Theme.Holo.Light.Dialog.Presentation" parent="@android:style/Theme.Holo.Light.NoActionBar.Fullscreen" >
     </style>
@@ -1861,4 +1925,11 @@
     <style name="Theme.Holo.Wallpaper.NoTitleBar">
         <item name="android:windowNoTitle">true</item>
     </style>
+
+    <!-- Default Quantum Paper theme. -->
+    <style name="Theme.Quantum" parent="@android:style/Theme.Holo.Light">
+        <item name="android:windowContentTransitions">true</item>
+        <item name="android:windowAnimationStyle">@android:style/Animation.Quantum.Activity</item>
+    </style>
+
 </resources>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 721c6b0..19556a1 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -194,6 +194,15 @@
         <!-- TimePicker style -->
         <item name="timePickerStyle">@style/Widget.DeviceDefault.TimePicker</item>
 
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.DeviceDefault.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.DeviceDefault.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@android:style/Theme.DeviceDefault.Dialog.TimePicker</item>
+
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.DeviceDefault.DatePicker</item>
 
@@ -363,6 +372,15 @@
         <!-- TimePicker style -->
         <item name="timePickerStyle">@style/Widget.DeviceDefault.Light.TimePicker</item>
 
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.DeviceDefault.Light.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.DeviceDefault.Light.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@android:style/Theme.DeviceDefault.Light.Dialog.TimePicker</item>
+
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.DeviceDefault.Light.DatePicker</item>
 
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index be55444..73a53cb 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -22,6 +22,7 @@
 	$(call all-java-files-under, EnabledTestApp/src)
 
 LOCAL_DX_FLAGS := --core-library
+LOCAL_AAPT_FLAGS = -0 dat -0 gld
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support android-common frameworks-core-util-lib mockwebserver guava littlemock
 LOCAL_JAVA_LIBRARIES := android.test.runner conscrypt telephony-common
 LOCAL_PACKAGE_NAME := FrameworksCoreTests
diff --git a/core/tests/coretests/assets/backup_mock.dat b/core/tests/coretests/assets/backup_mock.dat
new file mode 100644
index 0000000..f70b573
--- /dev/null
+++ b/core/tests/coretests/assets/backup_mock.dat
Binary files differ
diff --git a/core/tests/coretests/assets/backup_mock.gld b/core/tests/coretests/assets/backup_mock.gld
new file mode 100644
index 0000000..5197c23
--- /dev/null
+++ b/core/tests/coretests/assets/backup_mock.gld
@@ -0,0 +1,4 @@
+key1:
+key2a:YWJjZGVmZw==
+key3bc:YWJjZGVmZ2g=
+key4dad:
diff --git a/core/tests/coretests/assets/backup_real.dat b/core/tests/coretests/assets/backup_real.dat
new file mode 100644
index 0000000..2262568
--- /dev/null
+++ b/core/tests/coretests/assets/backup_real.dat
Binary files differ
diff --git a/core/tests/coretests/assets/backup_real.gld b/core/tests/coretests/assets/backup_real.gld
new file mode 100644
index 0000000..ef28f9b
--- /dev/null
+++ b/core/tests/coretests/assets/backup_real.gld
@@ -0,0 +1,3 @@
+CAEYLw:CC8QABoIR0VMIFN0dWIgnP//////////ASgBMAJAAUgBapgBI0ludGVudDthY3Rpb249YW5kcm9pZC5pbnRlbnQuYWN0aW9uLk1BSU47Y2F0ZWdvcnk9YW5kcm9pZC5pbnRlbnQuY2F0ZWdvcnkuTEFVTkNIRVI7bGF1bmNoRmxhZ3M9MHgxMDIwMDAwMDtjb21wb25lbnQ9Y29tLmdvb2dsZS5hbmRyb2lkLmdlbC8uU3R1YkFwcDtlbmQ=
+CAEYLQ:
+CAEYLA:
diff --git a/core/tests/coretests/src/android/app/backup/BackupDataTest.java b/core/tests/coretests/src/android/app/backup/BackupDataTest.java
new file mode 100644
index 0000000..0c204e0
--- /dev/null
+++ b/core/tests/coretests/src/android/app/backup/BackupDataTest.java
@@ -0,0 +1,291 @@
+/*
+ * 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.app.backup;
+
+import android.app.backup.BackupDataInput;
+import android.app.backup.BackupDataOutput;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.test.AndroidTestCase;
+import android.test.InstrumentationTestCase;
+import android.util.Base64;
+import android.util.Log;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.Exception;
+import java.nio.ByteBuffer;
+
+public class BackupDataTest extends AndroidTestCase {
+    private static final String KEY1 = "key1";
+    private static final String KEY2 = "key2a";
+    private static final String KEY3 = "key3bc";
+    private static final String KEY4 = "key4dad";  // variable key lengths to test padding
+    private static final String[] KEYS = {KEY1, KEY2, KEY3, KEY4};
+
+    private static final String DATA1 = "abcdef";
+    private static final String DATA2 = "abcdefg";
+    private static final String DATA3 = "abcdefgh";
+    private static final String DATA4 = "abcdeffhi"; //variable data lengths to test padding
+    private static final String[] DATA = {DATA1, DATA2, DATA3, DATA4};
+    private static final String TAG = "BackupDataTest";
+
+    private File mFile;
+    private ParcelFileDescriptor mDataFile;
+    private File mDirectory;
+    private Bundle mStatusBundle;
+    private AssetManager mAssets;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDirectory = new File(Environment.getExternalStorageDirectory(), "test_data");
+        mDirectory.mkdirs();
+        mAssets = mContext.getAssets();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        if (mDataFile != null) {
+            mDataFile.close();
+        }
+    }
+
+    public void testSingle() throws IOException {
+        mFile = new File(mDirectory, "backup_mixed_sinlge.dat");
+        openForWriting();
+        BackupDataOutput bdo = new BackupDataOutput(mDataFile.getFileDescriptor());
+
+        writeEntity(bdo, KEY1, DATA1.getBytes());
+
+        mDataFile.close();
+        openForReading();
+
+        BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor());
+        int count = 0;
+        while (bdi.readNextHeader()) {
+            readAndVerifyEntity(bdi, KEY1, DATA1.getBytes());
+            count++;
+        }
+        assertEquals("only one entity in this stream", 1, count);
+    }
+
+    public void testMultiple() throws IOException {
+        mFile = new File(mDirectory, "backup_multiple_test.dat");
+        openForWriting();
+        BackupDataOutput bdo = new BackupDataOutput(mDataFile.getFileDescriptor());
+
+        for(int i = 0; i < KEYS.length; i++) {
+            writeEntity(bdo, KEYS[i], DATA[i].getBytes());
+        }
+
+        mDataFile.close();
+        openForReading();
+
+        BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor());
+        int count = 0;
+        while (bdi.readNextHeader()) {
+            readAndVerifyEntity(bdi, KEYS[count], DATA[count].getBytes());
+            count++;
+        }
+        assertEquals("four entities in this stream", KEYS.length, count);
+    }
+
+    public void testDelete() throws IOException {
+        mFile = new File(mDirectory, "backup_delete_test.dat");
+        openForWriting();
+        BackupDataOutput bdo = new BackupDataOutput(mDataFile.getFileDescriptor());
+
+        for(int i = 0; i < KEYS.length; i++) {
+            deleteEntity(bdo, KEYS[i]);
+        }
+
+        mDataFile.close();
+        openForReading();
+
+        BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor());
+        int count = 0;
+        while (bdi.readNextHeader()) {
+            readAndVerifyDeletedEntity(bdi, KEYS[count]);
+            count++;
+        }
+        assertEquals("four deletes in this stream", KEYS.length, count);
+    }
+
+    public void testMixed() throws IOException {
+        mFile = new File(mDirectory, "backup_mixed_test.dat");
+        openForWriting();
+
+        BackupDataOutput bdo = new BackupDataOutput(mDataFile.getFileDescriptor());
+
+        int i = 0;
+        deleteEntity(bdo, KEYS[i]); i++;
+        writeEntity(bdo, KEYS[i], DATA[i].getBytes()); i++;
+        writeEntity(bdo, KEYS[i], DATA[i].getBytes()); i++;
+        deleteEntity(bdo, KEYS[i]); i++;
+
+        mDataFile.close();
+        openForReading();
+
+        BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor());
+        int out = 0;
+        assertTrue(bdi.readNextHeader());
+        readAndVerifyDeletedEntity(bdi, KEYS[out]); out++;
+        assertTrue(bdi.readNextHeader());
+        readAndVerifyEntity(bdi, KEYS[out], DATA[out].getBytes()); out++;
+        assertTrue(bdi.readNextHeader());
+        readAndVerifyEntity(bdi, KEYS[out], DATA[out].getBytes()); out++;
+        assertTrue(bdi.readNextHeader());
+        readAndVerifyDeletedEntity(bdi, KEYS[out]); out++;
+        assertFalse("four items in this stream",
+                bdi.readNextHeader());
+    }
+
+    public void testReadMockData() throws IOException {
+        copyAssetToFile("backup_mock.dat", "backup_read_mock_test.dat");
+
+        openForReading();
+        BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor());
+        BufferedReader truth = new BufferedReader(new InputStreamReader(
+                mAssets.openFd("backup_mock.gld").createInputStream()));
+        while( bdi.readNextHeader()) {
+            String[] expected = truth.readLine().split(":");
+            byte[] expectedBytes = null;
+            if (expected.length > 1) {
+                expectedBytes = Base64.decode(expected[1], Base64.DEFAULT);
+            }
+            String key = bdi.getKey();
+            int dataSize = bdi.getDataSize();
+
+            assertEquals("wrong key", expected[0], key);
+            assertEquals("wrong length for key " + key,
+                    (expectedBytes == null ? -1: expectedBytes.length), dataSize);
+            if (dataSize != -1) {
+                byte[] buffer = new byte[dataSize];
+                bdi.readEntityData(buffer, 0, dataSize);
+                assertEquals("wrong data for key " + key, expected[1],
+                        Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
+            }
+        }
+        assertNull("there are unused entries in the golden file", truth.readLine());
+    }
+
+    public void testReadRealData() throws IOException {
+        copyAssetToFile("backup_real.dat", "backup_read_real_test.dat");
+
+        openForReading();
+        BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor());
+        BufferedReader truth = new BufferedReader(new InputStreamReader(
+                mAssets.openFd("backup_real.gld").createInputStream()));
+
+        while(bdi.readNextHeader()) {
+            String[] expected = truth.readLine().split(":");
+            byte[] expectedBytes = null;
+            if (expected.length > 1) {
+                expectedBytes = Base64.decode(expected[1], Base64.DEFAULT);
+            }
+            String key = bdi.getKey();
+            int dataSize = bdi.getDataSize();
+
+            assertEquals("wrong key", expected[0], key);
+            assertEquals("wrong length for key " + key,
+                    (expectedBytes == null ? -1: expectedBytes.length), dataSize);
+            if (dataSize != -1) {
+                byte[] buffer = new byte[dataSize];
+                bdi.readEntityData(buffer, 0, dataSize);
+                assertEquals("wrong data for key " + key, expected[1],
+                        Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
+            }
+        }
+        assertNull("there are unused entries in the golden file", truth.readLine());
+    }
+
+    private void copyAssetToFile(String source, String destination) throws IOException {
+        mFile = new File(mDirectory, destination);
+        openForWriting();
+        FileInputStream fileInputStream = mAssets.openFd(source).createInputStream();
+        FileOutputStream fileOutputStream = new FileOutputStream(mDataFile.getFileDescriptor());
+        byte[] copybuffer = new byte[1024];
+        int numBytes = fileInputStream.read(copybuffer);
+        fileOutputStream.write(copybuffer, 0, numBytes);
+        fileOutputStream.close();
+    }
+
+    private void openForWriting() throws FileNotFoundException {
+        mDataFile = ParcelFileDescriptor.open(mFile,
+                ParcelFileDescriptor.MODE_WRITE_ONLY |
+                        ParcelFileDescriptor.MODE_CREATE |
+                        ParcelFileDescriptor.MODE_TRUNCATE);  // Make an empty file if necessary
+    }
+
+    private void openForReading() throws FileNotFoundException {
+        mDataFile = ParcelFileDescriptor.open(mFile,
+                ParcelFileDescriptor.MODE_READ_ONLY |
+                        ParcelFileDescriptor.MODE_CREATE);  // Make an empty file if necessary
+    }
+
+    private void writeEntity(BackupDataOutput bdo, String key, byte[] data) throws IOException {
+        int status = bdo.writeEntityHeader(key, data.length);
+        // documentation says "number of bytes written" but that's not what we get:
+        assertEquals(0, status);
+
+        status = bdo.writeEntityData(data, data.length);
+        // documentation says "number of bytes written" but that's not what we get:
+        assertEquals(0, status);
+    }
+
+    private void deleteEntity(BackupDataOutput bdo, String key) throws IOException {
+        int status = bdo.writeEntityHeader(key, -1);
+        // documentation says "number of bytes written" but that's not what we get:
+        assertEquals(0, status);
+    }
+
+    private void readAndVerifyEntity(BackupDataInput bdi, String expectedKey, byte[] expectedData)
+            throws IOException {
+        assertEquals("Key mismatch",
+                expectedKey, bdi.getKey());
+        assertEquals("data size mismatch",
+                expectedData.length, bdi.getDataSize());
+        byte[] data = new byte[bdi.getDataSize()];
+        bdi.readEntityData(data, 0, bdi.getDataSize());
+        assertEquals("payload size is wrong",
+                expectedData.length, data.length);
+        for (int i = 0; i < data.length; i++) {
+            assertEquals("payload mismatch",
+                    expectedData[i], data[i]);
+        }
+    }
+    private void readAndVerifyDeletedEntity(BackupDataInput bdi, String expectedKey)
+            throws IOException {
+        assertEquals("Key mismatch",
+                expectedKey, bdi.getKey());
+        assertEquals("deletion mis-reported",
+                -1, bdi.getDataSize());
+    }
+}
diff --git a/core/tests/coretests/src/android/net/LinkAddressTest.java b/core/tests/coretests/src/android/net/LinkAddressTest.java
new file mode 100644
index 0000000..389ff4d
--- /dev/null
+++ b/core/tests/coretests/src/android/net/LinkAddressTest.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import android.net.LinkAddress;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Tests for {@link LinkAddress}.
+ */
+public class LinkAddressTest extends AndroidTestCase {
+
+    private static final String V4 = "192.0.2.1";
+    private static final String V6 = "2001:db8::1";
+    private static final InetAddress V4_ADDRESS = NetworkUtils.numericToInetAddress(V4);
+    private static final InetAddress V6_ADDRESS = NetworkUtils.numericToInetAddress(V6);
+
+    public void testConstructors() throws SocketException {
+        LinkAddress address;
+
+        // Valid addresses work as expected.
+        address = new LinkAddress(V4_ADDRESS, 25);
+        assertEquals(V4_ADDRESS, address.getAddress());
+        assertEquals(25, address.getNetworkPrefixLength());
+
+        address = new LinkAddress(V6_ADDRESS, 127);
+        assertEquals(V6_ADDRESS, address.getAddress());
+        assertEquals(127, address.getNetworkPrefixLength());
+
+        address = new LinkAddress(V6 + "/64");
+        assertEquals(V6_ADDRESS, address.getAddress());
+        assertEquals(64, address.getNetworkPrefixLength());
+
+        address = new LinkAddress(V4 + "/23");
+        assertEquals(V4_ADDRESS, address.getAddress());
+        assertEquals(23, address.getNetworkPrefixLength());
+
+        // InterfaceAddress doesn't have a constructor. Fetch some from an interface.
+        List<InterfaceAddress> addrs = NetworkInterface.getByName("lo").getInterfaceAddresses();
+
+        // We expect to find 127.0.0.1/8 and ::1/128, in any order.
+        LinkAddress ipv4Loopback, ipv6Loopback;
+        assertEquals(2, addrs.size());
+        if (addrs.get(0).getAddress() instanceof Inet4Address) {
+            ipv4Loopback = new LinkAddress(addrs.get(0));
+            ipv6Loopback = new LinkAddress(addrs.get(1));
+        } else {
+            ipv4Loopback = new LinkAddress(addrs.get(1));
+            ipv6Loopback = new LinkAddress(addrs.get(0));
+        }
+
+        assertEquals(NetworkUtils.numericToInetAddress("127.0.0.1"), ipv4Loopback.getAddress());
+        assertEquals(8, ipv4Loopback.getNetworkPrefixLength());
+
+        assertEquals(NetworkUtils.numericToInetAddress("::1"), ipv6Loopback.getAddress());
+        assertEquals(128, ipv6Loopback.getNetworkPrefixLength());
+
+        // Null addresses are rejected.
+        try {
+            address = new LinkAddress(null, 24);
+            fail("Null InetAddress should cause IllegalArgumentException");
+        } catch(IllegalArgumentException expected) {}
+
+        try {
+            address = new LinkAddress((String) null);
+            fail("Null string should cause IllegalArgumentException");
+        } catch(IllegalArgumentException expected) {}
+
+        try {
+            address = new LinkAddress((InterfaceAddress) null);
+            fail("Null string should cause NullPointerException");
+        } catch(NullPointerException expected) {}
+
+        // Invalid prefix lengths are rejected.
+        try {
+            address = new LinkAddress(V4 + "/-1");
+            fail("Negative IPv4 prefix length should cause IllegalArgumentException");
+        } catch(IllegalArgumentException expected) {}
+
+        try {
+            address = new LinkAddress(V6 + "/-1");
+            fail("Negative IPv6 prefix length should cause IllegalArgumentException");
+        } catch(IllegalArgumentException expected) {}
+
+        try {
+            address = new LinkAddress(V4 + "/33");
+            fail("/35 IPv4 prefix length should cause IllegalArgumentException");
+        } catch(IllegalArgumentException expected) {}
+
+        try {
+            address = new LinkAddress(V6 + "/129");
+            fail("/129 IPv6 prefix length should cause IllegalArgumentException");
+        } catch(IllegalArgumentException expected) {}
+    }
+
+    private void assertLinkAddressesEqual(LinkAddress l1, LinkAddress l2) {
+        assertTrue(l1 + " unexpectedly not equal to " + l2, l1.equals(l2));
+        assertTrue(l2 + " unexpectedly not equal to " + l1, l2.equals(l1));
+        assertEquals(l1.hashCode(), l2.hashCode());
+    }
+
+    private void assertLinkAddressesNotEqual(LinkAddress l1, LinkAddress l2) {
+        assertFalse(l1 + " unexpectedly equal to " + l2, l1.equals(l2));
+        assertFalse(l2 + " unexpectedly equal to " + l1, l2.equals(l1));
+    }
+
+    public void testEquals() {
+        LinkAddress l1, l2;
+
+        l1 = new LinkAddress("2001:db8::1/64");
+        l2 = new LinkAddress("2001:db8::1/64");
+        assertLinkAddressesEqual(l1, l2);
+
+        l2 = new LinkAddress("2001:db8::1/65");
+        assertLinkAddressesNotEqual(l1, l2);
+        l2 = new LinkAddress("2001:db8::2/64");
+        assertLinkAddressesNotEqual(l1, l2);
+
+        l1 = new LinkAddress("192.0.2.1/24");
+        l2 = new LinkAddress("192.0.2.1/24");
+        assertLinkAddressesEqual(l1, l2);
+
+        l2 = new LinkAddress("192.0.2.1/23");
+        assertLinkAddressesNotEqual(l1, l2);
+        l2 = new LinkAddress("192.0.2.2/24");
+        assertLinkAddressesNotEqual(l1, l2);
+
+        // Addresses with the same start or end bytes aren't equal between families.
+        l1 = new LinkAddress("255.255.255.255/24");
+        l2 = new LinkAddress("ffff:ffff::/24");
+        assertLinkAddressesNotEqual(l1, l2);
+        l2 = new LinkAddress("::ffff:ffff/24");
+        assertLinkAddressesNotEqual(l1, l2);
+
+        // Because we use InetAddress, an IPv4 address is equal to its IPv4-mapped address.
+        // TODO: Investigate fixing this.
+        String addressString = V4 + "/24";
+        l1 = new LinkAddress(addressString);
+        l2 = new LinkAddress("::ffff:" + addressString);
+        assertLinkAddressesEqual(l1, l2);
+    }
+
+    public void testHashCode() {
+        LinkAddress l;
+
+        l = new LinkAddress(V4_ADDRESS, 23);
+        assertEquals(-982787, l.hashCode());
+
+        l = new LinkAddress(V4_ADDRESS, 27);
+        assertEquals(-982743, l.hashCode());
+
+        l = new LinkAddress(V6_ADDRESS, 64);
+        assertEquals(1076522926, l.hashCode());
+
+        l = new LinkAddress(V6_ADDRESS, 128);
+        assertEquals(1076523630, l.hashCode());
+    }
+
+    private LinkAddress passThroughParcel(LinkAddress l) {
+        Parcel p = Parcel.obtain();
+        LinkAddress l2 = null;
+        try {
+            l.writeToParcel(p, 0);
+            p.setDataPosition(0);
+            l2 = LinkAddress.CREATOR.createFromParcel(p);
+        } finally {
+            p.recycle();
+        }
+        assertNotNull(l2);
+        return l2;
+    }
+
+    private void assertParcelingIsLossless(LinkAddress l) {
+      LinkAddress l2 = passThroughParcel(l);
+      assertEquals(l, l2);
+    }
+
+    public void testParceling() {
+        LinkAddress l;
+
+        l = new LinkAddress(V6_ADDRESS, 64);
+        assertParcelingIsLossless(l);
+
+        l = new LinkAddress(V4 + "/28");
+        assertParcelingIsLossless(l);
+    }
+}
diff --git a/core/tests/coretests/src/android/net/SSLSessionCacheTest.java b/core/tests/coretests/src/android/net/SSLSessionCacheTest.java
new file mode 100644
index 0000000..be19303
--- /dev/null
+++ b/core/tests/coretests/src/android/net/SSLSessionCacheTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.net;
+
+import com.android.org.conscrypt.ClientSessionContext;
+import com.android.org.conscrypt.SSLClientSessionCache;
+
+import com.google.testing.littlemock.LittleMock;
+
+import junit.framework.TestCase;
+
+import java.security.KeyManagementException;
+import java.security.SecureRandom;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLContextSpi;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+public class SSLSessionCacheTest extends TestCase {
+
+    public void testInstall_compatibleContext() throws Exception {
+        final SSLContext ctx = SSLContext.getDefault();
+        final SSLClientSessionCache mock = LittleMock.mock(SSLClientSessionCache.class);
+        final ClientSessionContext clientCtx = (ClientSessionContext) ctx.getClientSessionContext();
+
+        try {
+            SSLSessionCache.install(new SSLSessionCache(mock), ctx);
+            clientCtx.getSession("www.foogle.com", 443);
+            LittleMock.verify(mock).getSessionData(LittleMock.anyString(), LittleMock.anyInt());
+        } finally {
+            // Restore cacheless behaviour.
+            SSLSessionCache.install(null, ctx);
+            clientCtx.getSession("www.foogle.com", 443);
+            LittleMock.verifyNoMoreInteractions(mock);
+        }
+    }
+
+    public void testInstall_incompatibleContext() {
+        try {
+            SSLSessionCache.install(
+                    new SSLSessionCache(LittleMock.mock(SSLClientSessionCache.class)),
+                    new FakeSSLContext());
+            fail();
+        } catch (IllegalArgumentException expected) {}
+    }
+
+    static final class FakeSSLContext extends SSLContext {
+        protected FakeSSLContext() {
+            super(new FakeSSLContextSpi(), null, "test");
+        }
+    }
+
+    static final class FakeSSLContextSpi extends SSLContextSpi {
+        @Override
+        protected void engineInit(KeyManager[] keyManagers, TrustManager[] trustManagers,
+                SecureRandom secureRandom) throws KeyManagementException {
+        }
+
+        @Override
+        protected SSLSocketFactory engineGetSocketFactory() {
+            return null;
+        }
+
+        @Override
+        protected SSLServerSocketFactory engineGetServerSocketFactory() {
+            return null;
+        }
+
+        @Override
+        protected SSLEngine engineCreateSSLEngine(String s, int i) {
+            return null;
+        }
+
+        @Override
+        protected SSLEngine engineCreateSSLEngine() {
+            return null;
+        }
+
+        @Override
+        protected SSLSessionContext engineGetServerSessionContext() {
+            return null;
+        }
+
+        @Override
+        protected SSLSessionContext engineGetClientSessionContext() {
+            return LittleMock.mock(SSLSessionContext.class);
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/text/HtmlTest.java b/core/tests/coretests/src/android/text/HtmlTest.java
deleted file mode 100644
index b2298f7..0000000
--- a/core/tests/coretests/src/android/text/HtmlTest.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * 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 android.text;
-
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.graphics.Typeface;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.style.ForegroundColorSpan;
-import android.text.style.QuoteSpan;
-import android.text.style.StrikethroughSpan;
-import android.text.style.StyleSpan;
-import android.text.style.SubscriptSpan;
-import android.text.style.SuperscriptSpan;
-import android.text.style.TextAppearanceSpan;
-import android.text.style.TypefaceSpan;
-import android.text.style.URLSpan;
-import android.text.style.UnderlineSpan;
-
-import junit.framework.TestCase;
-
-public class HtmlTest extends TestCase {
-
-    @SmallTest
-    public void testSingleTagOnWhileString() {
-        Spanned spanned = Html.fromHtml("<b>hello</b>");
-        Object[] spans = spanned.getSpans(-1, 100, Object.class);
-        assertEquals(1, spans.length);
-        Object span = spans[0];
-        assertEquals(0, spanned.getSpanStart(span));
-        assertEquals(5, spanned.getSpanEnd(span));
-    }
-
-    @SmallTest
-    public void testEmptyFontTag() {
-        Spanned spanned = Html.fromHtml("Hello <font color=\"#ff00ff00\"></font>");
-        Object[] spans = spanned.getSpans(0, 100, Object.class);
-        // TODO: figure out what the spans should be after the crashes are fixed and assert them.
-    }
-
-    /** Tests that the parser can handle mal-formed HTML. */
-    @SmallTest
-    public void testBadHtml() {
-        Spanned spanned = Html.fromHtml("Hello <b>b<i>bi</b>i</i>");
-        Object[] spans = spanned.getSpans(0, 100, Object.class);
-        assertEquals(Typeface.ITALIC, ((StyleSpan) spans[0]).getStyle());
-        assertEquals(7, spanned.getSpanStart(spans[0]));
-        assertEquals(9, spanned.getSpanEnd(spans[0]));
-        assertEquals(Typeface.BOLD, ((StyleSpan) spans[1]).getStyle());
-        assertEquals(6, spanned.getSpanStart(spans[1]));
-        assertEquals(9, spanned.getSpanEnd(spans[1]));
-        assertEquals(Typeface.ITALIC, ((StyleSpan) spans[2]).getStyle());
-        assertEquals(9, spanned.getSpanStart(spans[2]));
-        assertEquals(10, spanned.getSpanEnd(spans[2]));
-    }
-
-    @SmallTest
-    public void testSymbols() {
-        String spanned = Html.fromHtml("&copy; &gt; &lt").toString();
-        assertEquals("\u00a9 > <", spanned);
-    }
-    
-    @SmallTest
-    public void testColor() throws Exception {
-        Spanned s;
-        ForegroundColorSpan[] colors;
-
-        s = Html.fromHtml("<font color=\"#00FF00\">something</font>");
-        colors = s.getSpans(0, s.length(), ForegroundColorSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(0xFF00FF00, colors[0].getForegroundColor());
-
-        s = Html.fromHtml("<font color=\"navy\">something</font>");
-        colors = s.getSpans(0, s.length(), ForegroundColorSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(0xFF000080, colors[0].getForegroundColor());
-
-        s = Html.fromHtml("<font color=\"gibberish\">something</font>");
-        colors = s.getSpans(0, s.length(), ForegroundColorSpan.class);
-        assertEquals(0, colors.length);
-    }
-
-    @SmallTest
-    public void testResourceColor() throws Exception {
-        ColorStateList c =
-                Resources.getSystem().getColorStateList(android.R.color.primary_text_dark);
-        Spanned s;
-        TextAppearanceSpan[] colors;
-
-        s = Html.fromHtml("<font color=\"@android:color/primary_text_dark\">something</font>");
-        colors = s.getSpans(0, s.length(), TextAppearanceSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(c.toString(), colors[0].getTextColor().toString());
-
-        s = Html.fromHtml("<font color=\"@android:primary_text_dark\">something</font>");
-        colors = s.getSpans(0, s.length(), TextAppearanceSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(c.toString(), colors[0].getTextColor().toString());
-
-        s = Html.fromHtml("<font color=\"@color/primary_text_dark\">something</font>");
-        colors = s.getSpans(0, s.length(), TextAppearanceSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(c.toString(), colors[0].getTextColor().toString());
-
-        s = Html.fromHtml("<font color=\"@primary_text_dark\">something</font>");
-        colors = s.getSpans(0, s.length(), TextAppearanceSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(c.toString(), colors[0].getTextColor().toString());
-
-        s = Html.fromHtml("<font color=\"@" + android.R.color.primary_text_dark
-                + "\">something</font>");
-        colors = s.getSpans(0, s.length(), TextAppearanceSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(c.toString(), colors[0].getTextColor().toString());
-
-        s = Html.fromHtml("<font color=\"gibberish\">something</font>");
-        colors = s.getSpans(0, s.length(), TextAppearanceSpan.class);
-        assertEquals(colors.length, 0);
-    }
-
-    @SmallTest
-    public void testParagraphs() throws Exception {
-        SpannableString s;
-
-        s = new SpannableString("Hello world");
-        assertEquals(Html.toHtml(s), "<p>Hello world</p>\n");
-
-        s = new SpannableString("Hello world\nor something");
-        assertEquals(Html.toHtml(s), "<p>Hello world<br>\nor something</p>\n");
-
-        s = new SpannableString("Hello world\n\nor something");
-        assertEquals(Html.toHtml(s), "<p>Hello world</p>\n<p>or something</p>\n");
-
-        s = new SpannableString("Hello world\n\n\nor something");
-        assertEquals(Html.toHtml(s), "<p>Hello world<br></p>\n<p>or something</p>\n");
-
-        assertEquals("foo\nbar", Html.fromHtml("foo<br>bar").toString());
-        assertEquals("foo\nbar", Html.fromHtml("foo<br>\nbar").toString());
-        assertEquals("foo\nbar", Html.fromHtml("foo<br>\n \nbar").toString());
-    }
-
-    @SmallTest
-    public void testBlockquote() throws Exception {
-        SpannableString s;
-
-        s = new SpannableString("Hello world");
-        s.setSpan(new QuoteSpan(), 0, s.length(), Spannable.SPAN_PARAGRAPH);
-        assertEquals(Html.toHtml(s), "<blockquote><p>Hello world</p>\n</blockquote>\n");
-
-        s = new SpannableString("Hello\n\nworld");
-        s.setSpan(new QuoteSpan(), 0, 7, Spannable.SPAN_PARAGRAPH);
-        assertEquals(Html.toHtml(s), "<blockquote><p>Hello</p>\n</blockquote>\n<p>world</p>\n");
-    }
-
-    @SmallTest
-    public void testEntities() throws Exception {
-        SpannableString s;
-
-        s = new SpannableString("Hello <&> world");
-        assertEquals(Html.toHtml(s), "<p>Hello &lt;&amp;&gt; world</p>\n");
-
-        s = new SpannableString("Hello \u03D5 world");
-        assertEquals(Html.toHtml(s), "<p>Hello &#981; world</p>\n");
-
-        s = new SpannableString("Hello  world");
-        assertEquals(Html.toHtml(s), "<p>Hello&nbsp; world</p>\n");
-    }
-
-    @SmallTest
-    public void testMarkup() throws Exception {
-        SpannableString s;
-
-        s = new SpannableString("Hello bold world");
-        s.setSpan(new StyleSpan(Typeface.BOLD), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <b>bold</b> world</p>\n");
-
-        s = new SpannableString("Hello italic world");
-        s.setSpan(new StyleSpan(Typeface.ITALIC), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <i>italic</i> world</p>\n");
-
-        s = new SpannableString("Hello monospace world");
-        s.setSpan(new TypefaceSpan("monospace"), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <tt>monospace</tt> world</p>\n");
-
-        s = new SpannableString("Hello superscript world");
-        s.setSpan(new SuperscriptSpan(), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <sup>superscript</sup> world</p>\n");
-
-        s = new SpannableString("Hello subscript world");
-        s.setSpan(new SubscriptSpan(), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <sub>subscript</sub> world</p>\n");
-
-        s = new SpannableString("Hello underline world");
-        s.setSpan(new UnderlineSpan(), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <u>underline</u> world</p>\n");
-
-        s = new SpannableString("Hello struck world");
-        s.setSpan(new StrikethroughSpan(), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <strike>struck</strike> world</p>\n");
-
-        s = new SpannableString("Hello linky world");
-        s.setSpan(new URLSpan("http://www.google.com"), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s),
-                     "<p>Hello <a href=\"http://www.google.com\">linky</a> world</p>\n");
-    }
-
-    @SmallTest
-    public void testImg() throws Exception {
-        Spanned s;
-
-        s = Html.fromHtml("yes<img src=\"http://example.com/foo.gif\">no");
-
-        assertEquals("<p>yes<img src=\"http://example.com/foo.gif\">no</p>\n",
-                     Html.toHtml(s));
-    }
-
-    @SmallTest
-    public void testUtf8() throws Exception {
-        Spanned s;
-
-        s = Html.fromHtml("<p>\u0124\u00eb\u0142\u0142o, world!</p>");
-        assertEquals("<p>&#292;&#235;&#322;&#322;o, world!</p>\n", Html.toHtml(s));
-    }
-
-}
diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl
index 1413319..2042345 100644
--- a/data/keyboards/Generic.kl
+++ b/data/keyboards/Generic.kl
@@ -423,3 +423,16 @@
 axis 0x0a BRAKE
 axis 0x10 HAT_X
 axis 0x11 HAT_Y
+
+# LEDs
+led 0x00 NUM_LOCK
+led 0x01 CAPS_LOCK
+led 0x02 SCROLL_LOCK
+led 0x03 COMPOSE
+led 0x04 KANA
+led 0x05 SLEEP
+led 0x06 SUSPEND
+led 0x07 MUTE
+led 0x08 MISC
+led 0x09 MAIL
+led 0x0a CHARGING
diff --git a/data/sounds/effects/ogg/KeypressInvalid_48k.ogg b/data/sounds/effects/ogg/KeypressInvalid_48k.ogg
index 24935ad..d1843a7 100644
--- a/data/sounds/effects/ogg/KeypressInvalid_48k.ogg
+++ b/data/sounds/effects/ogg/KeypressInvalid_48k.ogg
Binary files differ
diff --git a/docs/downloads/training/BitmapFun.zip b/docs/downloads/training/BitmapFun.zip
index 8668897..d3dd02a 100644
--- a/docs/downloads/training/BitmapFun.zip
+++ b/docs/downloads/training/BitmapFun.zip
Binary files differ
diff --git a/docs/downloads/training/OpenGLES.zip b/docs/downloads/training/OpenGLES.zip
index 862ae1f..5bdfee3 100644
--- a/docs/downloads/training/OpenGLES.zip
+++ b/docs/downloads/training/OpenGLES.zip
Binary files differ
diff --git a/docs/html-intl/es/training/monitoring-device-state/battery-monitoring.jd b/docs/html-intl/intl/es/training/monitoring-device-state/battery-monitoring.jd
similarity index 100%
rename from docs/html-intl/es/training/monitoring-device-state/battery-monitoring.jd
rename to docs/html-intl/intl/es/training/monitoring-device-state/battery-monitoring.jd
diff --git a/docs/html-intl/es/training/monitoring-device-state/connectivity-monitoring.jd b/docs/html-intl/intl/es/training/monitoring-device-state/connectivity-monitoring.jd
similarity index 100%
rename from docs/html-intl/es/training/monitoring-device-state/connectivity-monitoring.jd
rename to docs/html-intl/intl/es/training/monitoring-device-state/connectivity-monitoring.jd
diff --git a/docs/html-intl/es/training/monitoring-device-state/docking-monitoring.jd b/docs/html-intl/intl/es/training/monitoring-device-state/docking-monitoring.jd
similarity index 100%
rename from docs/html-intl/es/training/monitoring-device-state/docking-monitoring.jd
rename to docs/html-intl/intl/es/training/monitoring-device-state/docking-monitoring.jd
diff --git a/docs/html-intl/es/training/monitoring-device-state/index.jd b/docs/html-intl/intl/es/training/monitoring-device-state/index.jd
similarity index 100%
rename from docs/html-intl/es/training/monitoring-device-state/index.jd
rename to docs/html-intl/intl/es/training/monitoring-device-state/index.jd
diff --git a/docs/html-intl/es/training/monitoring-device-state/manifest-receivers.jd b/docs/html-intl/intl/es/training/monitoring-device-state/manifest-receivers.jd
similarity index 100%
rename from docs/html-intl/es/training/monitoring-device-state/manifest-receivers.jd
rename to docs/html-intl/intl/es/training/monitoring-device-state/manifest-receivers.jd
diff --git a/docs/html-intl/es/training/multiscreen/adaptui.jd b/docs/html-intl/intl/es/training/multiscreen/adaptui.jd
similarity index 100%
rename from docs/html-intl/es/training/multiscreen/adaptui.jd
rename to docs/html-intl/intl/es/training/multiscreen/adaptui.jd
diff --git a/docs/html-intl/es/training/multiscreen/index.jd b/docs/html-intl/intl/es/training/multiscreen/index.jd
similarity index 100%
rename from docs/html-intl/es/training/multiscreen/index.jd
rename to docs/html-intl/intl/es/training/multiscreen/index.jd
diff --git a/docs/html-intl/es/training/multiscreen/screendensities.jd b/docs/html-intl/intl/es/training/multiscreen/screendensities.jd
similarity index 100%
rename from docs/html-intl/es/training/multiscreen/screendensities.jd
rename to docs/html-intl/intl/es/training/multiscreen/screendensities.jd
diff --git a/docs/html-intl/es/training/multiscreen/screensizes.jd b/docs/html-intl/intl/es/training/multiscreen/screensizes.jd
similarity index 100%
rename from docs/html-intl/es/training/multiscreen/screensizes.jd
rename to docs/html-intl/intl/es/training/multiscreen/screensizes.jd
diff --git a/docs/html-intl/ja/guide/publishing/app-signing.jd b/docs/html-intl/intl/ja/guide/publishing/app-signing.jd
similarity index 100%
rename from docs/html-intl/ja/guide/publishing/app-signing.jd
rename to docs/html-intl/intl/ja/guide/publishing/app-signing.jd
diff --git a/docs/html-intl/ja/guide/publishing/preparing.jd b/docs/html-intl/intl/ja/guide/publishing/preparing.jd
similarity index 100%
rename from docs/html-intl/ja/guide/publishing/preparing.jd
rename to docs/html-intl/intl/ja/guide/publishing/preparing.jd
diff --git a/docs/html-intl/ja/guide/publishing/versioning.jd b/docs/html-intl/intl/ja/guide/publishing/versioning.jd
similarity index 100%
rename from docs/html-intl/ja/guide/publishing/versioning.jd
rename to docs/html-intl/intl/ja/guide/publishing/versioning.jd
diff --git a/docs/html-intl/ja/guide/topics/fundamentals.jd b/docs/html-intl/intl/ja/guide/topics/fundamentals.jd
similarity index 100%
rename from docs/html-intl/ja/guide/topics/fundamentals.jd
rename to docs/html-intl/intl/ja/guide/topics/fundamentals.jd
diff --git a/docs/html-intl/ja/training/monitoring-device-state/battery-monitoring.jd b/docs/html-intl/intl/ja/training/monitoring-device-state/battery-monitoring.jd
similarity index 100%
rename from docs/html-intl/ja/training/monitoring-device-state/battery-monitoring.jd
rename to docs/html-intl/intl/ja/training/monitoring-device-state/battery-monitoring.jd
diff --git a/docs/html-intl/ja/training/monitoring-device-state/connectivity-monitoring.jd b/docs/html-intl/intl/ja/training/monitoring-device-state/connectivity-monitoring.jd
similarity index 100%
rename from docs/html-intl/ja/training/monitoring-device-state/connectivity-monitoring.jd
rename to docs/html-intl/intl/ja/training/monitoring-device-state/connectivity-monitoring.jd
diff --git a/docs/html-intl/ja/training/monitoring-device-state/docking-monitoring.jd b/docs/html-intl/intl/ja/training/monitoring-device-state/docking-monitoring.jd
similarity index 100%
rename from docs/html-intl/ja/training/monitoring-device-state/docking-monitoring.jd
rename to docs/html-intl/intl/ja/training/monitoring-device-state/docking-monitoring.jd
diff --git a/docs/html-intl/ja/training/monitoring-device-state/index.jd b/docs/html-intl/intl/ja/training/monitoring-device-state/index.jd
similarity index 100%
rename from docs/html-intl/ja/training/monitoring-device-state/index.jd
rename to docs/html-intl/intl/ja/training/monitoring-device-state/index.jd
diff --git a/docs/html-intl/ja/training/monitoring-device-state/manifest-receivers.jd b/docs/html-intl/intl/ja/training/monitoring-device-state/manifest-receivers.jd
similarity index 100%
rename from docs/html-intl/ja/training/monitoring-device-state/manifest-receivers.jd
rename to docs/html-intl/intl/ja/training/monitoring-device-state/manifest-receivers.jd
diff --git a/docs/html-intl/ja/training/multiscreen/adaptui.jd b/docs/html-intl/intl/ja/training/multiscreen/adaptui.jd
similarity index 100%
rename from docs/html-intl/ja/training/multiscreen/adaptui.jd
rename to docs/html-intl/intl/ja/training/multiscreen/adaptui.jd
diff --git a/docs/html-intl/ja/training/multiscreen/index.jd b/docs/html-intl/intl/ja/training/multiscreen/index.jd
similarity index 100%
rename from docs/html-intl/ja/training/multiscreen/index.jd
rename to docs/html-intl/intl/ja/training/multiscreen/index.jd
diff --git a/docs/html-intl/ja/training/multiscreen/screendensities.jd b/docs/html-intl/intl/ja/training/multiscreen/screendensities.jd
similarity index 100%
rename from docs/html-intl/ja/training/multiscreen/screendensities.jd
rename to docs/html-intl/intl/ja/training/multiscreen/screendensities.jd
diff --git a/docs/html-intl/ja/training/multiscreen/screensizes.jd b/docs/html-intl/intl/ja/training/multiscreen/screensizes.jd
similarity index 100%
rename from docs/html-intl/ja/training/multiscreen/screensizes.jd
rename to docs/html-intl/intl/ja/training/multiscreen/screensizes.jd
diff --git a/docs/html-intl/ko/training/monitoring-device-state/battery-monitoring.jd b/docs/html-intl/intl/ko/training/monitoring-device-state/battery-monitoring.jd
similarity index 100%
rename from docs/html-intl/ko/training/monitoring-device-state/battery-monitoring.jd
rename to docs/html-intl/intl/ko/training/monitoring-device-state/battery-monitoring.jd
diff --git a/docs/html-intl/ko/training/monitoring-device-state/connectivity-monitoring.jd b/docs/html-intl/intl/ko/training/monitoring-device-state/connectivity-monitoring.jd
similarity index 100%
rename from docs/html-intl/ko/training/monitoring-device-state/connectivity-monitoring.jd
rename to docs/html-intl/intl/ko/training/monitoring-device-state/connectivity-monitoring.jd
diff --git a/docs/html-intl/ko/training/monitoring-device-state/docking-monitoring.jd b/docs/html-intl/intl/ko/training/monitoring-device-state/docking-monitoring.jd
similarity index 100%
rename from docs/html-intl/ko/training/monitoring-device-state/docking-monitoring.jd
rename to docs/html-intl/intl/ko/training/monitoring-device-state/docking-monitoring.jd
diff --git a/docs/html-intl/ko/training/monitoring-device-state/index.jd b/docs/html-intl/intl/ko/training/monitoring-device-state/index.jd
similarity index 100%
rename from docs/html-intl/ko/training/monitoring-device-state/index.jd
rename to docs/html-intl/intl/ko/training/monitoring-device-state/index.jd
diff --git a/docs/html-intl/ko/training/monitoring-device-state/manifest-receivers.jd b/docs/html-intl/intl/ko/training/monitoring-device-state/manifest-receivers.jd
similarity index 100%
rename from docs/html-intl/ko/training/monitoring-device-state/manifest-receivers.jd
rename to docs/html-intl/intl/ko/training/monitoring-device-state/manifest-receivers.jd
diff --git a/docs/html-intl/ko/training/multiscreen/adaptui.jd b/docs/html-intl/intl/ko/training/multiscreen/adaptui.jd
similarity index 100%
rename from docs/html-intl/ko/training/multiscreen/adaptui.jd
rename to docs/html-intl/intl/ko/training/multiscreen/adaptui.jd
diff --git a/docs/html-intl/ko/training/multiscreen/index.jd b/docs/html-intl/intl/ko/training/multiscreen/index.jd
similarity index 100%
rename from docs/html-intl/ko/training/multiscreen/index.jd
rename to docs/html-intl/intl/ko/training/multiscreen/index.jd
diff --git a/docs/html-intl/ko/training/multiscreen/screendensities.jd b/docs/html-intl/intl/ko/training/multiscreen/screendensities.jd
similarity index 100%
rename from docs/html-intl/ko/training/multiscreen/screendensities.jd
rename to docs/html-intl/intl/ko/training/multiscreen/screendensities.jd
diff --git a/docs/html-intl/ko/training/multiscreen/screensizes.jd b/docs/html-intl/intl/ko/training/multiscreen/screensizes.jd
similarity index 100%
rename from docs/html-intl/ko/training/multiscreen/screensizes.jd
rename to docs/html-intl/intl/ko/training/multiscreen/screensizes.jd
diff --git a/docs/html-intl/ru/training/monitoring-device-state/battery-monitoring.jd b/docs/html-intl/intl/ru/training/monitoring-device-state/battery-monitoring.jd
similarity index 100%
rename from docs/html-intl/ru/training/monitoring-device-state/battery-monitoring.jd
rename to docs/html-intl/intl/ru/training/monitoring-device-state/battery-monitoring.jd
diff --git a/docs/html-intl/ru/training/monitoring-device-state/connectivity-monitoring.jd b/docs/html-intl/intl/ru/training/monitoring-device-state/connectivity-monitoring.jd
similarity index 100%
rename from docs/html-intl/ru/training/monitoring-device-state/connectivity-monitoring.jd
rename to docs/html-intl/intl/ru/training/monitoring-device-state/connectivity-monitoring.jd
diff --git a/docs/html-intl/ru/training/monitoring-device-state/docking-monitoring.jd b/docs/html-intl/intl/ru/training/monitoring-device-state/docking-monitoring.jd
similarity index 100%
rename from docs/html-intl/ru/training/monitoring-device-state/docking-monitoring.jd
rename to docs/html-intl/intl/ru/training/monitoring-device-state/docking-monitoring.jd
diff --git a/docs/html-intl/ru/training/monitoring-device-state/index.jd b/docs/html-intl/intl/ru/training/monitoring-device-state/index.jd
similarity index 100%
rename from docs/html-intl/ru/training/monitoring-device-state/index.jd
rename to docs/html-intl/intl/ru/training/monitoring-device-state/index.jd
diff --git a/docs/html-intl/ru/training/monitoring-device-state/manifest-receivers.jd b/docs/html-intl/intl/ru/training/monitoring-device-state/manifest-receivers.jd
similarity index 100%
rename from docs/html-intl/ru/training/monitoring-device-state/manifest-receivers.jd
rename to docs/html-intl/intl/ru/training/monitoring-device-state/manifest-receivers.jd
diff --git a/docs/html-intl/ru/training/multiscreen/adaptui.jd b/docs/html-intl/intl/ru/training/multiscreen/adaptui.jd
similarity index 100%
rename from docs/html-intl/ru/training/multiscreen/adaptui.jd
rename to docs/html-intl/intl/ru/training/multiscreen/adaptui.jd
diff --git a/docs/html-intl/ru/training/multiscreen/index.jd b/docs/html-intl/intl/ru/training/multiscreen/index.jd
similarity index 100%
rename from docs/html-intl/ru/training/multiscreen/index.jd
rename to docs/html-intl/intl/ru/training/multiscreen/index.jd
diff --git a/docs/html-intl/ru/training/multiscreen/screendensities.jd b/docs/html-intl/intl/ru/training/multiscreen/screendensities.jd
similarity index 100%
rename from docs/html-intl/ru/training/multiscreen/screendensities.jd
rename to docs/html-intl/intl/ru/training/multiscreen/screendensities.jd
diff --git a/docs/html-intl/ru/training/multiscreen/screensizes.jd b/docs/html-intl/intl/ru/training/multiscreen/screensizes.jd
similarity index 100%
rename from docs/html-intl/ru/training/multiscreen/screensizes.jd
rename to docs/html-intl/intl/ru/training/multiscreen/screensizes.jd
diff --git a/docs/html-intl/zh-cn/training/monitoring-device-state/battery-monitoring.jd b/docs/html-intl/intl/zh-cn/training/monitoring-device-state/battery-monitoring.jd
similarity index 100%
rename from docs/html-intl/zh-cn/training/monitoring-device-state/battery-monitoring.jd
rename to docs/html-intl/intl/zh-cn/training/monitoring-device-state/battery-monitoring.jd
diff --git a/docs/html-intl/zh-cn/training/monitoring-device-state/connectivity-monitoring.jd b/docs/html-intl/intl/zh-cn/training/monitoring-device-state/connectivity-monitoring.jd
similarity index 100%
rename from docs/html-intl/zh-cn/training/monitoring-device-state/connectivity-monitoring.jd
rename to docs/html-intl/intl/zh-cn/training/monitoring-device-state/connectivity-monitoring.jd
diff --git a/docs/html-intl/zh-cn/training/monitoring-device-state/docking-monitoring.jd b/docs/html-intl/intl/zh-cn/training/monitoring-device-state/docking-monitoring.jd
similarity index 100%
rename from docs/html-intl/zh-cn/training/monitoring-device-state/docking-monitoring.jd
rename to docs/html-intl/intl/zh-cn/training/monitoring-device-state/docking-monitoring.jd
diff --git a/docs/html-intl/zh-cn/training/monitoring-device-state/index.jd b/docs/html-intl/intl/zh-cn/training/monitoring-device-state/index.jd
similarity index 100%
rename from docs/html-intl/zh-cn/training/monitoring-device-state/index.jd
rename to docs/html-intl/intl/zh-cn/training/monitoring-device-state/index.jd
diff --git a/docs/html-intl/zh-cn/training/monitoring-device-state/manifest-receivers.jd b/docs/html-intl/intl/zh-cn/training/monitoring-device-state/manifest-receivers.jd
similarity index 100%
rename from docs/html-intl/zh-cn/training/monitoring-device-state/manifest-receivers.jd
rename to docs/html-intl/intl/zh-cn/training/monitoring-device-state/manifest-receivers.jd
diff --git a/docs/html-intl/zh-cn/training/multiscreen/adaptui.jd b/docs/html-intl/intl/zh-cn/training/multiscreen/adaptui.jd
similarity index 100%
rename from docs/html-intl/zh-cn/training/multiscreen/adaptui.jd
rename to docs/html-intl/intl/zh-cn/training/multiscreen/adaptui.jd
diff --git a/docs/html-intl/zh-cn/training/multiscreen/index.jd b/docs/html-intl/intl/zh-cn/training/multiscreen/index.jd
similarity index 100%
rename from docs/html-intl/zh-cn/training/multiscreen/index.jd
rename to docs/html-intl/intl/zh-cn/training/multiscreen/index.jd
diff --git a/docs/html-intl/zh-cn/training/multiscreen/screendensities.jd b/docs/html-intl/intl/zh-cn/training/multiscreen/screendensities.jd
similarity index 100%
rename from docs/html-intl/zh-cn/training/multiscreen/screendensities.jd
rename to docs/html-intl/intl/zh-cn/training/multiscreen/screendensities.jd
diff --git a/docs/html-intl/zh-cn/training/multiscreen/screensizes.jd b/docs/html-intl/intl/zh-cn/training/multiscreen/screensizes.jd
similarity index 100%
rename from docs/html-intl/zh-cn/training/multiscreen/screensizes.jd
rename to docs/html-intl/intl/zh-cn/training/multiscreen/screensizes.jd
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 1df2e22..4735033 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -61,7 +61,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on October 2, 2013.
+<p style="clear:both"><em>Data collected during a 7-day period ending on December 2, 2013.
 <br/>Any versions with less than 0.1% distribution are not shown.</em>
 </p>
 
@@ -92,7 +92,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on October 2, 2013
+<p style="clear:both"><em>Data collected during a 7-day period ending on December 2, 2013
 <br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p>
 
 
@@ -111,7 +111,7 @@
 
 
 <img alt="" style="float:right"
-src="//chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1%20only|GL%202.0%20%26%201.1&chd=t%3A0.2,99.8&chf=bg,s,00000000" />
+src="//chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1%20only|GL%202.0|GL%203.0&chd=t%3A0.1,98.3,1.6&chf=bg,s,00000000" />
 
 <p>To declare which version of OpenGL ES your application requires, you should use the {@code
 android:glEsVersion} attribute of the <a
@@ -129,17 +129,21 @@
 </tr>
 <tr>
 <td>1.1 only</th>
-<td>0.2%</td>
+<td>0.1%</td>
 </tr>
 <tr>
-<td>2.0 &amp; 1.1</th>
-<td>99.8%</td>
+<td>2.0</th>
+<td>96.3%</td>
+</tr>
+<tr>
+<td>3.0</th>
+<td>3.6%</td>
 </tr>
 </table>
 
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on October 2, 2013</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on December 2, 2013</em></p>
 
 
 
@@ -157,17 +161,17 @@
 var VERSION_DATA =
 [
   {
-    "chart": "//chart.googleapis.com/chart?chs=500x250&cht=p&chco=c4df9b%2C6fad0c&chf=bg%2Cs%2C00000000&chd=t%3A2.2%2C28.5%2C0.1%2C20.6%2C48.6&chl=Froyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean",
+    "chart": "//chart.googleapis.com/chart?cht=p&chs=500x250&chf=bg%2Cs%2C00000000&chd=t%3A1.6%2C24.1%2C0.1%2C18.6%2C54.5%2C1.1&chl=Froyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chco=c4df9b%2C6fad0c",
     "data": [
       {
         "api": 8,
         "name": "Froyo",
-        "perc": "2.2"
+        "perc": "1.6"
       },
       {
         "api": 10,
         "name": "Gingerbread",
-        "perc": "28.5"
+        "perc": "24.1"
       },
       {
         "api": 13,
@@ -177,22 +181,27 @@
       {
         "api": 15,
         "name": "Ice Cream Sandwich",
-        "perc": "20.6"
+        "perc": "18.6"
       },
       {
         "api": 16,
         "name": "Jelly Bean",
-        "perc": "36.5"
+        "perc": "37.4"
       },
       {
         "api": 17,
         "name": "Jelly Bean",
-        "perc": "10.6"
+        "perc": "12.9"
       },
       {
         "api": 18,
         "name": "Jelly Bean",
-        "perc": "1.5"
+        "perc": "4.2"
+      },
+      {
+        "api": 19,
+        "name": "KitKat",
+        "perc": "1.1"
       }
     ]
   }
@@ -209,28 +218,28 @@
       "Large": {
         "hdpi": "0.5",
         "ldpi": "0.6",
-        "mdpi": "3.5",
-        "tvdpi": "1.2",
+        "mdpi": "3.8",
+        "tvdpi": "1.4",
         "xhdpi": "0.6"
       },
       "Normal": {
-        "hdpi": "33.5",
+        "hdpi": "33.4",
         "ldpi": "0.1",
-        "mdpi": "15.3",
-        "xhdpi": "22.8",
-        "xxhdpi": "7.7"
+        "mdpi": "14.6",
+        "xhdpi": "21.6",
+        "xxhdpi": "9.7"
       },
       "Small": {
-        "ldpi": "9.4"
+        "ldpi": "8.8"
       },
       "Xlarge": {
         "hdpi": "0.3",
-        "mdpi": "4.4",
+        "mdpi": "4.5",
         "xhdpi": "0.1"
       }
     },
-    "densitychart": "//chart.googleapis.com/chart?chs=400x250&cht=p&chco=c4df9b%2C6fad0c&chf=bg%2Cs%2C00000000&chd=t%3A10.1%2C23.3%2C1.2%2C34.3%2C23.5%2C7.7&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi",
-    "layoutchart": "//chart.googleapis.com/chart?chs=400x250&cht=p&chco=c4df9b%2C6fad0c&chf=bg%2Cs%2C00000000&chd=t%3A4.8%2C6.4%2C79.5%2C9.4&chl=Xlarge%7CLarge%7CNormal%7CSmall"
+    "densitychart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chf=bg%2Cs%2C00000000&chd=t%3A9.5%2C22.9%2C1.4%2C34.2%2C22.3%2C9.7&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chco=c4df9b%2C6fad0c",
+    "layoutchart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chf=bg%2Cs%2C00000000&chd=t%3A4.9%2C6.9%2C79.4%2C8.8&chl=Xlarge%7CLarge%7CNormal%7CSmall&chco=c4df9b%2C6fad0c"
   }
 ];
 
@@ -297,6 +306,11 @@
     "api":18,
     "link":"<a href='/about/versions/android-4.3.html'>4.3</a>",
     "codename":"Jelly Bean"
+  },
+  {
+    "api":19,
+    "link":"<a href='/about/versions/android-4.4.html'>4.4</a>",
+    "codename":"KitKat"
   }
 ];
 
diff --git a/docs/html/about/versions/android-4.4.jd b/docs/html/about/versions/android-4.4.jd
index 6ef0337..3de2acc 100644
--- a/docs/html/about/versions/android-4.4.jd
+++ b/docs/html/about/versions/android-4.4.jd
@@ -244,7 +244,7 @@
 
 <p>If you want to emulate an NFC card that is using these protocols in your app, create a service component based on the {@link android.nfc.cardemulation.HostApduService} class. Whereas if your app instead uses a secure element for card emulation, you need to create a service based on the {@link android.nfc.cardemulation.OffHostApduService} class, which will not directly be involved in the transactions but is necessary to register the AIDs that should be handled by the secure element.</p>
 
-<p>For more information, read the <a href="">NFC Card Emulation</a> guide.</p>
+<p>For more information, read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">NFC Card Emulation</a> guide.</p>
 
 
 <h3 id="ReaderMode">NFC reader mode</h3>
@@ -474,7 +474,7 @@
 
 <p>To provide batching, the {@link android.hardware.SensorManager} class adds two new versions of the {@link android.hardware.SensorManager#registerListener(SensorEventListener, Sensor, int, int) registerListener()} method that allow you to specify the "maximum report latency." This new parameter specifies the maximum delay that your {@link android.hardware.SensorEventListener} will tolerate for delivery of new sensor events. For example, if you specify a batch latency of one minute, the system will deliver the recent set of batched events at an interval no longer than one minute by making consecutive calls to your {@link android.hardware.SensorEventListener#onSensorChanged onSensorChanged()} method&mdash;once for each event that was batched. The sensor events will never be delayed longer than your maximum report latency value, but may arrive sooner if other apps have requested a shorter latency for the same sensor.</p>
 
-<p>However, be aware that the sensor will deliver your app the batched events based on your report latency <strong>only while the CPU is awake</strong>. Although a hardware sensor that supports batching will continue to collect sensor events while the CPU is asleep, it will not wake the CPU to deliver your app the batched events. When the sensor eventually runs out of its memory for events, it will begin dropping the oldest events in order to save the newest events. You can avoid losing events by waking the device before the sensor fills its memory then call {@link android.hardware.SensorManager#flush flush()} to capture the latest batch of events. To estimate when the memory will be full and should be flushed, call {@link android.hardware.Sensor#getFifoReservedEventCount()} to get the maximum number of sensor events it can save, and divide that number by the rate at which your app desires each event. Use that calculation to set wake alarms with {@link android.app.AlarmManager} that invoke your {@link android.app.Service} (which implements the {@link android.hardware.SensorEventListener}) to flush the sensor. It's okay that the alarm may execute even while the device is awake, because the alarm interval should be large enough that it occurs only a few times in a day.</p>
+<p>However, be aware that the sensor will deliver your app the batched events based on your report latency <strong>only while the CPU is awake</strong>. Although a hardware sensor that supports batching will continue to collect sensor events while the CPU is asleep, it will not wake the CPU to deliver your app the batched events. When the sensor eventually runs out of its memory for events, it will begin dropping the oldest events in order to save the newest events. You can avoid losing events by waking the device before the sensor fills its memory then call {@link android.hardware.SensorManager#flush flush()} to capture the latest batch of events. To estimate when the memory will be full and should be flushed, call {@link android.hardware.Sensor#getFifoMaxEventCount()} to get the maximum number of sensor events it can save, and divide that number by the rate at which your app desires each event. Use that calculation to set wake alarms with {@link android.app.AlarmManager} that invoke your {@link android.app.Service} (which implements the {@link android.hardware.SensorEventListener}) to flush the sensor.</p>
 
 
 <p class="note"><strong>Note:</strong> Not all devices support batching sensor events because it requires support by the hardware sensor. However, beginning with Android 4.4, you should always use the new {@link android.hardware.SensorManager#registerListener(SensorEventListener, Sensor, int, int) registerListener()} methods, because if the device does not support batching, then the system gracefully ignores the batch latency argument and delivers sensor events in real time.</p>
@@ -572,8 +572,8 @@
 
 
 
-<p style="margin-top:50px" class="note">For a detailed view of all API changes in Android 4.3, see the
-<a href="{@docRoot}sdk/api_diff/18/changes.html">API Differences Report</a>.</p>
+<p style="margin-top:50px" class="note">For a detailed view of all API changes in Android 4.4, see the
+<a href="{@docRoot}sdk/api_diff/19/changes.html">API Differences Report</a>.</p>
 
 
 
diff --git a/docs/html/about/versions/jelly-bean.jd b/docs/html/about/versions/jelly-bean.jd
index c7d1941..25f88e3 100644
--- a/docs/html/about/versions/jelly-bean.jd
+++ b/docs/html/about/versions/jelly-bean.jd
@@ -438,9 +438,9 @@
 
 <p>Android 4.3 also includes new utilities and APIs for creating better RTL
 strings and testing your localized UIs. A new <strong>BidiFormatter</strong>
-provides a set of simple APIs for wrapping Unicode strings so that you can
-fine-tune your text rendering in RTL scripts. To let you use this utility more
-broadly in your apps, the BidiFormatter APIs are also now available for earlier
+class provides a simple API for wrapping Unicode strings, so that RTL-script
+data is displayed as intended in LTR-locale messages and vice-versa. To let you use this utility more
+broadly in your apps, the BidiFormatter API is also now available for earlier
 platform versions through the Support Package in the Android SDK. </p>
 
 <p>To assist you with managing date formatting across locales, Android 4.3
@@ -578,9 +578,10 @@
 graph for each visible Activity, including the navigation bar and notification
 bar. </p>
 
-<p>A green line highlights the <strong>60ms threshold</strong> for rendering
+<p>A green line highlights the <strong>16ms threshold</strong> for rendering
 operations, so you can assess the your app’s effective framerate relative
-to a 60 fps goal. If you see operations that cross the green line, you
+to a 60 fps goal (because 1/60th of a second equals roughly 16ms).
+If you see operations that cross the green line, you
 can analyze them further using Systrace and other tools.</p>
 
 <p class="caution" style="clear:both">On devices running Android 4.2 and higher,
diff --git a/docs/html/about/versions/kitkat.jd b/docs/html/about/versions/kitkat.jd
index 92ebf65..4237c98 100644
--- a/docs/html/about/versions/kitkat.jd
+++ b/docs/html/about/versions/kitkat.jd
@@ -54,8 +54,8 @@
 <!-- BEGIN ANDROID 4.4 -->
 <div id="44-android-44" class="version-section">
 
-  <div style="padding:0px 0px 0px 60px;margin-top:-3px;float:right;">
-    <img src="{@docRoot}design/media/index_landing_page.png" alt="Android 4.4 on phone and tablet" width="380">
+  <div style="padding:0px 0px 0px 60px;margin-top:-20px;float:right;">
+    <img src="{@docRoot}images/kk-devices.png" alt="Android 4.4 on phone and tablet" width="380">
   </div>
 
   <div class="landing-docs" style="float:right;clear:both;margin:22px 0 2em 3em;">
@@ -992,7 +992,7 @@
   <img src="{@docRoot}images/kk-pseudolocale-rtl.png" alt="" width="260" style=
   "margin-bottom:0;">
   <p class="img-caption" style="padding-top:1.5em;line-height:1.25em;">
-    Pseudo-locales make it easier to test your app's localization.
+    The <strong>Force RTL layout</strong> option makes it easier to test your app's localization.
   </p>
 </div>
 
@@ -1003,18 +1003,19 @@
   files by using a new attribute.
 </p>
 
-<h4 id="44-pseudolocale-rtl">RTL pseudo-locale</h4>
+<h4 id="44-pseudolocale-rtl">Force RTL Layout</h4>
 
 <p>
-  To make it easier to test and debug your layouts, Android includes an RTL
-  pseudo-locale as a new developer option.
+  To make it easier to test and debug layout mirroring issues without switching
+  to an RTL language, Android includes a new developer option to force RTL layout
+  direction in all apps.
 </p>
 
 <p>
-  The RTL pseudo-locale switches the device to RTL layout for all locales and
+  The Force RTL layout option switches the device to RTL layout for all locales and
   displays text in your current language. This can help you find layout issues
   across your app, without having to display the app in an RTL language. You
-  can access the RTL pseudo-localed as in <strong>Settings &gt; Developer
+  can access the option in <strong>Settings &gt; Developer
   options &gt; Force RTL layout direction</strong>.
 </p>
 
diff --git a/docs/html/channels/io2013.jd b/docs/html/channels/io2013.jd
index 977eb2f..2efda28 100644
--- a/docs/html/channels/io2013.jd
+++ b/docs/html/channels/io2013.jd
@@ -1,3 +1,4 @@
+excludeFromSuggestions=true
 fullpage=true
 page.title=Google I/O 13
 @jd:body
diff --git a/docs/html/design/building-blocks/buttons.jd b/docs/html/design/building-blocks/buttons.jd
index 7957ef8..2a77e24 100644
--- a/docs/html/design/building-blocks/buttons.jd
+++ b/docs/html/design/building-blocks/buttons.jd
@@ -1,5 +1,5 @@
 page.title=Buttons
-page.tags="button","input"
+page.tags=button,input
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/controls/button.html">
@@ -9,39 +9,83 @@
   </div>
 </a>
 
-<p>A button consists of text and/or an image that clearly communicates what action will occur when the
-user touches it. Android supports two different types of buttons: <em>basic buttons</em> and <em>borderless
-buttons</em>. Both can contain text labels and/or images.</p>
+<p>A button consists of text and/or an image that clearly communicates what action
+  will occur when the user touches it. A button can have an image, text, or both.
+</p>
 
-<img src="{@docRoot}design/media/buttons_basic.png">
-
-<h2 id="basic">Basic Buttons</h2>
-
-<p>Basic buttons are traditional buttons with borders and background. Android supports two styles for
-basic buttons: default and small. Default buttons have slightly larger font size and are optimized
-for display outside of form content. Small buttons are intended for display alongside other content.
-They have a smaller font and smaller minimum height. Use small buttons in forms where they need to
-align with other UI elements.</p>
-
-<img src="{@docRoot}design/media/buttons_default_small.png">
-<div class="layout-content-row">
-  <div class="layout-content-col span-6">
-    <div class="figure-caption">
-      Default buttons in Holo Dark &amp; Light.
-    </div>
+<div class="layout-content-row" style="margin-top:22px">
+  <div class="layout-content-col span-3">
+    <img src="{@docRoot}design/media/icon_magnifying_glass.png" style="height:64px;padding:20px 0 0 40px;">
   </div>
-  <div class="layout-content-col span-6">
-    <div class="figure-caption">
-      Small buttons in Holo Dark &amp; Light.
-    </div>
+  <div class="layout-content-col span-3">
+    <img src="{@docRoot}design/media/buttons_text.png"  style="height:94px;">
+  </div>
+  <div class="layout-content-col span-7">
+    <img src="{@docRoot}design/media/buttons_image_and_text.png"  style="height:94px;">
   </div>
 </div>
 
-<h2 id="borderless">Borderless Buttons</h2>
+<div class="layout-content-row" style="margin-top:0;">
+  <div class="layout-content-col span-3">
+      <p>An image alone works best when the action can be represented by a symbol that's well understood.</p>
+  </div>
+  <div class="layout-content-col span-3">
+      <p>Text alone is most appropriate for actions that would be difficult to
+      represent visually, or are critical to convey in words to avoid any ambiguity.</p>
+  </div>
+  <div class="layout-content-col span-7">
+    <p>
+      Both an icon and text is most appropriate when they complement each other:
+      each carrying its own bit of information, but together making a larger whole.
+    </p>
 
-<p>Borderless buttons resemble basic buttons except that they have no borders or background. You can
-use borderless buttons with both icons and text. Borderless buttons are visually more lightweight
-than basic buttons and integrate nicely with other content.</p>
+    <p>
+      For example, in a birthday reminder card in Google Now, the button's text
+      describes the action while its image indicates that the action will be done
+      in Google+.
+    </p>
+  </div>
+</div>
 
-<img src="{@docRoot}design/media/buttons_borderless.png">
+<h3>What about button backgrounds?</h3>
+
+<div class="layout-content-row">
+  <div class="layout-content-col span-6">
+    <p>For <strong>image-only</strong> buttons, a background isn't necessary because
+    users are accustomed to interacting with objects.</p>
+
+    <div class="layout-content-row" style="margin-left:72px">
+      <div class="layout-content-col span-2">
+        <div class="do-dont-label bad emulate-content-left-padding" style="width:30px">Don't</div>
+        <img src="{@docRoot}design/media/buttons_image_bg_dont.png" style="padding-left:14px;">
+      </div>
+      <div class="layout-content-col span-2" style="width:29px;margin-left:10px;">
+        <div class="do-dont-label good"><strong>Do</strong></div>
+        <img src="{@docRoot}design/media/icon_alarm.png" style="width:31px;padding-top:7px;">
+      </div>
+    </div>
+  </div>
+
+<div class="layout-content-col span-7">
+<p>
+  For buttons <strong>with text</strong>, a background is also usually
+  unnecessary. To invite users to touch, phrase it as a clear action (e.g.
+  "Start", "Sign in") and use different color and formatting than the screen's
+  usual body text.
+</p>
+
+<p>
+  Use buttons with backgrounds sparingly. Because they have a heavy appearance,
+  they work best when there's only one or two of them on the screen. They're
+  most appropriate for:
+</p>
+
+<ul>
+  <li>A call to action you really want users to pursue (e.g. "Sign up")</li>
+  <li>A key decision point (e.g. "Accept" / "Decline")</li>
+  <li>When the user is about to commit a significant action (e.g. "Erase
+  everything", "Buy now")</li>
+</ul>
+</div>
+</div>
 
diff --git a/docs/html/design/building-blocks/dialogs.jd b/docs/html/design/building-blocks/dialogs.jd
index f4bb87e..f9897f4 100644
--- a/docs/html/design/building-blocks/dialogs.jd
+++ b/docs/html/design/building-blocks/dialogs.jd
@@ -1,5 +1,5 @@
 page.title=Dialogs
-page.tags="dialog","alert","popup","toast"
+page.tags=dialog,alert,popup,toast
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/dialogs.html">
diff --git a/docs/html/design/building-blocks/grid-lists.jd b/docs/html/design/building-blocks/grid-lists.jd
index 1a09ef5..cef7514 100644
--- a/docs/html/design/building-blocks/grid-lists.jd
+++ b/docs/html/design/building-blocks/grid-lists.jd
@@ -1,5 +1,5 @@
 page.title=Grid Lists
-page.tags="gridview","layout","listview"
+page.tags=gridview,layout,listview
 @jd:body
 
 <img src="{@docRoot}design/media/gridview_overview.png">
diff --git a/docs/html/design/building-blocks/lists.jd b/docs/html/design/building-blocks/lists.jd
index 5514824..54fa442 100644
--- a/docs/html/design/building-blocks/lists.jd
+++ b/docs/html/design/building-blocks/lists.jd
@@ -1,5 +1,5 @@
 page.title=Lists
-page.tags="listview","layout"
+page.tags=listview,layout
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/layout/listview.html">
diff --git a/docs/html/design/building-blocks/pickers.jd b/docs/html/design/building-blocks/pickers.jd
index 6dd72ba..860a126 100644
--- a/docs/html/design/building-blocks/pickers.jd
+++ b/docs/html/design/building-blocks/pickers.jd
@@ -1,5 +1,5 @@
 page.title=Pickers
-page.tags="datepicker","timepicker"
+page.tags=datepicker,timepicker
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/controls/pickers.html">
diff --git a/docs/html/design/building-blocks/progress.jd b/docs/html/design/building-blocks/progress.jd
index 90732f4..6946a75 100644
--- a/docs/html/design/building-blocks/progress.jd
+++ b/docs/html/design/building-blocks/progress.jd
@@ -1,5 +1,5 @@
 page.title=Progress &amp; Activity
-page.tags="progressbar","download","network"
+page.tags=progressbar,download,network
 @jd:body
 
 <p>Progress bars and activity indicators signal to users that something is happening that will take a moment.</p>
diff --git a/docs/html/design/building-blocks/scrolling.jd b/docs/html/design/building-blocks/scrolling.jd
index 13b3b09..41e7cec 100644
--- a/docs/html/design/building-blocks/scrolling.jd
+++ b/docs/html/design/building-blocks/scrolling.jd
@@ -1,5 +1,5 @@
 page.title=Scrolling
-page.tags="scrollview","listview"
+page.tags=scrollview,listview
 @jd:body
 
 <p>Scrolling allows the user to navigate to content in the overflow using a swipe gesture. The
diff --git a/docs/html/design/building-blocks/seek-bars.jd b/docs/html/design/building-blocks/seek-bars.jd
index 9d38e36..1465688 100644
--- a/docs/html/design/building-blocks/seek-bars.jd
+++ b/docs/html/design/building-blocks/seek-bars.jd
@@ -1,5 +1,5 @@
 page.title=Seek Bars and Sliders
-page.tags="seekbar","progressbar"
+page.tags=seekbar,progressbar
 @jd:body
 
 <p>Interactive sliders make it possible to select a value from a continuous or discrete range of values
diff --git a/docs/html/design/building-blocks/spinners.jd b/docs/html/design/building-blocks/spinners.jd
index c00b639..f8d92d4 100644
--- a/docs/html/design/building-blocks/spinners.jd
+++ b/docs/html/design/building-blocks/spinners.jd
@@ -1,5 +1,5 @@
 page.title=Spinners
-page.tags="spinner","dropdown"
+page.tags=spinner,dropdown
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/controls/spinner.html">
diff --git a/docs/html/design/building-blocks/switches.jd b/docs/html/design/building-blocks/switches.jd
index 74cab5a..b294689 100644
--- a/docs/html/design/building-blocks/switches.jd
+++ b/docs/html/design/building-blocks/switches.jd
@@ -1,5 +1,5 @@
 page.title=Switches
-page.tags="switch","checkbox","radiobutton","button"
+page.tags=switch,checkbox,radiobutton,button
 @jd:body
 
 <p>Switches allow the user to select options. There are three kinds of switches: checkboxes, radio
diff --git a/docs/html/design/building-blocks/tabs.jd b/docs/html/design/building-blocks/tabs.jd
index 5a5da5d8..1fa3461 100644
--- a/docs/html/design/building-blocks/tabs.jd
+++ b/docs/html/design/building-blocks/tabs.jd
@@ -1,5 +1,5 @@
 page.title=Tabs
-page.tags="tabs","actionbar","navigation","viewpager"
+page.tags=tabs,actionbar,navigation,viewpager
 @jd:body
 
 <img src="{@docRoot}design/media/tabs_overview.png">
diff --git a/docs/html/design/building-blocks/text-fields.jd b/docs/html/design/building-blocks/text-fields.jd
index 383531b..4545bfb 100644
--- a/docs/html/design/building-blocks/text-fields.jd
+++ b/docs/html/design/building-blocks/text-fields.jd
@@ -1,5 +1,5 @@
 page.title=Text Fields
-page.tags="text","edittext","input"
+page.tags=text,edittext,input
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/controls/text.html">
diff --git a/docs/html/design/downloads/index.jd b/docs/html/design/downloads/index.jd
index d514c14..ddeda5c 100644
--- a/docs/html/design/downloads/index.jd
+++ b/docs/html/design/downloads/index.jd
@@ -1,4 +1,5 @@
 page.title=Downloads
+page.tags=Icons,stencils,color swatches
 @jd:body
 
 <div class="layout-content-row">
@@ -15,7 +16,7 @@
 
 <p>
   <a class="download-button" onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'All Design Assets']);"
-    href="{@docRoot}downloads/design/Android_Design_Downloads_20130814.zip">Download All</a>
+    href="{@docRoot}downloads/design/Android_Design_Downloads_20131106.zip">Download All</a>
 </p>
 
   </div>
@@ -26,8 +27,8 @@
 <div class="layout-content-row">
   <div class="layout-content-col span-5">
 
-<p>Drag and drop your way to beautifully designed Ice Cream Sandwich apps. The stencils feature the
-rich typography, colors, interactive controls, and icons found throughout Android 4.0, along with
+<p>Drag and drop your way to beautifully designed Android apps. The stencils feature the
+rich typography, colors, interactive controls, and icons found throughout Android, along with
 phone and tablet outlines to frame your creations. Source files for icons and controls are also
 available.</p>
 
@@ -40,14 +41,14 @@
   <div class="layout-content-col span-4">
 
 <p>
-  <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Fireworks Stencil']);"
+  <!--<a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Fireworks Stencil']);"
     href="{@docRoot}downloads/design/Android_Design_Fireworks_Stencil_20120814.png">Adobe&reg; Fireworks&reg; PNG Stencil</a>
   <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Illustrator Stencil']);"
     href="{@docRoot}downloads/design/Android_Design_Illustrator_Vectors_20120814.ai">Adobe&reg; Illustrator&reg; Stencil</a>
   <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'OmniGraffle Stencil']);"
-    href="{@docRoot}downloads/design/Android_Design_OmniGraffle_Stencil_20120814.graffle">Omni&reg; OmniGraffle&reg; Stencil</a>
+    href="{@docRoot}downloads/design/Android_Design_OmniGraffle_Stencil_20120814.graffle">Omni&reg; OmniGraffle&reg; Stencil</a>-->
   <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Photoshop Sources']);"
-    href="{@docRoot}downloads/design/Android_Design_Holo_Widgets_20120814.zip">Adobe&reg; Photoshop&reg; Sources</a>
+    href="{@docRoot}downloads/design/Android_Design_Stencils_Sources_20131106.zip">Adobe&reg; Photoshop&reg; Stencils and Sources</a>
 </p>
 
   </div>
@@ -74,7 +75,7 @@
 
 <p>
   <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Action Bar Icons']);"
-    href="{@docRoot}downloads/design/Android_Design_Icons_20130926.zip">Action Bar Icon Pack</a>
+    href="{@docRoot}downloads/design/Android_Design_Icons_20131106.zip">Action Bar Icon Pack</a>
 </p>
 
   </div>
@@ -114,7 +115,7 @@
   <div class="layout-content-col span-5">
 
 <h4>Color</h4>
-<p>Blue is the standard accent color in Android's color palette. Each color has a corresponding darker
+<p>In Android's color palette, each color has a corresponding darker
 shade that can be used as a complement when needed.</p>
 <p><a href="{@docRoot}design/style/color.html">More on Color</a></p>
 
diff --git a/docs/html/design/media/buttons_image_and_text.png b/docs/html/design/media/buttons_image_and_text.png
new file mode 100644
index 0000000..b7ffccb
--- /dev/null
+++ b/docs/html/design/media/buttons_image_and_text.png
Binary files differ
diff --git a/docs/html/design/media/buttons_image_bg_dont.png b/docs/html/design/media/buttons_image_bg_dont.png
new file mode 100644
index 0000000..651d3ce
--- /dev/null
+++ b/docs/html/design/media/buttons_image_bg_dont.png
Binary files differ
diff --git a/docs/html/design/media/buttons_text.png b/docs/html/design/media/buttons_text.png
new file mode 100644
index 0000000..54d3dd3
--- /dev/null
+++ b/docs/html/design/media/buttons_text.png
Binary files differ
diff --git a/docs/html/design/media/calendar.mp4 b/docs/html/design/media/calendar.mp4
deleted file mode 100644
index cdd72d2..0000000
--- a/docs/html/design/media/calendar.mp4
+++ /dev/null
Binary files differ
diff --git a/docs/html/design/media/calendar.ogv b/docs/html/design/media/calendar.ogv
deleted file mode 100644
index efb23d2..0000000
--- a/docs/html/design/media/calendar.ogv
+++ /dev/null
Binary files differ
diff --git a/docs/html/design/media/calendar.webm b/docs/html/design/media/calendar.webm
deleted file mode 100644
index 9d7d9f2..0000000
--- a/docs/html/design/media/calendar.webm
+++ /dev/null
Binary files differ
diff --git a/docs/html/design/media/dialogs_popups_example.png b/docs/html/design/media/dialogs_popups_example.png
index 6c98b1f..a8ebacd 100644
--- a/docs/html/design/media/dialogs_popups_example.png
+++ b/docs/html/design/media/dialogs_popups_example.png
Binary files differ
diff --git a/docs/html/design/media/icon_alarm.png b/docs/html/design/media/icon_alarm.png
new file mode 100644
index 0000000..36ce643a
--- /dev/null
+++ b/docs/html/design/media/icon_alarm.png
Binary files differ
diff --git a/docs/html/design/media/icon_magnifying_glass.png b/docs/html/design/media/icon_magnifying_glass.png
new file mode 100644
index 0000000..d443a85
--- /dev/null
+++ b/docs/html/design/media/icon_magnifying_glass.png
Binary files differ
diff --git a/docs/html/design/media/multipane_view_tablet.png b/docs/html/design/media/multipane_view_tablet.png
index d59308a..a713591 100644
--- a/docs/html/design/media/multipane_view_tablet.png
+++ b/docs/html/design/media/multipane_view_tablet.png
Binary files differ
diff --git a/docs/html/design/media/navigation_between_apps_back.png b/docs/html/design/media/navigation_between_apps_back.png
index a817374..d0c12cf 100644
--- a/docs/html/design/media/navigation_between_apps_back.png
+++ b/docs/html/design/media/navigation_between_apps_back.png
Binary files differ
diff --git a/docs/html/design/media/navigation_between_apps_inward.png b/docs/html/design/media/navigation_between_apps_inward.png
index 321d0da..75e7fc6 100644
--- a/docs/html/design/media/navigation_between_apps_inward.png
+++ b/docs/html/design/media/navigation_between_apps_inward.png
Binary files differ
diff --git a/docs/html/design/media/navigation_between_apps_up.png b/docs/html/design/media/navigation_between_apps_up.png
index 42d0d8f..67ebb77 100644
--- a/docs/html/design/media/navigation_between_apps_up.png
+++ b/docs/html/design/media/navigation_between_apps_up.png
Binary files differ
diff --git a/docs/html/design/media/navigation_from_outside_back.png b/docs/html/design/media/navigation_from_outside_back.png
index 0e1aa04..9153b08 100644
--- a/docs/html/design/media/navigation_from_outside_back.png
+++ b/docs/html/design/media/navigation_from_outside_back.png
Binary files differ
diff --git a/docs/html/design/media/navigation_up_vs_back_gmail.png b/docs/html/design/media/navigation_up_vs_back_gmail.png
index d5eaa18..7cc295e 100644
--- a/docs/html/design/media/navigation_up_vs_back_gmail.png
+++ b/docs/html/design/media/navigation_up_vs_back_gmail.png
Binary files differ
diff --git a/docs/html/design/media/progress_download.png b/docs/html/design/media/progress_download.png
index 5c9e556..5765095 100644
--- a/docs/html/design/media/progress_download.png
+++ b/docs/html/design/media/progress_download.png
Binary files differ
diff --git a/docs/html/design/media/touch_feedback.mp4 b/docs/html/design/media/touch_feedback.mp4
new file mode 100644
index 0000000..b91dc4b
--- /dev/null
+++ b/docs/html/design/media/touch_feedback.mp4
Binary files differ
diff --git a/docs/html/design/media/touch_feedback.ogv b/docs/html/design/media/touch_feedback.ogv
new file mode 100644
index 0000000..22c9f97
--- /dev/null
+++ b/docs/html/design/media/touch_feedback.ogv
Binary files differ
diff --git a/docs/html/design/media/touch_feedback.webm b/docs/html/design/media/touch_feedback.webm
new file mode 100644
index 0000000..a65c142
--- /dev/null
+++ b/docs/html/design/media/touch_feedback.webm
Binary files differ
diff --git a/docs/html/design/media/touch_feedback_thumb.png b/docs/html/design/media/touch_feedback_thumb.png
new file mode 100644
index 0000000..49af69f
--- /dev/null
+++ b/docs/html/design/media/touch_feedback_thumb.png
Binary files differ
diff --git a/docs/html/design/media/widgets_gestures.png b/docs/html/design/media/widgets_gestures.png
index 5e1268d..bbce87d 100644
--- a/docs/html/design/media/widgets_gestures.png
+++ b/docs/html/design/media/widgets_gestures.png
Binary files differ
diff --git a/docs/html/design/patterns/accessibility.jd b/docs/html/design/patterns/accessibility.jd
index 532900e..50c82fe 100644
--- a/docs/html/design/patterns/accessibility.jd
+++ b/docs/html/design/patterns/accessibility.jd
@@ -1,5 +1,5 @@
 page.title=Accessibility
-page.tags="accessibility","navigation","input"
+page.tags=accessibility,navigation,input
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}training/accessibility/index.html">
@@ -86,4 +86,4 @@
   <li>Provide alternatives to affordances that time out</li>
   <li>Use standard framework controls or enable TalkBack for custom controls</li>
   <li>Try it out yourself</li>
-</ul>
\ No newline at end of file
+</ul>
diff --git a/docs/html/design/patterns/actionbar.jd b/docs/html/design/patterns/actionbar.jd
index 939370c..f0104b5 100644
--- a/docs/html/design/patterns/actionbar.jd
+++ b/docs/html/design/patterns/actionbar.jd
@@ -1,5 +1,5 @@
 page.title=Action Bar
-page.tags="actionbar","navigation"
+page.tags=actionbar,navigation
 @jd:body
 
 <img src="{@docRoot}design/media/action_bar_pattern_overview.png">
@@ -182,7 +182,7 @@
 <p>
 
 <a onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Action Bar Icons (@actionbar page)']);"
-   href="{@docRoot}downloads/design/Android_Design_Icons_20130926.zip">Download the Action Bar Icon Pack</a>
+   href="{@docRoot}downloads/design/Android_Design_Icons_20131106.zip">Download the Action Bar Icon Pack</a>
 
 </p>
 
@@ -277,4 +277,4 @@
 <p>Sometimes it is important to display contextual information for your app that's always visible.
 Examples are the number of unread messages in a messaging inbox view or the Now Playing information
 in a music player. Carefully plan which important information you would like to display and
-structure your action bars accordingly.</p>
\ No newline at end of file
+structure your action bars accordingly.</p>
diff --git a/docs/html/design/patterns/app-structure.jd b/docs/html/design/patterns/app-structure.jd
index 1447d4e..e0a11ed 100644
--- a/docs/html/design/patterns/app-structure.jd
+++ b/docs/html/design/patterns/app-structure.jd
@@ -1,5 +1,5 @@
 page.title=App Structure
-page.tags="navigation","layout","tablet"
+page.tags=navigation,layout,tablet
 @jd:body
 
     <p>Apps come in many varieties that address very different needs. For example:</p>
@@ -307,4 +307,4 @@
 <li>
 <p>Allow for quick navigation between detail items with swipe views.</p>
 </li>
-</ul>
\ No newline at end of file
+</ul>
diff --git a/docs/html/design/patterns/buttons.jd b/docs/html/design/patterns/buttons.jd
new file mode 100644
index 0000000..2d65b2d
--- /dev/null
+++ b/docs/html/design/patterns/buttons.jd
@@ -0,0 +1,151 @@
+page.title=Buttons
+page.tags=buttons
+@jd:body
+
+<p>
+  Some content is best experienced full screen, like videos, games, image
+  galleries, books, and slides in a presentation. You can engage users more
+  deeply with content in full screen by minimizing visual distraction from app
+  controls and protecting users from escaping the app accidentally.
+</p>
+
+<div style="margin:auto;padding:auto;text-align:center;">
+    <img src="{@docRoot}design/media/fullscreen_landing.png" style="margin:1em auto 2em auto;">
+</div>
+<p>
+  In version 4.4, Android offers two approaches for making your app go full
+  screen: Lean Back and Immersive. In both approaches, all persistent system
+  bars are hidden. The difference between them is how the user brings the bars
+  back into view.
+</p>
+
+<div class="layout-content-row">
+  <div class="layout-content-col span-6">
+    <h4>Lean Back</h4>
+    <p>Touch the screen anywhere to bring back system bars. </p>
+    <img src="{@docRoot}design/media/fullscreen_leanback.png" style="width:311px;">
+  </div>
+  <div class="layout-content-col span-6">
+    <h4>Immersive</h4>
+    <p>Swipe from the any edge of the screen with a hidden bar to bring back system bars. </p>
+    <img src="{@docRoot}design/media/fullscreen_immersive_swipe_bottom.png" style="width:160px;float:right">
+    <img src="{@docRoot}design/media/fullscreen_immersive_swipe_top.png" style="width:160px">
+  </div>
+</div>
+
+<h2 id="leanback">
+  Lean Back
+</h2>
+
+<p>
+  The Lean Back approach is for full-screen experiences in which users won't be
+  interacting heavily with the screen while consuming content, like while
+  watching a video.
+</p>
+
+<p>
+  In this type of experience, users are leaning back and watching the screen.
+  Then, when they need to bring back the bars, they simply touch anywhere. This
+  gesture is easy and intuitive.
+</p>
+
+    <img src="{@docRoot}design/media/fullscreen_leanback.png" style="width:311px;">
+
+<h2 id="immersive">
+  Immersive
+</h2>
+
+<p>
+  The Immersive approach is mainly intended for apps in which the user will be
+  heavily interacting with the full screen as part of the primary experience.
+  Examples are games, viewing images in a gallery, or reading paginated
+  content, like a book or slides in a presentation.
+</p>
+
+<p>
+  In this type of experience, when users need to bring back the system bars,
+  they swipe from any edge where a system bar is hidden. By requiring this more
+  deliberate gesture, the user's deep engagement with your app won't be
+  interrupted by accidental touches and swipes.
+</p>
+
+<div class="layout-content-row">
+  <div class="layout-content-col span-6">
+    <img src="{@docRoot}design/media/fullscreen_immersive_swipe_bottom.png" style="width:160px;float:right">
+    <img src="{@docRoot}design/media/fullscreen_immersive_swipe_top.png" style="width:160px">
+  </div>
+</div>
+
+<p>
+  The user learns about the gesture to bring back the system bars through a
+  message that appears the first time the app goes full screen.
+</p>
+
+<p>
+  If your app has its own controls that aren't needed when a user is immersed
+  in content, make them disappear and reappear in sync with the system bars.
+  This rule also applies to any app-specific gestures you might have for hiding
+  and showing app controls. For example, if touching anywhere on the screen
+  toggles the appearance of an action bar or a palette, then it must also
+  toggle the appearance of system bars.
+</p>
+
+<p>
+  You might be tempted to use this approach just to maximize screen real
+  estate. But be mindful of how often users jump in and out of apps to check
+  notifications, do impromptu searches, and more. This approach will cause
+  users to lose easy access to system navigation, so a little extra space
+  should not be the only benefit they're getting in return.
+</p>
+
+<h2 id="variation_using_edges">
+  Variation: Swiping from edges with bars also affects the app
+</h2>
+
+<p>
+  In the Immersive approach, any time a user swipes from an edge with a system
+  bar, the Android framework takes care of revealing the system bars. Your app
+  won't even be aware that this gesture occurred.
+</p>
+
+<p>
+  But in some apps, the user might occasionally need to swipe from the edge as
+  <strong>part of the primary app experience</strong>. Examples are games and
+  drawing applications.
+</p>
+
+<p>
+  For apps with this requirement, you can use a variation on the Immersive
+  approach: when a user swipes from an edge with a system bar, system bars are
+  shown and the gesture is passed to the app so the app can respond to the
+  gesture.
+</p>
+
+<p>
+  For example, in a drawing app that uses this approach, if a user wants to
+  draw a line that begins at the very edge of the screen, swiping from the edge
+  would reveal the system bars and also start drawing a line that begins at the
+  very edge.
+</p>
+
+<p>
+  In this approach, to minimize disruption while a user is deeply engaged in
+  the app, the system bars are semi-transparent. The bars automatically
+  disappear after a few seconds of no interaction or as soon as the user
+  touches or gestures anywhere outside the system bars.
+</p>
+
+<h2 id="lightsout">What About Lights Out Mode?</h2>
+
+<p>
+  Before Android 4.4, the design guideline was to use Lights Out mode, a mode
+  in which the Action Bar and Status Bar fades away and becomes unavailable
+  after a few seconds of inactivity. The Navigation Bar is still available and
+  responds to touches but appears dimmed.
+</p>
+
+<p>
+  Replace previous implementations of Lights Out mode with the Lean Back or
+  Immersive approaches. Continue to use Lights Out mode for implementations of
+  your app targeted for earlier releases.
+</p>
diff --git a/docs/html/design/patterns/compatibility.jd b/docs/html/design/patterns/compatibility.jd
index 5ca6d8b..5a1562c 100644
--- a/docs/html/design/patterns/compatibility.jd
+++ b/docs/html/design/patterns/compatibility.jd
@@ -1,5 +1,5 @@
 page.title=Backwards Compatibility
-page.tags="support"
+page.tags=support
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}training/basics/supporting-devices/index.html">
diff --git a/docs/html/design/patterns/confirming-acknowledging.jd b/docs/html/design/patterns/confirming-acknowledging.jd
index e347231..d39d32d 100644
--- a/docs/html/design/patterns/confirming-acknowledging.jd
+++ b/docs/html/design/patterns/confirming-acknowledging.jd
@@ -1,5 +1,5 @@
 page.title=Confirming &amp; Acknowledging
-page.tags="dialog","toast","notification"
+page.tags=dialog,toast,notification
 @jd:body
 
 <p>In some situations, when a user invokes an action in your app, it's a good idea to <em>confirm</em> or <em>acknowledge</em> that action through text.</p>
@@ -67,4 +67,4 @@
     <p><strong>Acknowledgment is unnecessary</strong>. The user will know the app is gone from the Home Screen because they made it disappear by dragging it away.</p>
 
   </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/docs/html/design/patterns/fullscreen.jd b/docs/html/design/patterns/fullscreen.jd
index 191ca40..624d44c 100644
--- a/docs/html/design/patterns/fullscreen.jd
+++ b/docs/html/design/patterns/fullscreen.jd
@@ -1,5 +1,5 @@
 page.title=Full Screen
-page.tags="full screen","immersive", "leanback"
+page.tags=full screen,immersive,leanback
 @jd:body
 
 <p>
@@ -9,8 +9,9 @@
   controls and protecting users from escaping the app accidentally.
 </p>
 
+<div style="margin:auto;padding:auto;text-align:center;">
     <img src="{@docRoot}design/media/fullscreen_landing.png" style="margin:1em auto 2em auto;">
-
+</div>
 <p>
   In version 4.4, Android offers two approaches for making your app go full
   screen: Lean Back and Immersive. In both approaches, all persistent system
@@ -147,4 +148,4 @@
   Replace previous implementations of Lights Out mode with the Lean Back or
   Immersive approaches. Continue to use Lights Out mode for implementations of
   your app targeted for earlier releases.
-</p>
\ No newline at end of file
+</p>
diff --git a/docs/html/design/patterns/gestures.jd b/docs/html/design/patterns/gestures.jd
index 837a6dd..1ec7094 100644
--- a/docs/html/design/patterns/gestures.jd
+++ b/docs/html/design/patterns/gestures.jd
@@ -1,5 +1,5 @@
 page.title=Gestures
-page.tags="gesture","input","touch"
+page.tags=gesture,input,touch
 @jd:body
 
 <p>Gestures allow users to interact with your app by manipulating the screen objects you provide. The
@@ -65,8 +65,9 @@
   <div class="layout-content-col span-4">
     <img src="{@docRoot}design/media/gesture_doubletouch.png">
     <h4>Double touch </h4>
-    <p>Scales up the smallest targetable view, if available, or scales a standard amount
-      around the gesture. Also used as a secondary gesture for text selection.</p>
+    <p> Scales up a standard amount around the target with each repeated gesture until reaching
+    maximum scale. For nested views, scales up the smallest targetable view, or returns it to
+    its original scale. Also used as a secondary gesture for text selection.</p>
     <ul>
       <li class="no-bullet with-icon action">
         <h4>Action</h4>
diff --git a/docs/html/design/patterns/help.jd b/docs/html/design/patterns/help.jd
index ad5742d..bf708b1 100644
--- a/docs/html/design/patterns/help.jd
+++ b/docs/html/design/patterns/help.jd
@@ -1,5 +1,5 @@
 page.title=Help
-page.tags="settings","preferences"
+page.tags=settings,preferences
 @jd:body
 
 <p>We wish we could guarantee that if you follow every piece of advice on this website, everyone will be able to learn and use your app without a hitch. Sadly, that's not the case.</p>
@@ -110,4 +110,4 @@
 <p>People don't read help from start to finish. They scan around, looking for a piece of information containing the answer they need. Make it less burdensome with friendly formatting and layout choices like bold headings, bulleted and numbered lists, tables, and white space between paragraphs. And if you have a large amount of content, divide it into multiple screens to cut down on scrolling.</p>
 
 <h4>Take me straight to the answer</h4>
-<p>What's better than a screen that's easy to scan? A screen that requires no scanning at all because the answer's right there. Consider having each screen in your app navigate to help that's relevant just to that screen. We call this <em>contextual help</em>, and it's the holy grail of user assistance. If you take this approach, be sure to also provide a way to get to the rest of the help content.</p>
\ No newline at end of file
+<p>What's better than a screen that's easy to scan? A screen that requires no scanning at all because the answer's right there. Consider having each screen in your app navigate to help that's relevant just to that screen. We call this <em>contextual help</em>, and it's the holy grail of user assistance. If you take this approach, be sure to also provide a way to get to the rest of the help content.</p>
diff --git a/docs/html/design/patterns/multi-pane-layouts.jd b/docs/html/design/patterns/multi-pane-layouts.jd
index 06c8189..ff2dd4e 100644
--- a/docs/html/design/patterns/multi-pane-layouts.jd
+++ b/docs/html/design/patterns/multi-pane-layouts.jd
@@ -1,5 +1,5 @@
 page.title=Multi-pane Layouts
-page.tags="tablet","navigation","layout","fragment"
+page.tags=tablet,navigation,layout,fragment
 @jd:body
 
 
diff --git a/docs/html/design/patterns/navigation-drawer.jd b/docs/html/design/patterns/navigation-drawer.jd
index bf6609e..7e63ba6c 100644
--- a/docs/html/design/patterns/navigation-drawer.jd
+++ b/docs/html/design/patterns/navigation-drawer.jd
@@ -1,5 +1,5 @@
 page.title=Navigation Drawer
-page.tags="DrawerLayout","SlidingPaneLayout"
+page.tags=DrawerLayout,SlidingPaneLayout
 @jd:body
 
 
diff --git a/docs/html/design/patterns/navigation.jd b/docs/html/design/patterns/navigation.jd
index 6f2215a..08828e8 100644
--- a/docs/html/design/patterns/navigation.jd
+++ b/docs/html/design/patterns/navigation.jd
@@ -1,5 +1,5 @@
 page.title=Navigation with Back and Up
-page.tags="navigation","activity","task","up navigation","back navigation"
+page.tags=navigation,activity,task,up navigation,back navigation
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}training/implementing-navigation/index.html">
diff --git a/docs/html/design/patterns/new.jd b/docs/html/design/patterns/new.jd
index 50cb950..d672e46 100644
--- a/docs/html/design/patterns/new.jd
+++ b/docs/html/design/patterns/new.jd
@@ -1,5 +1,5 @@
 page.title=New in Android
-page.tags="KitKat", "Android 4.4"
+page.tags=KitKat,Android 4.4
 @jd:body
 
 
diff --git a/docs/html/design/patterns/selection.jd b/docs/html/design/patterns/selection.jd
index 973ffde..ee46795 100644
--- a/docs/html/design/patterns/selection.jd
+++ b/docs/html/design/patterns/selection.jd
@@ -1,5 +1,5 @@
 page.title=Selection
-page.tags="actionmode","navigation","contextual"
+page.tags=actionmode,navigation,contextual
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/menus.html#context-menu">
diff --git a/docs/html/design/patterns/settings.jd b/docs/html/design/patterns/settings.jd
index fa3e538..a09193d 100644
--- a/docs/html/design/patterns/settings.jd
+++ b/docs/html/design/patterns/settings.jd
@@ -1,5 +1,5 @@
 page.title=Settings
-page.tags="preferences","sharedpreferences"
+page.tags=preferences,sharedpreferences
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/settings.html">
@@ -696,4 +696,4 @@
 <li><p>Use design patterns wherever applicable so users don't face a learning curve.</p></li>
 <li><p>Choose defaults that are safe, neutral, and fit the majority of users.</p></li>
 <li><p>Give each setting a clear, concise label and use secondary text appropriately.</p></li>
-</ul>
\ No newline at end of file
+</ul>
diff --git a/docs/html/design/patterns/swipe-views.jd b/docs/html/design/patterns/swipe-views.jd
index 4c9fb88..89397ae 100644
--- a/docs/html/design/patterns/swipe-views.jd
+++ b/docs/html/design/patterns/swipe-views.jd
@@ -1,5 +1,5 @@
 page.title=Swipe Views
-page.tags="viewpager","navigation","tabs"
+page.tags=viewpager,navigation,tabs
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}training/implementing-navigation/lateral.html">
diff --git a/docs/html/design/patterns/widgets.jd b/docs/html/design/patterns/widgets.jd
index 87ebbb9..953c125 100644
--- a/docs/html/design/patterns/widgets.jd
+++ b/docs/html/design/patterns/widgets.jd
@@ -1,5 +1,5 @@
 page.title=Widgets
-page.tags="appwidget","home"
+page.tags=appwidget,home
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/appwidgets/index.html">
diff --git a/docs/html/design/style/branding.jd b/docs/html/design/style/branding.jd
index 9ef934d..2353a93 100644
--- a/docs/html/design/style/branding.jd
+++ b/docs/html/design/style/branding.jd
@@ -1,5 +1,5 @@
 page.title=Your Branding
-page.tags="branding","logo"
+page.tags=branding,logo
 @jd:body
 
 <p>Following Android design patterns doesn't mean that your app has to look the same as
@@ -49,16 +49,16 @@
 <div class="vspace size-1">&nbsp;</div>
 
 <div class="layout-content-row">
-  <div class="layout-content-col span-6">
-        <img src="{@docRoot}design/media/yourbranding_icon.png" style="width:60px;float:left;padding-right:1em;">
-    <div class="figure-caption" style="widdth:220px;margin-left:20px;">
-    The HowzAbout app uses a launcher icon that is a shortened version of its full logo.
+  <div class="layout-content-col span-6" style="padding-top:24px;">
+        <img src="{@docRoot}design/media/branding_launcher_icon.png" style="width:60px;float:left;padding-right:1em;">
+    <div class="figure-caption" style="width:290px;margin-left:20px;">
+    Google+ reinforces its brand by carrying its launcher icon through to the action bar.
     </div>
-
+        <img src="{@docRoot}design/media/branding_logo_icon_action_bar.png" style="width:320px;float:left;padding-right:1em;">
   </div>
   <div class="layout-content-col span-6">
-    <img src="{@docRoot}design/media/yourbranding_app.png" style="width:94%">
-    <div class="figure-caption">
+    <img src="{@docRoot}design/media/yourbranding_app.png" style="width:320px;">
+    <div class="figure-caption" style="width:320px;">
       Example of a the logo in the action bar. This works well in cases where the brand's logo matches the name of the app.
     </div>
   </div>
@@ -77,7 +77,7 @@
   </div>
 
   <div class="layout-content-col span-6">
-    <img src="{@docRoot}design/media/yourbranding_in-app-icons.png" style="width:300px;margin:12px 48px 0 16px;"">
+    <img src="{@docRoot}design/media/yourbranding_in-app-icons.png" style="width:300px;margin:12px 48px 0 16px;">
     </div>
   </div>
 </div>
@@ -100,9 +100,9 @@
 
     <div style="margin-bottom:1em;">
       <span class="do-dont-label bad" style="margin-left:12px">Don't</span>
-      <span style="margin-left: 44px;"  class="do-dont-label good"><strong>Do</strong></span>
+      <span style="margin-left: 64px;"  class="do-dont-label good"><strong>Do</strong></span>
     </div>
-      <img src="{@docRoot}design/media/yourbranding_sharing.png" style="width:200px;">
+      <img src="{@docRoot}design/media/yourbranding_sharing.png" style="width:180px;">
   </div>
 </div>
 
diff --git a/docs/html/design/style/iconography.jd b/docs/html/design/style/iconography.jd
index b0a3439..5dde600 100644
--- a/docs/html/design/style/iconography.jd
+++ b/docs/html/design/style/iconography.jd
@@ -1,5 +1,5 @@
 page.title=Iconography
-page.tags="icons"
+page.tags=icons
 @jd:body
 
 <img src="{@docRoot}design/media/iconography_overview.png">
@@ -139,7 +139,7 @@
 </p>
 <p>
 <a onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Action Bar Icons (@iconography page)']);"
-   href="{@docRoot}downloads/design/Android_Design_Icons_20130926.zip">Download the Action Bar Icon Pack</a>
+   href="{@docRoot}downloads/design/Android_Design_Icons_20131106.zip">Download the Action Bar Icon Pack</a>
 </p>
 
 <div class="layout-content-row">
diff --git a/docs/html/design/style/metrics-grids.jd b/docs/html/design/style/metrics-grids.jd
index c375631..a553475 100644
--- a/docs/html/design/style/metrics-grids.jd
+++ b/docs/html/design/style/metrics-grids.jd
@@ -1,5 +1,5 @@
 page.title=Metrics and Grids
-page.tags="layout","screens"
+page.tags=layout,screens
 @jd:body
 
 <p>Devices vary not only in physical size, but also in screen density (<acronym title="Dots per
diff --git a/docs/html/design/style/touch-feedback.jd b/docs/html/design/style/touch-feedback.jd
index a5bf7b3..9f36fed 100644
--- a/docs/html/design/style/touch-feedback.jd
+++ b/docs/html/design/style/touch-feedback.jd
@@ -1,5 +1,5 @@
 page.title=Touch Feedback
-page.tags="input","button"
+page.tags=input,button
 @jd:body
 
     <div class="layout-content-row" style="margin-bottom: -100px">
@@ -7,8 +7,6 @@
 
 <p>Use illumination and dimming to respond to touches, reinforce the resulting behaviors
 of gestures, and indicate what actions are enabled and disabled.</p>
-<p>Whenever a user touches an actionable area in your app, provide a subtle visual response.
-This lets the user know which object was touched and that your app is "listening".</p>
 
 <p><strong>Be responsive to touches in a gentle way</strong>. Whenever a user touches an
 actionable area in your app, let them know the app is "listening" by providing a visual
@@ -22,27 +20,16 @@
 easier because the default touch feedback works with whatever hue you choose.</li>
 </ul>
 
-  </div>
+</div>
 
-  <div class="layout-content-col span-6" style="float:right;">
-
-   <!-- <div class="framed-nexus5-port-span-5">
-      <video class="play-on-hover" autoplay>
-        <source src="{@docRoot}design/media/calendar.mp4" type="video/mp4">
-        <source src="{@docRoot}design/media/calendar.webm" type="video/webm">
-        <source src="{@docRoot}design/media/calendar.ogv" type="video/ogg">
-      </video>
-    </div>
-    <div class="figure-caption" style="margin-top:0">
-      <div class="video-instructions">&nbsp;</div>
-    </div>
-  </div> -->
-
-
-  <div class="layout-content-col span-6">
-
-    <img src="{@docRoot}design/media/touch_feedback_reaction_response.png">
-
+<div class="layout-content-col span-6" style="float:right;">
+  <video  class="play-on-hover" width="268" height="442" autoplay style="border:1px solid #ddd;background-color:#f9f9f9;" poster="">
+    <source src="{@docRoot}design/media/touch_feedback.mp4" type="video/mp4">
+    <source src="{@docRoot}design/media/touch_feedback.webm" type="video/webm">
+    <source src="{@docRoot}design/media/touch_feedback.ogv" type="video/ogg">
+  </video>
+  <div class="figure-caption">
+    <div style="color:#a3a3a3;margin-left:130px;"><em>Click image to replay...</em></div>
   </div>
 </div>
 
@@ -96,4 +83,4 @@
   widgets, like lists and grid lists, have support for boundary feedback built
   in. If you’re building custom widgets, keep boundary feedback in mind and
   provide it from within your app.
-</p>
\ No newline at end of file
+</p>
diff --git a/docs/html/design/style/typography.jd b/docs/html/design/style/typography.jd
index 3c201f7..ec6fba2 100644
--- a/docs/html/design/style/typography.jd
+++ b/docs/html/design/style/typography.jd
@@ -1,5 +1,5 @@
 page.title=Typography
-page.tags="textview","font"
+page.tags=textview,font
 @jd:body
 
 <div class="layout-content-row">
diff --git a/docs/html/design/style/writing.jd b/docs/html/design/style/writing.jd
index cda17eb..4f62253 100644
--- a/docs/html/design/style/writing.jd
+++ b/docs/html/design/style/writing.jd
@@ -1,5 +1,5 @@
 page.title=Writing Style
-page.tags="dialog","toast","notification"
+page.tags=dialog,toast,notification
 @jd:body
 
 <h2 id="voa">Android's Voice</h2>
@@ -319,4 +319,4 @@
         ellipsis. </li>
     </ul>
   </li>
-</ul>
\ No newline at end of file
+</ul>
diff --git a/docs/html/develop/index.jd b/docs/html/develop/index.jd
index 61a98b7..3f88b9d 100644
--- a/docs/html/develop/index.jd
+++ b/docs/html/develop/index.jd
@@ -3,6 +3,7 @@
 header.hide=1
 carousel=1
 tabbedList=1
+excludeFromSuggestions=true
 @jd:body
 
 <style>
diff --git a/docs/html/distribute/distribute_toc.cs b/docs/html/distribute/distribute_toc.cs
index ecdf2a8..1fabcb3 100644
--- a/docs/html/distribute/distribute_toc.cs
+++ b/docs/html/distribute/distribute_toc.cs
@@ -81,6 +81,7 @@
     <ul>
        <li><a href="<?cs var:toroot ?>distribute/googleplay/spotlight/tablets.html">Tablet Stories</a></li>
        <li><a href="<?cs var:toroot ?>distribute/googleplay/spotlight/games.html">Game Stories</a></li>
+       <li><a href="<?cs var:toroot ?>distribute/googleplay/spotlight/localization.html">Localization Stories</a></li>
     </ul>
   </li> 
 
@@ -90,6 +91,7 @@
       <li><a href="<?cs var:toroot ?>distribute/googleplay/edu/about.html">About</a></li>
       <li><a href="<?cs var:toroot ?>distribute/googleplay/edu/start.html">Get Started</a></li>
       <li><a href="<?cs var:toroot ?>distribute/googleplay/edu/guidelines.html">Guidelines</a></li>
+      <li><a href="<?cs var:toroot ?>distribute/googleplay/edu/faq.html">FAQ</a></li>
       <li><a href="<?cs var:toroot ?>distribute/googleplay/edu/contact.html">Sign Up</a></li>
     </ul>  
   </li>
diff --git a/docs/html/distribute/googleplay/edu/about.jd b/docs/html/distribute/googleplay/edu/about.jd
index cc131c64..20a0d4d 100644
--- a/docs/html/distribute/googleplay/edu/about.jd
+++ b/docs/html/distribute/googleplay/edu/about.jd
@@ -3,26 +3,25 @@
 excludeFromSuggestions=true
 @jd:body
 
-<div style="position:absolute;margin-left: 636px;
+    <div style="position:absolute;margin-left: 636px;
             margin-top:-76px;color:#777;">If you're interested<br>
             <a href="{@docRoot}distribute/googleplay/edu/contact.html"
             class="go-link"
             style="display: block;text-align: right;">SIGN UP</a></div>
 
     <div style="float:right;margin:0px 0px 24px 44px;">
-  <img src="{@docRoot}images/gp-edu-knum-landscape.png" style="width:420px" alt="" />
+  <img src="{@docRoot}images/gp-edu-apps-n7.jpg" style="width:420px" alt="" />
 </div>
 
 <p>Introducing Google Play for Education, the online destination where schools
 can find the right tablet content and tools for their students and teachers.</p>
 
-<p>With easy bulk ordering for groups, schools will be able to purchase and
-instantly distribute apps, videos, and books right to their students’
+<p>With easy bulk ordering for groups, schools can purchase and
+instantly distribute your apps, and videos right to their students’
 devices.</p>
 
-<p>The Google Play team looks forward to seeing you create first class content
-that will help schools. We want to help you create innovative educational apps,
-without having to knock on school doors to reach teachers and students.</p>
+<p>Google Play for Education can help your innovative educational apps
+gain visibility with the right audiences, without having to knock on school doors. </p>
 
 <p><a class="landing-page-link" style="text-align:right;" href="#video">Watch a Video</a></p>
 
@@ -32,36 +31,36 @@
 
 <h4>Get discovered</h4>
 
-<p>With Google Play for Education, teachers and administrators will be able to
+<p>With Google Play for Education, teachers and administrators can
 browse content by curriculum, grade, and standard &mdash; discovering the right
-content at the right time for their students. If your app offers an exciting new
-way to learn sixth grade algebra, we'll make it easy for math educators to find,
-purchase, and distribute your app to their classes.</p>
+content for their students. If your app offers an exciting new
+way to learn sixth grade algebra, math educators will be able to find,
+purchase, and distribute your app to their classes in a few clicks.</p>
 
 <h4>Reach more schools and students</h4>
 
-<p>Google has built a strong network of K-12 schools who are already using
-Google Apps for Education and other Google services. These schools are excited
-and looking forward to bringing your apps and content into their classrooms with
-Nexus tablets.</p>
+<p>Over 30 million students, faculty, and staff are already using
+Google Apps for Education and other Google services. Many of these schools are
+excited to take advantage of tablets with Google Play for Education and they
+look to bringing your apps into their classrooms,
+especially apps using Google sign-on.</p>
 
 <h4>Monetize effectively</h4>
-<p>With the wide launch of Google Play for Education later this year, educators
-will be able to make high-volume purchases using standard institutional payment
-mechanisms and distribute them to the students they want &mdash; whether it is a
-class of 30 or a district of 30,000.</p>
-
+<p>With Google Play for Education, educators are able to make high-volume purchases
+using standard institutional payment mechanisms and distribute them to the students
+they want &mdash; whether it is a class of 20 or a district of 20,000.</p>
+<code></code>
   </div>
 
   <div class="col-6 normal-links">
     <h3 style="clear:left">For Educators</h3>
     <h4>Android tablets in the classroom</h4>
     <p>Google Play for Education brings the innovation of Android technology
-into classrooms. Educators can set up and deploy large numbers of devices in
+into classrooms. School districts can set up and deploy large numbers of devices in
 just minutes or hours rather than days.</p>
 
     <h4>Curriculum-based discovery</h4>
-    <p>Powerful browsing tools let educators quickly discover apps, books,
+    <p>Powerful browsing tools let educators quickly discover apps,
 videos, and other content&mdash;with many recommended by teachers and
 categorized according to familiar Core Curriculum standards.  
 
diff --git a/docs/html/distribute/googleplay/edu/contact.jd b/docs/html/distribute/googleplay/edu/contact.jd
index 804d925..ca83438 100644
--- a/docs/html/distribute/googleplay/edu/contact.jd
+++ b/docs/html/distribute/googleplay/edu/contact.jd
@@ -5,11 +5,7 @@
 
 <p>We're looking forward to improving how students learn in the classroom as we
 bring your first-class educational content into schools across the United
-States, and to a broader international audience in the future. We'll soon share
-more information about Google Play for Education and our services that will help
-teachers and administrators buy, deploy, and use apps. </p>
-
-
+States, and to a broader international audience in the future. </p>
 
 <div class="vspace size-1">
   &nbsp;
@@ -35,8 +31,8 @@
     <p>
 If you're a school or system interested in tablets and Google Play for Education,
 complete the expression of interest form at <a href="http://www.google.com/edu/android">www.google.com/edu/android</a>.
-We'll be in touch later in the year as the program launches widely to schools.
   </p><a href="http://www.google.com/edu/android">School Interest Form »</a>
   </div>
 </div>
 
+
diff --git a/docs/html/distribute/googleplay/edu/faq.jd b/docs/html/distribute/googleplay/edu/faq.jd
new file mode 100644
index 0000000..6afc107
--- /dev/null
+++ b/docs/html/distribute/googleplay/edu/faq.jd
@@ -0,0 +1,372 @@
+page.title=Google Play for Education FAQ
+page.metaDescription=Questions and answers about Google Play for Education.
+excludeFromSuggestions=true
+@jd:body
+
+     <div style="position:absolute;margin-left: 636px;
+            margin-top:-76px;color:#777;">If you're interested<br>
+            <a href="{@docRoot}distribute/googleplay/edu/contact.html"
+            class="go-link"
+            style="display: block;text-align: right;">SIGN UP</a></div>
+    
+ 
+    <style>
+  dt {
+    font-weight:bold;
+  }
+  </style>
+  
+<div id="qv-wrapper">
+<ol id="qv">
+<h2>In this document</h2>
+<ol>
+  <li><a href="#business">Business Model</a></li>
+  <li><a href="#free_trials">Free Trials</a></li>
+  <li><a href="#discovery">Discovery</a></li>
+  <li><a href="#reviews">App Review Process</a></li>
+  <li><a href="#features">App Features</a></li>
+  <li><a href="#marketing">Marketing and ROI</a></li>
+  <li><a href="#devices">Devices</a></li>
+  <li><a href="#accounts">Accounts</a></li>
+</ol>
+</div>
+
+<p>
+  The sections below provide more information about Google Play for Education
+  and answer common questions that you might have about it.
+</p>
+
+
+<h2 id="business">Business Model and Monetization</h2>
+
+<dl>
+  <dt>
+    What is Google Play for Education?
+  </dt>
+
+  <dd>
+    Google Play for Education is a new online destination designed for schools.
+    Teachers can discover educational apps, books, and videos to meet the needs
+    of a single student, a classroom, or a whole district. Educators can browse
+    apps by grade, subject, keyword, or standard including common core.
+    Purchasing is done via PO with no credit card required. Apps are
+    distributed to tablets instantly via the cloud.
+  </dd>
+
+  <dt>
+    Is Google Play for Education primarily for students or educators?
+  </dt>
+
+  <dd>
+    The store on Google Play for Education is for educators, but its content is
+    for both educators and students. Teachers and administrators have the
+    ability to make purchases and control who within their school has access to
+    the purchase flows.
+  </dd>
+
+  <dt>
+    Will Google Play for Education support subscription purchases?
+  </dt>
+
+  <dd>
+    Currently, Google Play for Education supports one-time purchases. We are
+    investigating additional purchase mechanisms to enable more flexible
+    pricing models for developers and schools.
+  </dd>
+
+  <dt>
+    Why is it recommended to disable in-app purchases?
+  </dt>
+
+  <dd>
+    In-app purchase is currently not supported with Google Play for Education,
+    and a student device will block the Play transaction if a student attempts
+    to make an in-app purchase. To avoid student confusion in the classroom,
+    also recommend not including any in-app purchase buttons and other UI in
+    your application. We are investigating additional purchase mechanisms to
+    enable more flexible pricing models for developers and schools.
+  </dd>
+
+  <dt>
+    Is Google Play for Education restricted so only its users can purchase from
+    the Google Play for Education? Or will anyone be able to purchase from it?
+  </dt>
+
+  <dd>
+    Currently, only schools that are signed up for Google Play for Education
+    can make purchases on it.
+  </dd>
+
+  <dt>
+    Is there a way to differentiate an app's pricing between Google Play for
+    Education and Google Play?
+  </dt>
+
+  <dd>
+    For each app that you publish, you can set a single price that applies to
+    both Google Play and Google Play for Education &mdash. You can’t set a
+    different price for a given app (based on a single package name) in Google
+    Play for Education.
+  </dd>
+</dl>
+
+
+<h2 id="free_trials">Free Trials</h2>
+
+<dl>
+  <dt>
+    Can I offer free trials through Google Play for Education?
+  </dt>
+
+  <dd>
+    Google Play for Education doesn't currently support free trials. If you
+    want, you can offer a free version of your app with limited functionality
+    in Google Play for Education, but that app would need to be separate from
+    your paid app and be reviewed separately for educational content.
+  </dd>
+
+  <dt>
+    Can I offer a free trial through Google Play's "In-app Subscriptions with
+    Free Trials" feature?
+  </dt>
+
+  <dd>
+    Google Play for Education does not currently support In-app Billing or
+    In-app Subscriptions with free trials.
+  </dd>
+</dl>
+
+
+<h2 id="discovery">Discovery</h2>
+
+<dl>
+  <dt>
+    What are the categories in Google Play for Education?
+  </dt>
+
+  <dd>
+    Google Play for Education includes categories for all grade levels from
+    Kindergarten to 12 and the following subjects: English Language Arts, World
+    Languages, Mathematics, Science, Social Science, Elective, OER (Open
+    Education Resources), and Tools.
+  </dd>
+
+  <dt>
+    I created an app specifically for Google Play for Education and do not want
+    it to show up in Google Play. Is this possible?
+  </dt>
+
+  <dd>
+    Currently, it is not possible to publish an app Google Play for Education
+    and make it unavailable on Google Play.
+  </dd>
+
+  <dt>
+    If my app offers content for every level of education, how will it fit the
+    common-core standard filters?
+  </dt>
+
+  <dd>
+    If your app applies to multiple levels of education, then the app will show
+    up filtered results for in multiple levels.
+  </dd>
+</dl>
+
+
+<h2 id="reviews">App Review Process</h2>
+
+<dl>
+  <dt>
+    How are apps being reviewed? By whom and with what criteria?
+  </dt>
+
+  <dd>
+    Apps are being reviewed by a third party network of educators. These
+    educators assign the appropriate subject, grade, and common core standards
+    metadata, as well as evaluating whether the app meets the Google Play for
+    Education <a href=
+    "{@docRoot}distribute/googleplay/edu/guidelines.html">criteria for
+    classroom use</a>. You can learn more about the submission process and
+    criteria at <a href=
+    "http://developer.android.com/edu">developer.android.com/edu</a>.
+  </dd>
+
+  <dt>
+    How do I update my apps in Google Play for Education?
+  </dt>
+
+  <dd>
+    Developers can update their apps on Google Play for Education in the same
+    manner that they do for Google Play. App updates will not be reviewed prior
+    to being made available through Play for Education. However, we will
+    periodically review updated apps for quality.
+  </dd>
+
+  <dt>
+    Does the app maturity rating reflect solely what a user can do within my
+    Android app, or does the web version of my app influence the rating as
+    well?
+  </dt>
+
+  <dd>
+    The maturity rating that you set for your Android app refers only to the
+    content displayed in that application.
+  </dd>
+</dl>
+
+
+<h2 id="features">App Features</h2>
+
+<dl>
+  <dt>
+    Do I need separate builds of my phone and tablet apps for Google Play for
+    Education, or is it the exact same app that lives on Google Play?
+  </dt>
+
+  <dd>
+    We recommend you create one app and use it in both Google Play and Google
+    Play for Education.
+  </dd>
+
+  <dt>
+    What is the best way to get students’ work within apps sent back to their
+    teachers?
+  </dt>
+
+  <dd>
+    Many teachers have mentioned that the way apps treat this now is via an
+    email from a third party, which is not optimal for schools. As many schools
+    use Google Apps for Education, consider integrating your app with Google
+    Drive using the SDK which can be found here: <a class="external-link" href=
+    "https://developers.google.com/drive/about-sdk">developers.google.com/drive/about-sdk</a>.
+  </dd>
+
+  <dt>
+    How can developers test the teacher experience in Google Play for
+    Education? Is there a way to get an account to test it?
+  </dt>
+
+  <dd>
+    Currently, we are unable to provide developers with a test account to test
+    the Google Play for Education user experience. We are investigating ways to
+    allow developers to simulate the environment.
+  </dd>
+
+  <dt>
+    If I already have an app in the Chrome Apps Pack will I get some help
+    migrating this to Android?
+  </dt>
+
+  <dd>
+    If you’d like to reach users of Nexus tablets for schools we encourage you
+    to build a native app for the optimal user experience. Considerations for
+    building your app and instructions for registering it can be found at
+    <a href="http://developer.android.com/edu">developer.android.com/edu</a>.
+  </dd>
+</dl>
+
+
+<h2 id="marketing">Marketing and ROI</h2>
+
+<dl>
+  <dt>
+    What are you doing to promote these apps to educators?
+  </dt>
+
+  <dd>
+    Google Play for Education is an extension of Google Play targeting schools
+    and making discovery easier for educational apps. It helps your apps gain
+    visibility with the right audiences, without having to knock on school
+    doors. We are constantly referring to the highest quality apps in our
+    educator outreach. We have also developed a series of collections to help
+    educators quickly browse apps for the most common use cases.
+  </dd>
+
+  <dt>
+    How many installs have similar apps had on Play? How much can I expect to
+    make if I do an ROI analysis?
+  </dt>
+
+  <dd>
+    While we cannot disclose specific numbers, Google Play app listings provide
+    app download ranges for all apps.
+  </dd>
+
+  <dt>
+    What is the seasonality like for the education market? What are the key
+    timing considerations for app developers?
+  </dt>
+
+  <dd>
+    In the United States, school districts’ budget decisions go through a
+    planning phase in the Spring with budgets being released on July 1. We have
+    observed high purchase-volumes in the second quarter of the calendar year,
+    using up end-of-year budgets. New budget purchases begin in the third
+    quarter of the calendar year.
+  </dd>
+
+  <dt>
+    Is there a way to offer a special deal, such as a discount, only on Google
+    Play for Education and not on Google Play?
+  </dt>
+
+  <dd>
+    No, this is not possible. Pricing, including special offers, must be the
+    same between Google Play for Education and Google Play.
+  </dd>
+</dl>
+
+
+<h2 id="devices">Devices</h2>
+
+<dl>
+  <dt>
+    Which devices are available in the program? Will more be available?
+  </dt>
+
+  <dd>
+    Nexus 7 is available for shipment now, and the Asus Transformer will be
+    available in early 2014. We look forward to welcoming more Android devices
+    into the Google in Education family soon.
+  </dd>
+
+  <dt>
+    Can the devices be shared among many students?
+  </dt>
+
+  <dd>
+    No. Currently, this program is for one-to-one usage. Each student can login
+    to one specific tablet that is allocated to them.
+  </dd>
+</dl>
+
+
+<h2 id="accounts">
+  Accounts
+</h2>
+
+<dl>
+  <dt>
+    Will an app know whether a user is a teacher or student?
+  </dt>
+
+  <dd>
+    No, the app has no mechanism for knowing if it is running on a teacher’s
+    device or a student’s device. We recommend developers use their own user
+    database to enable this feature, where logins can be based on Google
+    Account information.
+  </dd>
+
+  <dt>
+    What log-in method do you recommend for an app on Google Play for
+    Education?
+  </dt>
+
+  <dd>
+    One of the key pieces of feedback we have heard multiple times from various
+    schools is that they prefer apps that offer Google Single Sign-on, so that
+    teachers and students do not need to remember multiple log-in credentials.
+    As schools in the program use Google Accounts and Google Apps for
+    Education, offering Google Single Sign-on is ideal.
+  </dd>
+</dl>
\ No newline at end of file
diff --git a/docs/html/distribute/googleplay/edu/guidelines.jd b/docs/html/distribute/googleplay/edu/guidelines.jd
index c1d3065..c4b719b 100644
--- a/docs/html/distribute/googleplay/edu/guidelines.jd
+++ b/docs/html/distribute/googleplay/edu/guidelines.jd
@@ -3,18 +3,16 @@
 excludeFromSuggestions=true
 @jd:body
 
-<div style="position:absolute;margin-left: 636px;
+   <div style="position:absolute;margin-left: 636px;
             margin-top:-76px;color:#777;">If you're interested<br>
             <a href="{@docRoot}distribute/googleplay/edu/contact.html"
             class="go-link"
             style="display: block;text-align: right;">SIGN UP</a></div>
 
-<div
-style="background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">You
-can now include your apps in the Google Play for Education <a
-href="{@docRoot}distribute/googleplay/edu/start.html#program">pilot program</a>,
-getting it into the hands of participating schools and key influencers in the
-education technology community. See <a href="start.html">Get Started</a> to
+<div style="background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">You
+can now include your educational apps in the recently launched Google Play for Education program,
+getting it into the hands of participating schools and key influencers in the education technology
+community. See <a href="start.html">Get Started</a> to
 learn how to participate. </div>
 
 <p>The sections below list the guidelines and requirements for apps
@@ -28,8 +26,8 @@
 intuitive user experience on Android tablets.</p>
 
 <p>In addition, ensure that your app complies with the terms of a <a
-href="https://play.google.com/about/developer-distribution-agreement-addendum.
-html" target="_policies">Google Play for Education Addendum</a>, as well as
+href="https://play.google.com/about/developer-distribution-agreement-addendum.html"
+target="_policies">Google Play for Education Addendum</a>, as well as
 the standard  <a
 href="http://play.google.com/about/developer-content-policy.html"
 target="_policies">Google Play Developer Program Policies</a> and <a
@@ -229,14 +227,9 @@
 <ul>
 <li><em>Android version</em> &mdash; Test the app on devices running Android
 4.2. Google Play for Education devices will be running Android 4.2 or higher
-(API level 17).</li>
+(API level 17+).</li>
 <li><em>Proxy server</em> &mdash; Test the app in network environment that uses
 proxies. Many schools use proxies.</li>
-<li><em>Secondary user account</em> &mdash; Test the app using a secondary user
-account. Most Google Play for Education users will not be using the primary <a
-href="{@docRoot}about/versions/jelly-bean.html#42-multiuser">multiuser</a>
-account on their devices. For testing, create a secondary multiuser account on
-your tablet.</li>
 <li><em>No location services</em> &mdash; Test the app to make sure it works
 properly with location services disabled. Many schools will disable location
 services for student devices.</li>
@@ -249,4 +242,3 @@
 <li><em>No access to network</em> &mdash; Test the app to make sure it works
 properly when the device cannot connect to the internet. </li>
 </ul>
-
diff --git a/docs/html/distribute/googleplay/edu/index.jd b/docs/html/distribute/googleplay/edu/index.jd
index de5fe35..a27f82f 100644
--- a/docs/html/distribute/googleplay/edu/index.jd
+++ b/docs/html/distribute/googleplay/edu/index.jd
@@ -1,5 +1,5 @@
 page.title=Google Play for Education
-page.tags="Google Play","education","schools", "distribution"
+page.tags=Google Play,education,schools,distribution
 header.hide=1
 
 @jd:body
@@ -10,20 +10,21 @@
             style="display: block;text-align: right;">SIGN UP</a></div>
 
    <div class="marquee">
-  <div class="mainimg" style="position:absolute;margin-left:6px;margin-top:96px;">
-    <img src="{@docRoot}images/gp-edu-hero7.png" style="width:590px;">
+  <div class="mainimg" style="position:absolute;margin-left:34px;margin-top:57px;">
+    <img src="{@docRoot}images/gp-edu-hero14.jpg" style="width:670px;" />
   </div>
-  <div class="copy" style="position:relative;left:314px;margin-top:42px;width:420px;">
+  <div class="copy" style="position:relative;left:334px;margin-top:28px;width:420px;">
     <h1 style="margin-bottom:10px;">Google Play for Education</h1>
-    <p>A destination where schools can find great&nbsp;educational content in Google Play. 
-    Bulk&nbsp;purchase and instant distribution let&nbsp;educators bring your apps directly
-    to&nbsp;classrooms and schools.</p>
-    <p><a class="button" href="{@docRoot}distribute/googleplay/edu/about.html"
-      >Read More</a></p>
+    <p>Google Play for Education is a destination where schools can find great,
+    teacher-approved, educational apps and videos on Play Store. Teachers can filter
+    content by subject matter, grade and other criteria. Bulk purchase and instant
+    distribution let educators bring your apps directly to classrooms and schools.</p>
+    <p>If you have an educational app, join Google Play for Education.</p>
+    <p><a class="button" href="{@docRoot}distribute/googleplay/edu/about.html">Learn More</a></p>
   </div>
 </div>
 
-<div class="distribute-features col-13" style="clear:both;margin-top:253px;">
+<div class="distribute-features col-13" style="clear:both;margin-top:248px;">
   <div class="distribute-link">
   <ul>
     <li><a href="{@docRoot}distribute/googleplay/edu/about.html"><h5>About the Initiative</h5>
@@ -31,14 +32,16 @@
     <li><a href="{@docRoot}distribute/googleplay/edu/start.html"><h5>Get your Apps Ready</h5> 
     Follow these guidelines to make sure your app meets requirements and offers a great user experience. </a>
     </li>
-    <li class="last"><a href="{@docRoot}distribute/googleplay/edu/contact.html"><h5>Sign Up</h5>
-    Sign up here to be notified of the latest information regarding this program.</a>
+    <li class="last"><a href="{@docRoot}distribute/googleplay/edu/start.html#opt-in"><h5>Submit your App</h5>
+    Use the Google Play Developer Console to mark your app for inclusion in the program and review by third-party
+    educators. </a>
     </li>
   </ul>
   </div>
 
 </div>
 
+
     
 
 
diff --git a/docs/html/distribute/googleplay/edu/start.jd b/docs/html/distribute/googleplay/edu/start.jd
index 78b8739..01d4406 100644
--- a/docs/html/distribute/googleplay/edu/start.jd
+++ b/docs/html/distribute/googleplay/edu/start.jd
@@ -3,18 +3,19 @@
 excludeFromSuggestions=true
 @jd:body
 
-<div style="position:absolute;margin-left: 636px;
+    <div class="jd-descr" itemprop="articleBody">
+    <div style="position:absolute;margin-left: 636px;
             margin-top:-76px;color:#777;">If you're interested<br>
             <a href="{@docRoot}distribute/googleplay/edu/contact.html"
             class="go-link"
             style="display: block;text-align: right;">SIGN UP</a></div>
 
 <div style="background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">You
-can now include your apps in the Google Play for Education <a href="#program">pilot program</a>,
-getting it into the hands of participating schools and key influencers in the education technology
-community. See the sections below to learn more.</div>
+can now include your educational apps in the Google Play for Education program,
+getting it into the hands of participating schools and key influencers in the
+education technology community. See the sections below to learn more.</div>
 
-<p>If you've got a great app for education or just an idea for one, plan to be a
+<p>If you've got a great app for education, be
 part of Google Play for Education to reach even more teachers and students. It's
 easy to participate, and you'll be able to offer new or existing Android apps
 using familiar tools and processes in Google Play.</p>
@@ -26,8 +27,8 @@
 your apps should meet. When your app is ready, you can opt-in to Google Play for
 Education from the Developer Console.</p>
 
-<p>Note that the initial launch of Google Play for Education is planned for Fall
-2013 and will include schools in the United States only, with support for other
+<p>Note that Google Play for Education is currently available to schools in the
+United States only, with support for schools in other
 countries to follow. At this time, please include your app in Google Play for
 Education only if it is targeting the <strong>US K-12 market</strong>. </p>
 
@@ -35,11 +36,12 @@
 <h2 id="participate">How to Participate</h2>
 
 <div style="float:right; padding-top:2em;"><img
-src="{@docRoot}images/gp-edu-process.png"></div>
+src="{@docRoot}images/gp-edu-process.png" /></div>
 
-<p>Google Play for Education lets you put your educational apps in front of a
+<p>Google Play for Education is a great way to put your educational apps in front of a
 new audience of teachers and students. You can develop and publish using
-familiar tools and processes, such as your existing Developer Console account
+familiar tools and processes, such as your existing <a
+href="https://play.google.com/apps/publish/">Developer Console</a> account
 and your current distribution and pricing settings. It's easy to participate
 &mdash; the sections below outline the process.</p>
 
@@ -109,7 +111,7 @@
 </div>
 </div>
 
-<p>When you've built your release-ready APK and tested to ensure that it meets
+<p>Once you've built your release-ready APK and tested to ensure that it meets
 the <a href="{@docRoot}distribute/googleplay/edu/guidelines.html">app guidelines</a>,
 upload it to the Developer Console, create your store listing, and set
 distribution options. If you aren't familiar with how to prepare for launch on
@@ -117,7 +119,8 @@
 href="{@docRoot}distribute/googleplay/publish/preparing.html">Launch Checklist</a>. </p>
 
 <p>When your app is ready to publish, you can <em>opt-in</em> to Google Play for
-Education from the Developer Console. Opt-in means that you want your app to be
+Education directly from the <a
+href="https://play.google.com/apps/publish/">Developer Console</a>. Opt-in means that you want your app to be
 made available to educators through Google Play for Education, including review,
 classification, and approval by our third-party educator network. Note that
 opt-in does not affect the availability of your app in Google Play Store.</p>
@@ -141,18 +144,21 @@
 opt-in. </li>
   <li>Under Pricing and Distribution, scroll down to find "Google Play for
 Education" and the opt-in checkbox. </li>
-  <li>Click the checkbox next to "Include my app in Google Play for
-Education..."</li>
-  <li>After you've opted-in, find the "Ads" and "In-app purchases" checkboxes below.
-Check each checkbox that applies. Your app's use of ads or in-app purchases will
+  <li>Click the checkbox next to "Include this application in Google Play for
+Education."</li>
+  <li>In the first dialog that appears, review the content policies and guidelines
+  and click "Continue" if your app meets the the policies and guidelines.</li>
+  <li>In next dialog that appears, shown below, find the "Ads" and "In-app purchases" radio
+  buttons. Check each option that applies. Your app's use of ads or in-app purchases will
 be shown to educators when they are browsing your app. </li>
   <li>Click "Save" to save your Pricing and Distribution changes.</li>
 </ol>
 
 <div style="clear:both;margin-top:1.5em;margin-bottom:1.5em;width:660px;">
-<img src="{@docRoot}images/gp-edu-optin.png" style="border:2px solid #ddd;width:660px;">
-<p class="image-caption"><span style="font-weight:500;">Opt-in for apps</span>:
-Include your app in Google Play for Education by opting-in from the Developer Console.</p>
+<img src="{@docRoot}images/gp-edu-ads-iab.png" style="border:2px solid #ddd;width:660px;" />
+<p class="image-caption"><span style="font-weight:500;">Ads and in-app purchase</span>:
+When you opt-in to Google Play for Education, make sure to declare your app's use of ads and
+in-app purchases.</p>
 </div>
 
 <p>Once you save changes and publish your app, the app will be submitted to our
@@ -176,23 +182,20 @@
 
 <p>Our third-party educator network will evaluate apps according to educational
 value and alignment with K-12 core standards, then assign the metadata for
-subject, grade level, and core curriculum that makes them easily browseable for
+subject, grade level, and core curriculum that makes them easily browsable for
 educators. To understand how your apps will be evaluated, please see the <a
 href="{@docRoot}distribute/googleplay/edu/guidelines.html">Guidelines for
 Apps</a> document.</p>
 
 <p>As soon as you opt-in to Google Play for Education and publish, your app is
 queued for review by our third-party educator network. The review and approval
-process can take <strong>3-4 weeks or more</strong>. You'll receive notification
+process can take four weeks or more</strong>. You'll receive notification
 by email (to your developer account address) when the review is complete, with a
 summary of the review results. </p>
 
-<p class="note"><strong>Note</strong>: Until the full product launch in Fall
-2013, please expect the initial review of your app to take longer than usual.
-</p>
-
 <p>At any time, you can check the review and approval status of your app in the
-Developer Console, under "Google Play for Education" in the app's Pricing and
+<a href="https://play.google.com/apps/publish/">Developer Console</a>, under
+"Google Play for Education" in the app's Pricing and
 Distribution page. There are three approval states:</p>
 
 <ul>
@@ -200,9 +203,6 @@
 is not yet complete.</li>
 <li><em>Approved</em> &mdash; Your app was reviewed and approved. The app
 will be made available directly to educators through Google Play for Education.
-Until the full product launch later this year, your app will be available to a
-limited number of educators through the <a
-href="{@docRoot}distribute/googleplay/edu/start.html#program">pilot program</a>.
 Once your app is approved, you can update it at your convenience without needing
 another full review. </li>
 <li><em>Not approved</em> &mdash; Your app was reviewed and not approved.
@@ -215,50 +215,14 @@
 
 <h3 id="appeal">5. Get support or appeal your review results</h3>
 
-<p>After your app is reviewed you'll receive an email giving you the review
-results, including whether the app was approved, how the app was classified, and
+<p>After your app is reviewed you'll receive an email giving you the
+results, including information on whether the app was approved and
 what issues may need to be addressed. You'll receive the email at the address
 you specified for your developer account. </p>
 
-<p>If you believe your app was reviewed or classified incorrectly, you will be
-able to appeal and request reconsideration. Watch for more information on the
-appeal process and links in the weeks to come.</p>
+<p>If your app has issues that need to be addressed, make the necessary
+adjustments, upload your app, and then resubmit the app to Google Play for
+Education through the Developer Console using process described above. Your app
+will be queued for review and you'll receive the review results by email just
+as before.</p>
 
-<p class="note"><strong>Note</strong>: Support and appeal forms are not yet
-available, but will be available soon.</p>
-
-
-<h2 id="program">Including Your Apps in the Pilot Program</h2>
-
-<p>Leading up to the Fall 2013 launch, the Google Play for Education team is
-conducting an extensive series of pilots that include schools and students across
-the United States. Educators in participating schools can browse for apps and
-purchase them in bulk, then deploy them instantly to teacher and student
-devices. </p>
-
-<h3 id="pilot">Early opt-in and publishing</h3>
-<p>As an app developer, you can take part in the pilot program, getting your app
-into the hands of schools and key influencers in the education technology
-community. It's a great way to get early feedback on your educational app. </p>
-
-<p>To offer your app in the pilot program, prepare the app and ensure that it meets
-the <a href="{@docRoot}distribute/googleplay/edu/guidelines.html">Guidelines
-for Apps</a>. Then opt-in to Google Play for Education and publish as soon
-as you are ready. Once your app is approved during review by our third-party
-educator network, it will be made available to educators in the pilot program
-right away. Note that during the pilot program, the review and approval process
-may take longer than usual.</p>
-
-<h3 id="launch">Full launch to US schools</h3>
-<p>The initial launch of Google Play for Education is planned for Fall 2013. The
-pilot program and full launch will include schools in the United States only,
-with support for schools in other countries to follow. </p>
-
-<p>At this time, you should include your app in Google Play for Education only
-if it is targeting the US K-12 market. </p>
-
-<h3 id="more">More information</h3>
-
-<p>If you'd like to be notified by email of the latest information about Google Play
-for Education, visit the <a href="{@docRoot}distribute/googleplay/edu/contact.html">
-Sign Up</a> page and fill out the form. </p>
\ No newline at end of file
diff --git a/docs/html/distribute/googleplay/publish/localizing.jd b/docs/html/distribute/googleplay/publish/localizing.jd
index 29b27c8..30f10b7 100644
--- a/docs/html/distribute/googleplay/publish/localizing.jd
+++ b/docs/html/distribute/googleplay/publish/localizing.jd
@@ -1,5 +1,5 @@
 page.title=Localization Checklist
-page.tags="localize","localization","resources", "formats", "l10n"
+page.tags=localize,localization,resources,formats,l10n
 @jd:body
 
 <div id="qv-wrapper"><div id="qv">
@@ -293,7 +293,7 @@
 <tr>
 <td><p>Related resources:</p>
 <ul style="margin-top:-.5em;">
-<li><strong><a href="{@docRoot}topics/resources/string-resource.html">String Resources</a></strong> &mdash; Developer guide explaining how to use string resources in your UI.</li>
+<li><strong><a href="{@docRoot}guide/topics/resources/string-resource.html">String Resources</a></strong> &mdash; Developer guide explaining how to use string resources in your UI.</li>
 <li><strong><a href="{@docRoot}design/style/writing.html">Writing Style</a></strong> &mdash; Android Design guidelines for voice and style in your UI.</li>
 <li><strong><a class="external-link" href="http://en.wikipedia.org/wiki/XLIFF">XML Localisation Interchange File Format (XLIFF)</a></strong> &mdash; Background information on XLIFF.</li>
 </ul>
@@ -372,24 +372,24 @@
 <p>After the translations are merged back into your app, start <a
 href="#testing">testing the localized app</a>.</p>
 
+<h4 id="gp-trans">Purchase professional translations through Google Play
+<br />App Translation Service</h4>
+
 <div class="sidebox-wrapper">
 <div class="sidebox">
-<h2>Join the translation pilot</h2>
-<p>Google Play is offering translation services as part of a pilot
-program. If you're interested, sign up on the APK page in your
-Developer Console.</p>
+<h2>App Translations in Google Play</h2>
 
-<p>If you join, also try the <a
+<p>Hear from developers who have used the Google Play App Translation Service in <a
+href="{@docRoot}distribute/googleplay/spotlight/localization.html">Developer
+Stories: Localization in Google Play</a>.</p>
+
+<p>To make it easy to export your app's strings and import
+the finished translations into your project, try the <a
 href="{@docRoot}sdk/installing/installing-adt.html#tmgr">
-ADT Translation Manager Plugin</a>, which makes it easy to upload
-your strings to the Developer Console and download translations
-right into your project. </div>
+ADT Translation Manager Plugin</a>.</div>
 </div>
 
-<h4 id="gp-trans">Purchase professional translations through the
-Developer Console</h4>
-
-<p>Google Play can help you quickly find and purchase translations of your app.
+<p>Google Play App Translation Service can help you quickly find and purchase translations of your app.
 In the Developer Console, you can browse a list of third-party vendors who are
 pre-qualified by Google to offer high-quality translation at competitive prices.
 You can upload the strings you want translated, select the languages you want to
diff --git a/docs/html/distribute/googleplay/publish/preparing.jd b/docs/html/distribute/googleplay/publish/preparing.jd
index 5593f4f..6af3eea 100644
--- a/docs/html/distribute/googleplay/publish/preparing.jd
+++ b/docs/html/distribute/googleplay/publish/preparing.jd
@@ -1,5 +1,5 @@
 page.title=Launch Checklist
-page.tags="publishing","launch","Google Play", "Developer Console"
+page.tags=publishing,launch,Google Play,Developer Console
 @jd:body
 
 <div id="qv-wrapper"><div id="qv">
@@ -671,7 +671,7 @@
 <li><strong><a href="http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=113477&topic=2364761&ctx=topic">Supporting your users
 </a></strong> &mdash; Help Center document describing options for supporting users.</li>
 <li><strong><a href="http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=1153479">In-app Billing</a></strong> &mdash; Help Center document describing how to correctly set up In-app Billing.</li>
-<li><strong><a href="https://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=138001">Issuing Refunds</a></strong> &mdash;  -- Help Center document describing how to issue refunds.</li>
+<li><strong><a href="https://support.google.com/payments/answer/2741495?rd=1">Issuing Refunds</a></strong> &mdash;  -- Help Center document describing how to issue refunds.</li>
 </ul>
 </td>
 </tr>
diff --git a/docs/html/distribute/googleplay/spotlight/index.jd b/docs/html/distribute/googleplay/spotlight/index.jd
index c599628..b501f20 100644
--- a/docs/html/distribute/googleplay/spotlight/index.jd
+++ b/docs/html/distribute/googleplay/spotlight/index.jd
@@ -55,7 +55,7 @@
           <div style="width:700px;">
           <p style="margin-top:26px;
                     margin-bottom:12px;">
-          Bangalore-based developers <a href="//play-next-dogfood.corp.google.com/store/apps/details?id=in.redbus.android">redBus.in</a> are bringing the sophistication and convenience of air-travel booking to bus transit. Hear how Android is helping them deliver a superior travel experience to millions of daily bus riders in India.</p>
+          Bangalore-based developers <a href="//play.google.com/store/apps/details?id=in.redbus.android">redBus.in</a> are bringing the sophistication and convenience of air-travel booking to bus transit. Hear how Android is helping them deliver a superior travel experience to millions of daily bus riders in India.</p>
            </div>
            <iframe style="float:left;
              margin-right:24px;
diff --git a/docs/html/distribute/googleplay/spotlight/localization.jd b/docs/html/distribute/googleplay/spotlight/localization.jd
new file mode 100644
index 0000000..ae5993d
--- /dev/null
+++ b/docs/html/distribute/googleplay/spotlight/localization.jd
@@ -0,0 +1,328 @@
+page.title=Developer Stories: Localization in Google Play
+walkthru=0
+header.hide=0
+
+@jd:body
+
+<p>
+  As you build your app and distribute it across the world through Google Play,
+  localization becomes an increasingly important tool to reach more users.
+  Localization involves a <a href=
+  "{@docRoot}distribute/googleplay/publish/localizing.html">variety of tasks</a>, but
+  most important is creating quality translations of your app's UI strings and
+  marketing materials.
+</p>
+
+<p>
+  Managing the translation process across multiple languages can be a
+  challenge, especially if you need to locate translators on your own. That’s
+  why Google Play offers the App Translation Service right from the Developer
+  Console. It's a single place where you can go to source professional
+  translators, get cost estimates, and then send your strings and other
+  materials for translation.
+</p>
+
+<p>
+  Here are some stories from developers who have used Google Play's App Translation
+  Service to localize their apps and the results they've seen as they've
+  expand their offerings beyond a single language.
+</p>
+
+<!-- START STORY -->
+
+<div style="margin-bottom:2em;padding-top:10px;" id="zombieragdoll">
+
+<h3 style="line-height:1.25em">Zombie Ragdoll: Improved user engagement<br /> with localized versions</h3>
+
+  <img alt="" class="screenshot thumbnail" style="-webkit-border-radius: 5px;
+            -moz-border-radius: 5px;
+            border-radius: 5px height:78px;
+            width: 78px;
+            float: left;
+            margin: 12px 20px 9px 20px;" src=
+            "https://lh4.ggpht.com/m-Ew8c8C_nGctbP6PSPGOaVNnGFryReOE2yHXJ9Z6Prk1nsDyx5w5TmWfg-P5N3HypA=w124">
+
+  <div style="list-style: none;height:100%;
+  float: right;
+  border-top: 1px solid #9C0;
+  width: 220px;
+  margin: 4px 20px;padding: .5em;">
+
+    <h5>About the app</h5>
+
+    <ul>
+      <li><a href="https://play.google.com/store/apps/details?id=com.rvappstudios.zombieragdoll">Zombie Ragdoll</a></li>
+      <li>A fun zombie-based physics game</li>
+    </ul>
+
+    <h5>Localization Results</h5>
+
+    <ul>
+      <li>Increased engagement because of appeal of the localized version</li>
+      <li>80% of installs came from users of non-English languages</li>
+      </ul>
+
+    <div style="padding:.5em 0 0 1em;">
+      <a href="https://play.google.com/store/apps/details?id=com.rvappstudios.zombieragdoll">
+        <img alt="Android app on Google Play"
+         src="//developer.android.com/images/brand/en_generic_rgb_wo_45.png" />
+      </a>
+
+    </div>
+  </div>
+
+  <div style="line-height:1.4em;">
+
+<p>
+  The 2013 Google I/O talks about <a href=
+  "https://developers.google.com/events/io/sessions/326345917">Building Android
+  Apps for a Global Audience</a> and <a href=
+  "https://developers.google.com/events/io/sessions/326455375">What’s New for
+  Developers in Google Play</a> inspired developers at RV AppStudios to go global
+  from very beginning for their new game, Zombie Ragdoll. They launched Zombie
+  Ragdoll in August 2013, localized into 20 languages.
+</p>
+
+<p>
+  They quickly saw the impact of their decision to ship simultaneously in
+  multiple languages through increased non-English installs and improved
+  engagement with users worldwide. In addition, they started getting
+  significant usage in countries where their apps had not been as popular
+  before. They are seeing great traction in countries like Vietnam, Russia,
+  Philippines and Thailand.
+</p>
+
+<p>
+  Vivek Dave, founder of RV AppStudios, credits the success of Zombie Ragdoll
+  to localization:
+</p>
+
+<p>
+  "The value of localization is clear, it helps discoverability and helps
+  connect with the users in other countries. So when the localization
+  opportunity arose, we immediately jumped on it. Android is worldwide, and we
+  would be severely limiting ourselves if we focused on English as the only
+  language.
+</p>
+
+<p>
+  "The App Translation Service offered in the Google Play Developer Console is
+  extremely easy to use and the pricing is very attractive. Developers with
+  limited localization experience can easily create, upload, and translate
+  their app."
+</p>
+
+
+<p>
+  RV AppStudios not only localizes the text within the game, but also localizes
+  the game assets to a specific country/culture. Dave says, “Users want a
+  personalized experience, and by offering a localized game with translation of
+  text and graphic assets, we believe users will connect at a much deeper level
+  with the game.”
+</p>
+
+
+  <div style="margin-top:8px;float:left;margin-right:24px;">
+    <img src="{@docRoot}images/distribute/zombie-ragdoll-n5-land.jpg" style="width:470px;">
+  </div>
+
+
+    <div style="margin-top:128px;">
+      <p class="img-caption"><strong>Hindi version of Zombie Ragdoll</strong>:
+      Localized screenshots and videos in the app's Google Play listing go a
+      long way toward increasing the number of installs.</p>
+    </div>
+
+  </div>
+
+</div> <!-- END STORY -->
+
+<!-- START STORY -->
+
+<div style="margin-bottom:2em;padding-top:18px;clear:both;" id="sayhichat">
+
+<h3>SayHi Chat: Install growth and user engagement<br />
+  from professional translations</h3>
+
+  <img alt="" class="screenshot thumbnail" style="-webkit-border-radius: 5px;
+            -moz-border-radius: 5px;
+            border-radius: 5px height:78px;
+            width: 78px;
+            float: left;
+            margin: 12px 20px 9px 20px;" src=
+            "https://lh5.ggpht.com/qiL6CF1Hktz618T3mbGrxvm_OoeheQ78FgG7zr90C2MCRiz4IDQsbKuHT4xQGiWEU8o=w124">
+
+  <div style="list-style: none;height:100%;
+  float: right;
+  border-top: 1px solid #9C0;
+  width: 220px;
+  margin: 4px 20px;padding: .5em;">
+
+    <h5>About the app</h5>
+
+    <ul>
+      <li><a href="https://play.google.com/store/apps/details?id=com.unearby.sayhi">SayHi Chat,
+      Love, Meet, Dating</a></li>
+      <li>A social app to help you find people nearby</li>
+    </ul>
+
+    <h5>Localization Results</h5>
+
+    <ul>
+      <li>120% growth in language installs for new languages added</li>
+      <li>~20% increase in revenue and ~50% increase in User Reviews in the new
+        languages</li>
+      </ul>
+
+    <div style="padding:.5em 0 0 1em;">
+      <a href="https://play.google.com/store/apps/details?id=com.unearby.sayhi">
+        <img alt="Android app on Google Play"
+         src="//developer.android.com/images/brand/en_generic_rgb_wo_45.png" />
+      </a>
+
+    </div>
+  </div>
+
+  <div style="line-height:1.4em;">
+
+<p>
+  The SayHi Chat app started out only in Japanese, Chinese and English. It soon
+  became one of the most popular apps in Japan, Hong Kong, and Taiwan. The
+  SayHi team realized it was time to launch in more languages, as the language
+  barrier was restricting how fast SayHi could grow globally. </p>
+
+  <p>Yan Shi, senior
+  developer at SayHi, says: "We checked Google Analytics for our DAU and user
+  growth numbers in each country, we also looked at total Android and iOS users
+  in those markets before finalizing our next set of languages.
+</p>
+
+  <div style="margin-top:8px;float:left;width:270px;">
+    <img src="{@docRoot}images/distribute/hichat-n5-port.jpg" style="width:240px;margin-right:48px;">
+  </div>
+
+<p>
+  SayHi used the App Translation Service to launch in 13 additional languages
+  in August 2013 and immediately saw 120% increase in install rates. In
+  addition, they are seeing their app ranked in Top 10 apps in countries like
+  Poland and Italy.
+</p>
+
+<p>Notably, they saw steady growth in Spain after replacing their previous
+  non-professional Spanish translation with a professional one produced through
+  the App Translation Service.</p>
+
+<p>
+  Yan Shi adds, “The App Translation Service is really easy to use and
+  the completion time for translation requests is very good.”
+</p>
+
+    <div style="width:600px;margin-top:98px;padding:0;">
+      <p class="img-caption"><strong>Arabic version of SayHi Chat</strong>:
+        User engagement increased significantly with
+        the localized version.</p>
+    </div>
+
+  </div>
+</div> <!-- END STORY -->
+
+
+<div style="margin-bottom:2em;clear:both;padding-top:18px;" id="g4a"><!-- START STORY -->
+
+<h3 style="line-spacing:1.25em;">G4A Indian Rummy: Benefitting from ease-of-use and<br /> fast turnaround time</h3>
+
+  <img alt="" class="screenshot thumbnail" style="-webkit-border-radius: 5px;
+            -moz-border-radius: 5px;
+            border-radius: 5px height:78px;
+            width: 78px;
+            float: left;
+            margin: 12px 20px 9px 20px;" src=
+            "https://lh4.ggpht.com/IxSyQgO0LWzPRoLfCrER06-0kr6aMAa2azF7eNYB30EBZAGOLYJUZulknPockbTlDYU=w124">
+
+  <div style="list-style: none;height:100%;
+  float: right;
+  border-top: 1px solid #9C0;
+  width: 220px;
+  margin: 4px 20px;padding: .5em;">
+
+    <h5>About the app</h5>
+
+    <ul>
+      <li><a href="https://play.google.com/store/apps/details?id=org.games4all.android.games.indianrummy.prod">G4A Indian Rummy</a></li>
+      <li>A card game in which the players try to form sets and sequences of cards</li>
+    </ul>
+
+    <h5>Localization Results</h5>
+
+    <ul>
+      <li>Double the number of users in French and German languages</li>
+      <li>300% increase in user engagement with localized version</li>
+      </ul>
+
+    <div style="padding:.5em 0 0 1em;">
+      <a href="https://play.google.com/store/apps/details?id=com.rvappstudios.zombieragdoll">
+        <img alt="Android app on Google Play"
+         src="//developer.android.com/images/brand/en_generic_rgb_wo_45.png" />
+      </a>
+    </div>
+  </div>
+
+  <div style="line-height:1.4em;">
+
+<p>
+  Games4All (G4A) is the developer of Indian Rummy and a variety of games that
+  they distribute broadly to users around the world. After noticing that
+  certain apps had become especially popular in specific countries, they
+  decided to localize those apps. Initially they used a local agency to do
+  the translation and got great results &mdash; the number of users in
+  that language increased tremendously when they released the localized
+  version.
+</p>
+
+<p>
+  Building on that success, G4A expanded their localization goals but
+  found that translation quality varied across their vendors and costs limited the
+  language/game combinations they could try. That's when G4A decided to try the
+  App Translation Service.
+</p>
+
+<p>
+  Founder Pieter Olivier says, "When we heard that the App Translation
+  Service was available in the Developer Console, we jumped at the opportunity.
+  We've now been using the App Translation Service for several months and found
+  that the cost per translation is much lower than with local companies and the
+  process is much easier."
+</p>
+
+<p>So far, G4A has translated the game Indian Rummy into five languages through
+   the App Translation Service.</p>
+
+<p>
+  Olivier continues, "The first thing we did was convert all of our texts into
+  the strings.xml format. After that using the service was extremely easy and
+  straightforward. In contrast, our previous experiences with translation
+  agencies were much more difficult: files often required extensive conversion
+  operations to make them usable, and turnaround times varied wildly.
+</p>
+
+<p>
+  "With the App Translation Service, the turnaround time is usually measured in
+  days instead of weeks that we were used to with traditional translation
+  agencies."
+</p>
+
+  <div style="margin-top:14px;float:left;margin-right:24px;">
+    <img src="{@docRoot}images/distribute/indian-rummy-n4-land.jpg" style="width:470px;">
+  </div>
+
+    <div style="margin-top:158px;">
+      <p class="img-caption"><strong>Dutch
+      version of Indian Rummy</strong>: Making slight changes to games rules based on
+      local nuances was key to success of the game.</p>
+    </div>
+
+  </div>
+
+
+
+</div> <!-- END STORY -->
\ No newline at end of file
diff --git a/docs/html/google/gcm/adv.jd b/docs/html/google/gcm/adv.jd
index 1360624..245467f 100644
--- a/docs/html/google/gcm/adv.jd
+++ b/docs/html/google/gcm/adv.jd
@@ -22,7 +22,12 @@
   </ol>
 </li>
 <li><a href="#retry">Automatic Retry Using Exponential Back-Off</a></li>
-<li><a href="#unreg">How Unregistration Works</a></li>
+<li><a href="#unreg">Unregistration</a>
+  <ol>
+    <li><a href="#unreg-why">Why you should rarely unregister</a></li>
+    <li><a href="#unreg-how">How unregistration works</a></li>
+  </ol>
+</li>
 <li><a href="#collapsible">Send-to-Sync vs. Messages with Payload</a>
   <ol>
     <li><a href="#s2s">Send-to-sync messages</a></li>
@@ -31,7 +36,8 @@
     </ol>
 </li>
 <li><a href="#ttl">Setting an Expiration Date for a Message</a> </li>
-<li><a href="#throttling"></a><a href="#multi-senders">Receiving Messages from Multiple Senders</a></li>
+<li><a href="#throttling"></a><a href="#multi-senders">Receiving Messages from
+Multiple Senders</a></li>
 </ol>
 
 </div>
@@ -42,17 +48,56 @@
 
 
 <h2 id="msg-lifetime">Lifetime of a Message</h2>
-<p>When a 3rd-party server posts a message to GCM and receives a message ID back, it does not mean that the message was already delivered to the device. Rather, it means that it was accepted for delivery. What happens to the message after it is accepted depends on many factors.</p>
-<p>In the best-case scenario, if the device is connected to GCM, the screen is on, and there are no throttling restrictions (see <a href="#throttling">Throttling</a>), the message will be delivered right away.</p>
+<p>When a 3rd-party server posts a message to GCM and receives a message ID back,
+it does not mean that the message was already delivered to the device. Rather, it
+means that it was accepted for delivery. What happens to the message after it is
+accepted depends on many factors.</p>
+
+<p>In the best-case scenario, if the device is connected to GCM, the screen is on,
+and there are no throttling restrictions (see <a href="#throttling">Throttling</a>),
+the message will be delivered right away.</p>
+
 <p>If the device is connected but idle, the message will still be
-delivered right away unless the <code>delay_while_idle</code> flag is set to true. Otherwise, it will be stored in the GCM servers until the device is awake. And that's where the <code>collapse_key</code> flag plays a role: if there is already a message with the same collapse key (and registration ID) stored and waiting for delivery, the old message will be discarded and the new message will take its place (that is, the old message will be collapsed by the new one). However, if the collapse key is not set, both the new and old messages are stored for future delivery.</p>
+delivered right away unless the <code>delay_while_idle</code> flag is set to true.
+Otherwise, it will be stored in the GCM servers until the device is awake. And
+that's where the <code>collapse_key</code> flag plays a role: if there is already
+a message with the same collapse key (and registration ID) stored and waiting for
+delivery, the old message will be discarded and the new message will take its place
+(that is, the old message will be collapsed by the new one). However, if the collapse
+key is not set, both the new and old messages are stored for future delivery.
+Collapsible messages are also called <a href="#s2s">send-to-sync messages</a>.</p>
 
-<p class="note"><strong>Note:</strong> There is a limit on how many messages can be stored without collapsing. That limit is currently 100. If the limit is reached, all stored messages are discarded. Then when the device is back online, it receives a special message indicating that the limit was reached. The application can then handle the situation properly, typically by requesting a full sync.</p>
+<p class="note"><strong>Note:</strong> There is a limit on how many messages can
+be stored without collapsing. That limit is currently 100. If the limit is reached,
+all stored messages are discarded. Then when the device is back online, it receives
+a special message indicating that the limit was reached. The application can then
+handle the situation properly, typically by requesting a full sync.
+<br><br>
+Likewise, there is a limit on how many <code>collapse_key</code>s you can have for
+a particular device. GCM allows a maximum of 4 different collapse keys to be used
+by the GCM server per device
+any given time. In other words, the GCM server can simultaneously store 4 different
+send-to-sync messages, each with a different collapse key. If you exceed this number
+GCM will only keep 4 collapse keys, with no guarantees about which ones they will be.
+See <a href="#s2s">Send-to-sync messages</a> for more information.
+</p>
 
-<p>If the device is not connected to GCM, the message will be stored until a connection is established (again respecting the collapse key rules). When a connection is established, GCM will deliver all pending messages to the device, regardless of the <code>delay_while_idle</code> flag. If the device never gets connected again (for instance, if it was factory reset), the message will eventually time out and be discarded from GCM storage. The default timeout is 4 weeks, unless the <code>time_to_live</code> flag is set.</p>
+<p>If the device is not connected to GCM, the message will be stored until a
+connection is established (again respecting the collapse key rules). When a connection
+is established, GCM will deliver all pending messages to the device, regardless of
+the <code>delay_while_idle</code> flag. If the device never gets connected again
+(for instance, if it was factory reset), the message will eventually time out and
+be discarded from GCM storage. The default timeout is 4 weeks, unless the
+<code>time_to_live</code> flag is set.</p>
 
-<p>Finally, when GCM attempts to deliver a message to the device and the application was uninstalled, GCM will discard that message right away and invalidate the registration ID. Future attempts to send a message to that device will get a <code>NotRegistered</code> error. See <a href="#unreg">How Unregistration Works</a> for more information.</p>
-<p>Although is not possible to track the status of each individual message, the Google APIs Console stats are broken down by messages sent to device, messages collapsed, and messages waiting for delivery.</p>
+<p>Finally, when GCM attempts to deliver a message to the device and the
+application was uninstalled, GCM will discard that message right away and
+invalidate the registration ID. Future attempts to send a message to that device
+will get a <code>NotRegistered</code> error. See <a href="#unreg">
+How Unregistration Works</a> for more information.</p>
+<p>Although is not possible to track the status of each individual message, the
+Google Cloud Console stats are broken down by messages sent to device, messages
+collapsed, and messages waiting for delivery.</p>
 
 <h2 id="throttling">Throttling</h2>
 <p>To prevent abuse (such as sending a flood of messages to a device) and
@@ -74,107 +119,112 @@
 efficiency reasons.</p>
 
 <h2 id="reg-state">Keeping the Registration State in Sync</h2>
-<p>Whenever the application receives a <code>com.google.android.c2dm.intent.REGISTRATION</code> intent with a <code>registration_id</code> extra, it should save the ID for future use, pass it to the 3rd-party server to complete the registration, and keep track of whether the server completed the registration. If the server fails to complete the registration, it should try again or unregister from GCM.</p>
+<p>Whenever the application registers as described in
+<a href="{@docRoot}google/gcm/client.html">Implementing GCM Client</a>,
+it should save the registration ID for future use, pass it to the
+3rd-party server to complete the registration, and keep track of
+whether the server completed the registration. If the server fails
+to complete the registration, it should try again or unregister from GCM.</p>
+
 <p>There are also two other scenarios that require special care:</p>
 <ul>
   <li>Application update</li>
   <li>Backup and restore
   </li>
 </ul>
-<p>When an application is updated, it should invalidate its existing registration ID, as it is not guaranteed to work with the new version.  Because there is no lifecycle method called when the application is updated, the best way to achieve this validation is by storing the current application version when a registration ID is stored. Then when the application is started, compare the stored value with the current application version. If they do not match, invalidate the stored data and start the registration process again.</p>
+<p>When an application is updated, it should invalidate its existing registration
+ID, as it is not guaranteed to work with the new version.  Because there is no
+lifecycle method called when the application is updated, the best way to achieve
+this validation is by storing the current application version when a registration
+ID is stored. Then when the application is started, compare the stored value with
+the current application version. If they do not match, invalidate the stored data
+and start the registration process again.</p>
 
-<p>Similarly, you should not save the registration ID when an application is backed up. This is because the registration ID could become invalid by the time the application is restored, which would put the application in an invalid state  (that is, the application thinks it is registered, but the server and GCM do not store that registration ID anymore&mdash;thus the application will not get more messages).</p>
+<p>Similarly, you should not save the registration ID when an application is
+backed up. This is because the registration ID could become invalid by the time
+the application is restored, which would put the application in an invalid state
+(that is, the application thinks it is registered, but the server and GCM do not
+store that registration ID anymore&mdash;thus the application will not get more
+messages).</p>
 <h3 id="canonical">Canonical IDs</h3>
-<p>On the server side, as long as the application is behaving well, everything should work normally. However, if a bug in the application triggers multiple registrations for the same device, it can be hard to reconcile state and you might end up with duplicate messages.</p>
-<p>GCM provides a facility called &quot;canonical registration IDs&quot; to easily recover from these situations. A canonical registration ID is defined to be the ID of the last registration requested by your application. This is the ID that the server should use when sending messages to the device.</p>
-<p>If later on you try to send a message using a different registration ID, GCM will process the request as usual, but it will include the canonical registration ID in the <code>registration_id</code> field of the response. Make sure to replace the registration ID stored in your server with this canonical ID, as eventually the ID you're using will stop working.</p>
+<p>On the server side, as long as the application is behaving well, everything
+should work normally. However, if a bug in the application triggers multiple
+registrations for the same device, it can be hard to reconcile state and you might
+end up with duplicate messages.</p>
+<p>GCM provides a facility called &quot;canonical registration IDs&quot; to easily
+recover from these situations. A canonical registration ID is defined to be the ID
+of the last registration requested by your application. This is the ID that the
+server should use when sending messages to the device.</p>
+<p>If later on you try to send a message using a different registration ID, GCM
+will process the request as usual, but it will include the canonical registration
+ID in the <code>registration_id</code> field of the response. Make sure to replace
+the registration ID stored in your server with this canonical ID, as eventually
+the ID you're using will stop working.</p>
 
 <h2 id="retry">Automatic Retry Using Exponential Back-Off</h2>
 
-<p>When the application receives a <code>com.google.android.c2dm.intent.REGISTRATION</code> intent with the <code>error</code> extra set as <code>SERVICE_NOT_AVAILABLE</code>, it should retry the failed operation (register or unregister).</p>
-<p>In the simplest case, if your application just calls <code>register</code> and GCM is not a fundamental part of the application, the application could simply ignore the error and try to register again the next time it starts. Otherwise, it should retry the previous operation using exponential back-off. In exponential back-off, each time there is a failure, it should wait twice the previous amount of time before trying again. If the register (or unregister) operation was synchronous, it could be retried in a simple loop. However, since it is asynchronous, the best approach is to schedule a pending intent to retry the operation. The following steps describe how to implement this in the <code>MyIntentService</code> example used above:</p>
-<ol>
-  <li> Create a random token to verify the origin of the retry intent:
+<p>When registration or unregistration fails, the app should retry the failed operation.</p>
+<p>In the simplest case, if your application attempts to register and GCM is not a
+fundamental part of the application, the application could simply ignore the error
+and try to register again the next time it starts. Otherwise, it should retry the
+previous operation using exponential back-off. In exponential back-off, each time
+there is a failure, it should wait twice the previous amount of time before trying
+again. If the register (or unregister) operation was synchronous, it could be retried
+in a simple loop. However, since it is asynchronous, the best approach is to schedule
+a {@link android.app.PendingIntent} to retry the operation.
 
-<pre class="prettyprint pretty-java">private static final String TOKEN =
-        Long.toBinaryString(new Random().nextLong());
-</pre>
+<h2 id="unreg">Unregistration</h2>
 
-  <li> Change the <code>handleRegistration()</code> method so it creates the pending intent when appropriate:</li>
+<p>This section explains when you should unregister in GCM and what happens
+when you do.</p>
 
-<pre class="prettyprint pretty-java">...
-if (error != null) {
- if ("SERVICE_NOT_AVAILABLE".equals(error)) {
-   long backoffTimeMs = // get back-off time from shared preferences
-   long nextAttempt = SystemClock.elapsedRealtime() + backoffTimeMs;
-   Intent retryIntent = new Intent("com.example.gcm.intent.RETRY");
-   retryIntent.putExtra("token", TOKEN);
-   PendingIntent retryPendingIntent =
-       PendingIntent.getBroadcast(context, 0, retryIntent, 0);
-   AlarmManager am = (AlarmManager)   
-       context.getSystemService(Context.ALARM_SERVICE);
-   am.set(AlarmManager.ELAPSED_REALTIME, nextAttempt, retryPendingIntent);
-   backoffTimeMs *= 2; // Next retry should wait longer.
-   // update back-off time on shared preferences
- } else {
-   // Unrecoverable error, log it
-   Log.i(TAG, "Received error: " + error);
-}
-...</pre>
-<p> The back-off time is stored in a shared preference. This ensures that it is persistent across multiple activity launches. The name of the intent does not matter, as long as the same intent is used in the following steps.</p></li>
+<h3 id="unreg-why">Why you should rarely unregister</h3>
 
-  <li> Change the <code>onHandleIntent()</code> method adding an <code>else if</code> case for the retry intent:</li>
+<p>A registration ID (regID) represents a particular Android application running
+on a particular device. You should only need to unregister in rare cases, such as
+if you want an app to stop receiving messages, or if you suspect that the regID has
+been compromised. In general, though, once an app has a regID, you shouldn't need
+to change it.</p>
 
-<pre class="prettyprint pretty-java">...
-} else if (action.equals("com.example.gcm.intent.RETRY")) {
-    String token = intent.getStringExtra("token");
-    // make sure intent was generated by this class, not by a malicious app
-    if (TOKEN.equals(token)) {
-        String registrationId = // get from shared properties
-        if (registrationId != null) {
-        // last operation was attempt to unregister; send UNREGISTER intent again
-    } else {
-        // last operation was attempt to register; send REGISTER intent again
-    }
-}
-...</pre>
+<p>In particular, you should never unregister your app as a mechanism for
+logout or for switching between users, for the following reasons:</p>
 
-  <li> Create a new instance of <code>MyReceiver</code> in your activity:</li>
+<ul>
+  <li>A regID maps an app to a device. It isn't associated with a particular
+  logged in user. If you unregister and then re-register, GCM may return the same
+  ID or a different ID&mdash;there's no guarantee either way.</li>
 
-<pre class="prettyprint pretty-java">private final MyBroadcastReceiver mRetryReceiver = new MyBroadcastReceiver();
-</pre>
+  <li>Unregistration may take up to 5 minutes to propagate.</li>
+  <li>After unregistration, re-registration may again take up to 5 minutes to
+propagate. During this time messages may be rejected due to the state of being
+unregistered, and after all this, messages may still go to the wrong user.</li>
+</ul>
 
-  <li>In the activity's <code>onCreate()</code> method, register the new instance to receive the <code>com.example.gcm.intent.RETRY</code> intent:
-    <pre class="prettyprint pretty-java">...
-IntentFilter filter = new IntentFilter(&quot;com.example.gcm.intent.RETRY&quot;);
-filter.addCategory(getPackageName());
-registerReceiver(mRetryReceiver, filter);
-...</pre>
 
-<p class="note"><strong>Note:</strong> You must dynamically create a new instance of the broadcast receiver since the one defined by the manifest can only receive intents with the <code>com.google.android.c2dm.permission.SEND</code> permission. The permission <code>com.google.android.c2dm.permission.SEND</code> is a system permission and as such it cannot be granted to a regular application.</p>
+<p>The solution is to manage your own mapping between users, the regID, and
+individual messages:</p>
 
-</li>
+<ul>
+  <li>Your app server should maintain a mapping between the current user
+and the regID. This should include information about which user is supposed to
+receive a particular message.</li>
+  <li>The app running on the device should check to ensure that messages it
+receives match the logged in user.</li>
+</ul>
 
-  <li>In the activity's <code>onDestroy()</code> method, unregister the broadcast receiver:</li>
 
-<pre class="prettyprint pretty-java">unregisterReceiver(mRetryReceiver);</pre>
-</ol>
-<h2 id="unreg">How Unregistration Works</h2>
-<p>There are two ways to unregister a device from GCM: manually and automatically.</p>
-<p>An Android application can manually unregister itself by issuing a <code>com.google.android.c2dm.intent.UNREGISTER</code> intent, which is useful when the application offers a logoff feature (so it can unregister on logoff and register again on logon). See the <a href="gcm.html#unregistering">Architectural Overview</a> for more discussion of this topic. This is the sequence of events when an application unregisters itself:</p>
-<ol>
-  <li> The application issues a <code>com.google.android.c2dm.intent.UNREGISTER</code> intent, passing the package name as an extra.</li>
-  <li>When the GCM server is done with the unregistration, it sends a <code>com.google.android.c2dm.intent.REGISTRATION</code> intent with the <code>unregistered</code> extra set.</li>
-  <li>The application then must contact the 3rd-party server so it can remove the registration ID.</li>
-  <li>The application should also clear its registration ID.
-  </li>
-</ol>
-<p>An application can be automatically unregistered after it is uninstalled from the device. However, this process does not happens right away, as Android does not provide an uninstall callback. What happens in this scenario is as follows:</p>
+<h3 id="unreg-how">How unregistration works</h3>
+
+<p>An application can be automatically unregistered after it is uninstalled from
+the device. However, this process does not happens right away, as Android does not
+provide an uninstall callback. What happens in this scenario is as follows:</p>
 <ol>
   <li>The end user uninstalls the application.</li>
   <li>The 3rd-party server sends a message to GCM server.</li>
   <li>The GCM server sends the message to the device.</li>
-  <li>The GCM client receives the message and queries Package Manager about whether there are broadcast receivers configured to receive it, which returns <code>false</code>. 
+  <li>The GCM client receives the message and queries Package Manager about
+whether there are broadcast receivers configured to receive it, which returns
+<code>false</code>.
 </li>
   <li>The GCM client informs the GCM server that the application was uninstalled.</li>
   <li>The GCM server marks the registration ID for deletion.</li>
@@ -184,9 +234,16 @@
   </li>
 </ol>
 
-<p class ="note"><strong>Note:</strong> The GCM client is the Google Cloud Messaging framework present on the device.</p>
+<p class ="note"><strong>Note:</strong> The GCM client is the Google Cloud
+Messaging framework present on the device.</p>
 
-<p>Note that it might take a while for the registration ID be completely removed from GCM. Thus it is possible that messages sent during step 7 above gets a valid message ID as response, even though the message will not be delivered to the device. Eventually, the registration ID will be removed and the server will get a <code>NotRegistered</code> error, without any further action being required from the 3rd-party server (this scenario happens frequently while an application is being developed and tested).</p>
+<p>Note that it might take a while for the registration ID be completely removed
+from GCM. Thus it is possible that messages sent during step 7 above gets a valid
+message ID as response, even though the message will not be delivered to the device.
+Eventually, the registration ID will be removed and the server will get a
+<code>NotRegistered</code> error, without any further action being required from
+the 3rd-party server (this scenario happens frequently while an application is
+being developed and tested).</p>
 
 <h2 id="collapsible">Send-to-Sync  vs. Messages with Payload</h2>
 
@@ -196,17 +253,45 @@
   <li>By default, it is stored by GCM for 4 weeks.</li>
 </ul>
 
-<p>But despite these similarities, messages can behave very differently depending on their particular settings. One major distinction between messages is whether they are collapsed (where each new message replaces the preceding message) or not collapsed (where each individual message is delivered). Every message sent in GCM is either a &quot;send-to-sync&quot; (collapsible) message or a &quot;message with payload&quot; (non-collapsible message). These concepts are described in more detail in the following sections.</p>
+<p>But despite these similarities, messages can behave very differently depending
+on their particular settings. One major distinction between messages is whether
+they are collapsed (where each new message replaces the preceding message) or not
+collapsed (where each individual message is delivered). Every message sent in GCM
+is either a &quot;send-to-sync&quot; (collapsible) message or a &quot;message with
+payload&quot; (non-collapsible message). These concepts are described in more
+detail in the following sections.</p>
 
 <h3 id="s2s"><strong>Send-to-sync messages</strong></h3>
 
-<p>A send-to-sync (collapsible) message is often a &quot;tickle&quot; that tells a mobile application to sync data from the server. For example, suppose you have an email application. When a user receives new email on the server, the server pings the mobile application with a &quot;New mail&quot; message. This tells the application to sync to the server to pick up the new email. The server might send this message multiple times as new mail continues to accumulate, before the application has had a chance to sync. But if the user has received 25 new emails, there's no need to preserve every &quot;New mail&quot; message. One is sufficient. Another example would be a sports application that updates users with the latest score. Only the most recent message is relevant, so it makes sense to have each new message replace the preceding message. </p>
+<p>A send-to-sync (collapsible) message is often a &quot;tickle&quot; that tells
+a mobile application to sync data from the server. For example, suppose you have
+an email application. When a user receives new email on the server, the server
+pings the mobile application with a &quot;New mail&quot; message. This tells the
+application to sync to the server to pick up the new email. The server might send
+this message multiple times as new mail continues to accumulate, before the application
+has had a chance to sync. But if the user has received 25 new emails, there's no
+need to preserve every &quot;New mail&quot; message. One is sufficient. Another
+example would be a sports application that updates users with the latest score.
+Only the most recent message is relevant, so it makes sense to have each new
+message replace the preceding message. </p>
 
-<p>The email and sports applications are cases where you would probably use the GCM <code>collapse_key</code> parameter. A <em>collapse key</em> is an arbitrary string that is used to collapse a group of like messages when the device is offline, so that only the most recent message gets sent to the client. For example, &quot;New mail,&quot; &quot;Updates available,&quot; and so on</p>
-<p>GCM allows a maximum of 4 different collapse keys to be used by the GCM server at any given time. In other words, the GCM server can simultaneously store 4 different send-to-sync messages, each with a different collapse key. If you exceed this number GCM will only keep 4 collapse keys, with no guarantees about which ones they will be.</p>
+<p>The email and sports applications are cases where you would probably use the
+GCM <code>collapse_key</code> parameter. A <em>collapse key</em> is an arbitrary
+string that is used to collapse a group of like messages when the device is offline,
+so that only the most recent message gets sent to the client. For example,
+&quot;New mail,&quot; &quot;Updates available,&quot; and so on</p>
+<p>GCM allows a maximum of 4 different collapse keys to be used by the GCM server
+at any given time. In other words, the GCM server can simultaneously store 4
+different send-to-sync messages per device, each with a different collapse key.
+For example, Device A can have A1, A2, A3, and A4. Device B can have B1, B2, B3,
+and B4, and so on. If you exceed this number GCM will only keep 4 collapse keys, with no
+guarantees about which ones they will be.</p>
 
 <h3 id="payload">Messages with payload</h3>
-<p>Unlike a send-to-sync message, every &quot;message with payload&quot; (non-collapsible message) is delivered. The payload the message contains can be up to 4kb. For example, here is a JSON-formatted message in an IM application in which spectators are discussing a sporting event:</p>
+<p>Unlike a send-to-sync message, every &quot;message with payload&quot;
+(non-collapsible message) is delivered. The payload the message contains can be
+up to 4kb. For example, here is a JSON-formatted message in an IM application in
+which spectators are discussing a sporting event:</p>
 
 <pre class="prettyprint pretty-json">{
   "registration_id" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
@@ -217,19 +302,38 @@
   },
 }</pre>
 
-<p>A &quot;message with payload&quot; is not simply a &quot;ping&quot; to the mobile application to contact the server to fetch data. In the aforementioned IM application, for example, you would want to deliver every message, because every message has different content. To specify a non-collapsible message, you simply omit the <code>collapse_key</code> parameter. Thus GCM will send each message individually. Note that the order of delivery is not guaranteed.</p>
-<p>GCM will store up to 100 non-collapsible messages. After that, all messages are discarded from GCM, and a new message is created that tells the client how far behind it is. The message is delivered through a regular <code>com.google.android.c2dm.intent.RECEIVE</code> intent, with the following extras:</p>
-<ul>
-  <li> <code>message_type</code>&mdash;The value is always the string &quot;deleted_messages&quot;.</li>
-  <li><code>total_deleted</code>&mdash;The value  is a string with the number of deleted messages.</li>
-</ul>
-<p>The application should respond by syncing with the server to recover the discarded messages. </p>
+<p>A &quot;message with payload&quot; is not simply a &quot;ping&quot; to the
+mobile application to contact the server to fetch data. In the aforementioned IM
+application, for example, you would want to deliver every message, because every
+message has different content. To specify a non-collapsible message, you simply
+omit the <code>collapse_key</code> parameter. Thus GCM will send each message
+individually. Note that the order of delivery is not guaranteed.</p>
+
+<p>GCM will store up to 100 non-collapsible messages. After that, all messages
+are discarded from GCM, and a new message is created that tells the client how
+far behind it is. The message is delivered through a regular
+<code>com.google.android.c2dm.intent.RECEIVE</code> intent with the
+extra <code>message_type</code>, for which the value is always the string
+&quot;deleted_messages&quot;.</p>
+
+<p>The application should respond by syncing with the server to recover the
+discarded messages. </p>
 
 <h3 id="which">Which should I use?</h3>
-  <p>If your application does not need to use non-collapsible messages, collapsible messages are a better choice from a performance standpoint, because they put less of a burden on the device battery.</p>
+  <p>If your application does not need to use non-collapsible messages, collapsible
+messages are a better choice from a performance standpoint, because they put less
+of a burden on the device battery. However, if you use collapsible messages, remember that
+<strong>GCM only allows a maximum of 4 different collapse keys to be used by the GCM server
+per device at any given time</strong>. You must not exceed this number, or it could cause
+unpredictable consequences.</p>
 
 <h2 dir="ltr" id="ttl">Setting an Expiration Date for a Message</h2>
-<p>The Time to Live (TTL) feature lets  the sender  specify the maximum lifespan of a message using the <code>time_to_live</code> parameter in the send request. The value of this parameter must be a duration from 0 to 2,419,200 seconds, and it corresponds to the maximum period of time for which GCM will store and try to deliver the message. Requests that don't contain this field default to the maximum period of 4 weeks.</p>
+<p>The Time to Live (TTL) feature lets  the sender  specify the maximum lifespan
+of a message using the <code>time_to_live</code> parameter in the send request.
+The value of this parameter must be a duration from 0 to 2,419,200 seconds, and
+it corresponds to the maximum period of time for which GCM will store and try to
+deliver the message. Requests that don't contain this field default to the maximum
+period of 4 weeks.</p>
 <p>Here are some possible uses for this feature:</p>
 <ul>
   <li>Video chat incoming calls</li>
@@ -237,9 +341,29 @@
   <li>Calendar events</li>
 </ul>
 <h3 id="bg">Background </h3>
-<p>GCM will usually deliver messages immediately after they are sent. However, this might not always be possible. For example, the device could be turned off, offline, or otherwise unavailable. In other cases, the sender itself might request that messages not be delivered until the device becomes active by using the <code>delay_while_idle</code> flag. Finally, GCM might intentionally delay messages to prevent an application from consuming excessive resources and negatively impacting battery life.</p>
-<p>When this happens, GCM will store the message and deliver it as soon as it's feasible. While this is fine in most cases, there are some applications for which a late message might as well never be delivered. For example, if the message is an incoming call or video chat notification, it will only be meaningful for a small period of time before the call is terminated. Or if the message is an invitation to an event, it will be useless if received after the event has ended.</p>
-<p>Another advantage of specifying the expiration date for a message is that GCM will never throttle messages with a <code>time_to_live</code> value of 0 seconds. In other words, GCM will guarantee best effort for messages that must be delivered &quot;now or never.&quot; Keep in mind that a <code>time_to_live</code> value of 0 means messages that can't be delivered immediately will be discarded. However, because such messages are never stored, this provides the best latency for sending notifications.</p>
+<p>GCM will usually deliver messages immediately after they are sent. However,
+this might not always be possible. For example, the device could be turned off,
+offline, or otherwise unavailable. In other cases, the sender itself might request
+that messages not be delivered until the device becomes active by using the
+<code>delay_while_idle</code> flag. Finally, GCM might intentionally delay messages
+to prevent an application from consuming excessive resources and negatively
+impacting battery life.</p>
+
+<p>When this happens, GCM will store the message and deliver it as soon as it's
+feasible. While this is fine in most cases, there are some applications for which
+a late message might as well never be delivered. For example, if the message is
+an incoming call or video chat notification, it will only be meaningful for a
+small period of time before the call is terminated. Or if the message is an
+invitation to an event, it will be useless if received after the event has ended.</p>
+
+<p>Another advantage of specifying the expiration date for a message is that GCM
+will never throttle messages with a <code>time_to_live</code> value of 0 seconds.
+In other words, GCM will guarantee best effort for messages that must be delivered
+&quot;now or never.&quot; Keep in mind that a <code>time_to_live</code> value of
+0 means messages that can't be delivered immediately will be discarded. However,
+because such messages are never stored, this provides the best latency for
+sending notifications.</p>
+
 <p>Here is an example of a JSON-formatted request that includes TTL:</p>
 <pre class="prettyprint pretty-json">
 {
@@ -256,9 +380,23 @@
 
 
 <h2 id="multi-senders">Receiving Messages from Multiple Senders</h2>
-<p>GCM allows multiple parties to send messages to the same application. For example, suppose your application is an articles aggregator with multiple contributors, and you want each of them to be able to send a message when they publish a new article. This message might contain a URL so that the application can download the article. Instead of having to centralize all sending activity in one location, GCM gives you the ability to let each of these contributors send its own messages.</p>
-<p>To make this possible, all you need to do is have each sender generate its own project number. Then include those IDs in the sender field, separated by commas, when requesting a registration. Finally, share the registration ID with your partners, and they'll be able to send messages to your application using their own authentication keys.</p>
-<p>This code snippet illustrates this feature. Senders are passed as an intent extra in a comma-separated list:</p>
+
+<p>GCM allows multiple parties to send messages to the same application. For
+example, suppose your application is an articles aggregator with multiple
+contributors, and you want each of them to be able to send a message when they
+publish a new article. This message might contain a URL so that the application
+can download the article. Instead of having to centralize all sending activity in
+one location, GCM gives you the ability to let each of these contributors send
+its own messages.</p>
+
+<p>To make this possible, all you need to do is have each sender generate its own
+project number. Then include those IDs in the sender field, separated by commas,
+when requesting a registration. Finally, share the registration ID with your
+partners, and they'll be able to send messages to your application using their
+own authentication keys.</p>
+<p>This code snippet illustrates this feature. Senders are passed as an intent
+extra in a comma-separated list:</p>
+
 <pre class="prettyprint pretty-java">Intent intent = new Intent(GCMConstants.INTENT_TO_GCM_REGISTRATION);
 intent.setPackage(GSF_PACKAGE);
 intent.putExtra(GCMConstants.EXTRA_APPLICATION_PENDING_INTENT,
@@ -269,4 +407,3 @@
  </pre>
 
 <p>Note that there is limit of 100 multiple senders.</p>
- 
diff --git a/docs/html/google/gcm/ccs.jd b/docs/html/google/gcm/ccs.jd
index 0cadbd2..d2177ca 100644
--- a/docs/html/google/gcm/ccs.jd
+++ b/docs/html/google/gcm/ccs.jd
@@ -1,93 +1,96 @@
-page.title=GCM Cloud Connection Server
+page.title=GCM Cloud Connection Server (XMPP)
 @jd:body
 
 <div id="qv-wrapper">
 <div id="qv">
 
-<h2>Quickview</h2>
-
-<ul>
-<li>Get an introduction to key CCS terms and concepts.</li>
-<li>Learn how to send and receive both upstream and downstream messages in CCS.</li>
-</ul>
-
 
 <h2>In this document</h2>
 
 <ol class="toc">
-  <li><a href="#gcm">CCS vs. GCM HTTP</a> </li>
   <li><a href="#usage">How to Use CCS</a>
-    <ol>
-      <li><a href="#send_msg">Sending Messages</a></li>
-      <li><a href="#format">Message Format</a></li>
-      <li><a href="#msg_examples">Message Examples</a></li>
+    <ol class="toc">
+      <li><a href="#auth">Authentication</a></li>
+      </ol>
+      </li>
+    <li><a href="#format">Message Format</a>
+      <ol class="toc">
+        <li><a href="#request">Request format</a></li>
+        <li><a href="#response">Response format</a></li>
+      </ol>
+      </li>
+  <li><a href="#upstream">Upstream Messages</a> </li>
+  <li><a href="#flow">Flow Control</a> </li>
+  <li><a href="#implement">Implementing an XMPP-based App Server</a>
+    <ol class="toc">
+      <li><a href="#smack">Java sample using the Smack library</a></li>
+      <li><a href="#python">Python sample</a></li>
     </ol>
   </li>
-  <li><a href="#flow">Flow Control</a> </li>
 </ol>
 
 <h2>See Also</h2>
 
 <ol class="toc">
-<li><a href="{@docRoot}google/play-services/gcm/gs.html">Getting Started</a></li>
-<li><a href="https://services.google.com/fb/forms/gcm/" class="external-link" target="_android">CCS and User Notifications Signup Form</a></li>
+<li><a href="{@docRoot}google/gcm/http.html">HTTP</a></li>
+<li><a href="{@docRoot}google/gcm/gs.html">Getting Started</a></li>
+<li><a href="{@docRoot}google/gcm/server.html">Implementing GCM Server</a></li>
+<li><a href="{@docRoot}google/gcm/client.html">Implementing GCM Client</a></li>
+<li><a href="https://services.google.com/fb/forms/gcm/" class="external-link"
+target="_android">CCS and User Notifications Signup Form</a></li>
 </ol>
 
 </div>
 </div>
 
-<p class="note"><strong>Note:</strong> To try out this feature, sign up using <a href="https://services.google.com/fb/forms/gcm/">this form</a>.</p>
+<p class="note"><strong>Note:</strong> To try out this feature, sign up using
+<a href="https://services.google.com/fb/forms/gcm/">this form</a>.</p>
 
-<p>The GCM Cloud Connection Server (CCS) allows third party servers to communicate with Android devices by  establishing a persistent TCP connection with Google servers using the XMPP protocol. This communication is asynchronous and bidirectional.</p>
-<p>You can continue to use the HTTP request mechanism to send messages to GCM servers, side-by-side with CCS which uses XMPP. Some of the benefits of CCS include:</p>
+<p>The GCM Cloud Connection Server (CCS) is a connection server based on XMPP.
+CCS allows 3rd-party app servers (which you're
+responsible for implementing) to communicate
+with Android devices by  establishing a persistent TCP connection with Google
+servers using the XMPP protocol. This communication is asynchronous and bidirectional.</p>
+<p>You can continue to use the HTTP request mechanism to send messages to GCM
+servers, side-by-side with CCS which uses XMPP. Some of the benefits of CCS include:</p>
 <ul>
-  <li>The asynchronous nature of XMPP allows you to send more messages with fewer resources.</li>
-  <li>Communication is bidirectional&mdash;not only can the server send messages to the device, but the device can send messages back to the server.</li>
-<li>You can send messages back using the same connection used for receiving, thereby improving battery life.</li>
+  <li>The asynchronous nature of XMPP allows you to send more messages with fewer
+resources.</li>
+  <li>Communication is bidirectional&mdash;not only can the server send messages
+to the device, but the device can send messages back to the server.</li>
+<li>You can send messages back using the same connection used for receiving,
+thereby improving battery life.</li>
 </ul>
 
-<p>The upstream messaging (device-to-cloud) feature of CCS is part of the Google Play services platform. Upstream messaging is available through the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs. To use upstream messaging and the new streamlined registration process, you must <a href="{@docRoot}google/play-services/setup.html">set up</a> the Google Play services SDK.</p>
+<p>The upstream messaging (device-to-cloud) feature of CCS is part of the Google
+Play services platform. Upstream messaging is available through the
+<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a>
+APIs. For examples, see
+<a href="#implement">Implementing an XMPP-based App Server</a>.</p>
 
-<p class="note"><strong>Note:</strong> For an example of an XMPP server, see <a href="server.html#xmpp">GCM Server</a>.
+<p class="note"><strong>Note:</strong> See
+<a href="server.html#params">Implementing GCM Server</a> for a list of all the message
+parameters and which connection server(s) supports them.</p>
 
-<h2 id="gcm">CCS vs. GCM HTTP</h2>
-
-<p>CCS messaging differs from GCM HTTP messaging in the following ways:</p>
-<ul>
-  <li>Upstream/Downstream messages
-    <ul>
-      <li>GCM HTTP: Downstream only: cloud-to-device. </li>
-      <li>CCS: Upstream and downstream (device-to-cloud, cloud-to-device). </li>
-    </ul>
-  </li>
-  <li>Asynchronous messaging
-    <ul>
-      <li>GCM HTTP: 3rd-party servers send messages as HTTP POST requests and wait for a response. This mechanism is synchronous and causes the sender to block before sending another message.</li>
-      <li>CCS: 3rd-party servers connect to Google infrastructure using a persistent XMPP connection and send/receive messages to/from all their devices at full line speed. CCS sends acknowledgements or failure notifications (in the form of special ACK and NACK JSON-encoded XMPP messages) asynchronously.</li>
-    </ul>
-  </li>
-
-  <li>JSON
-    <ul>
-      <li>GCM HTTP: JSON messages sent as HTTP POST.</li>
-      <li>CCS: JSON messages encapsulated in XMPP messages.</li>
-    </ul>
-  </li>
-</ul>
-<p>This document describes how to use CCS. For general concepts and information on how to use GCM HTTP, see the <a href="gcm.html">GCM Architectural Overview</a>.</p>
 
 <h2 id="usage">How to Use CCS</h2>
 
-<p>GCM Cloud Connection Server (CCS) is an XMPP endpoint, running on {@code http://gcm.googleapis.com} port 5235.</p>
+<p>GCM Cloud Connection Server (CCS) is an XMPP endpoint, running on
+{@code http://gcm.googleapis.com} port 5235.</p>
 
-<p>CCS requires a Transport Layer Security (TLS) connection. That means the  XMPP client must initiate a TLS connection.
-For example in smack, you would call {@code setSocketFactory(SSLSocketFactory)}, similar to “old style SSL” XMPP connections and https.</p>
+<p>CCS requires a Transport Layer Security (TLS) connection. That means the  XMPP
+client must initiate a TLS connection.
+For example in Java, you would call {@code setSocketFactory(SSLSocketFactory)}.</p>
 
-<p>CCS requires a SASL PLAIN authentication mechanism using {@code &lt;your_GCM_Sender_Id&gt;&#64;gcm.googleapis.com} (GCM sender ID) and the API key as the password, where the sender ID and API key are the same as described in <a href="gs.html">Getting Started</a>.</p>
+<p>CCS requires a SASL PLAIN authentication mechanism using
+{@code &lt;your_GCM_Sender_Id&gt;&#64;gcm.googleapis.com} (GCM sender ID) and the
+API key as the password, where the sender ID and API key are the same as described
+in <a href="gs.html">Getting Started</a>.</p>
 
 <p> You can use most XMPP libraries to interact with CCS.</p>
 
-<h3 id="send_msg">Sending messages</h3>
+<h3 id="auth">Authentication</h3>
 
 <p>The following snippets illustrate how to perform authentication in CCS.</p>
 <h4>Client</h4>
@@ -108,13 +111,13 @@
 <h4>Client</h4>
 <pre>&lt;auth mechanism=&quot;PLAIN&quot;
 xmlns=&quot;urn:ietf:params:xml:ns:xmpp-sasl&quot;&gt;MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb
-mRyb2lkLmNvbQAxMjYyMDAzNDc5FzNAcHJvamVjdHMtZ2EtLmFuZHJvaWQuY29tAEFJe
 mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==&lt;/auth&gt;
 </pre>
+
 <h4>Server</h4>
 <pre>&lt;success xmlns=&quot;urn:ietf:params:xml:ns:xmpp-sasl&quot;/&gt;</pre>
 
-<h3 id="format">Message Format</h3>
+<h2 id="format">Message Format</h2>
 <p>CCS uses normal XMPP <code>&lt;message&gt;</code> stanzas. The body of the message must be:
 </p>
 <pre>
@@ -123,25 +126,42 @@
 &lt;/gcm&gt;
 </pre>
 
-<p>The JSON payload for server-to-device is similar to what the GCM http endpoint uses, with these exceptions:</p>
+<p>The JSON payload for server-to-device is similar to what the GCM http endpoint
+uses, with these exceptions:</p>
 <ul>
   <li>There is no support for multiple recipients.</li>
   <li>{@code to} is used instead of {@code registration_ids}.</li>
-  <li>CCS adds the field {@code message_id}, which is required. This ID uniquely identifies the message in an XMPP connection. The ACK or NACK from CCS uses the {@code message_id} to identify a message sent from 3rd-party servers to CCS. Therefore, it's important that this {@code message_id} not only be unique, but always present.</li>
+  <li>CCS adds the field {@code message_id}, which is required. This ID uniquely
+identifies the message in an XMPP connection. The ACK or NACK from CCS uses the
+{@code message_id} to identify a message sent from 3rd-party app servers to CCS.
+Therefore, it's important that this {@code message_id} not only be unique, but
+always present.</li>
 
-  <li>For ACK/NACK messages that are special control messages, you also need to include a {@code message_type} field in the JSON message. For example:
+<li>For ACK/NACK messages that are special control messages, you also need to
+include a {@code message_type} field in the JSON message. The value can be either
+'ack' or 'nack'. For example:
 
-<pre>message_type = ('ack' OR 'nack');</pre>
+<pre>message_type = ('ack');</pre>
   </li>
 </ul>
-<p>For each message a device sends to the server, you need to send an ACK message. You never need to send a NACK message. If you don't send an ACK for a message, CCS will just resend it.
+<p>For each device message your app server receives from CCS, it needs to send
+an ACK message.
+It never needs to send a NACK message. If you don't send an ACK for a message,
+CCS will just resend it.
 </p>
-<p>CCS also sends an ACK or NACK for each server-to-device message. If you do not receive either, it means that the TCP connection was closed in the middle of the operation and your server needs to resend the messages.
+<p>CCS also sends an ACK or NACK for each server-to-device message. If you do not
+receive either, it means that the TCP connection was closed in the middle of the
+operation and your server needs to resend the messages. See
+<a href="#flow">Flow Control</a> for details.
 </p>
 
-<h3 id="msg_examples">Message Examples</h3>
+<p class="note"><strong>Note:</strong> See
+<a href="server.html#params">Implementing GCM Server</a> for a list of all the message
+parameters and which connection server(s) supports them.</p>
 
-<p>Here is an XMPP stanza containing the JSON message from a 3rd-party server to CCS:
+<h3 id="request">Request format</h3>
+
+<p>Here is an XMPP stanza containing the JSON message from a 3rd-party app server to CCS:
 
 </p>
 <pre>&lt;message id=&quot;&quot;&gt;
@@ -160,7 +180,15 @@
 &lt;/message&gt;
 </pre>
 
-<p>Here is an XMPP stanza containing the ACK/NACK message from CCS to 3rd-party server:
+<h3 id="response">Response format</h3>
+
+<p>A CCS response can have 3 possible forms. The first one is a regular 'ack'
+message. But when the response contains an error, there are 2
+different forms the message can take, described below.</p>
+
+<h4 id="ack">ACK message</h4>
+
+<p>Here is an XMPP stanza containing the ACK/NACK message from CCS to 3rd-party app server:
 </p>
 <pre>&lt;message id=&quot;&quot;&gt;
   &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
@@ -171,24 +199,138 @@
   }
   &lt;/gcm&gt;
 &lt;/message&gt;
+</pre>
 
-&lt;message id=&quot;&quot;&gt;
-  &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
+<h4 id="nack">NACK message</h4>
+
+<p>A NACK error is a regular XMPP message in which the {@code message_type} status
+message is &quot;nack&quot;. A NACK message contains:</p>
+<ul>
+<li>Nack error code.</li>
+<li>Nack error description.</li>
+</ul>
+
+<p>Below are some examples.</p>
+
+<p>Bad registration:</p>
+<pre>&lt;message&gt;
+  &lt;data:gcm xmlns:data=&quot;google:mobile:data&quot;&gt;
   {
-      &quot;from&quot;:&quot;REGID&quot;,
-      &quot;message_id&quot;:&quot;m-1366082849205&quot;
-      &quot;error&quot;: ERROR_CODE,
-      &quot;message_type&quot;:&quot;nack&quot;
+    &quot;error&quot;:&quot;BAD_REGISTRATION&quot;,  // error code
+    &quot;message_id&quot;:&quot;msgId1&quot;,
+    &quot;from&quot;:&quot;PA91bHFOtaQGSwupt5l1og&quot;,
+    &quot;message_type&quot;:&quot;nack&quot;
   }
+  &lt;/data:gcm&gt;
+&lt;/message&gt;</pre>
+
+<p>Invalid "time to live":</p>
+
+<pre>&lt;message&gt;
+  &lt;data:gcm xmlns:data=&quot;google:mobile:data&quot;&gt;
+  {
+     &quot;error&quot;:&quot;InvalidJson : INVALID_TTL : Invalid value (-1) for \&quot;time_to_live\&quot;: must be between 0 and \&quot;2419200\&quot;\n&quot;,
+     &quot;message_id&quot;:&quot;msgId1&quot;,
+     &quot;from&quot;:&quot;APA91bHFOtaQGSwupt5l1og&quot;,
+     &quot;message_type&quot;:&quot;nack&quot;
+  }
+  &lt;/data:gcm&gt;
+&lt;/message&gt;</pre>
+
+<p>JSON type error:</p>
+
+<pre>&lt;message&gt;
+  &lt;data:gcm xmlns:data=&quot;google:mobile:data&quot;&gt;
+  {
+     &quot;error&quot;:&quot;InvalidJson : JSON_TYPE_ERROR : Field \&quot;delay_while_idle\&quot; must be a JSON java.lang.Boolean: not-boolean-user-supplied-value\n&quot;,
+     &quot;message_id&quot;:&quot;msgId1&quot;,
+     &quot;from&quot;:&quot;APA91bHFOtaQGSwupt5l1og&quot;,
+     &quot;message_type&quot;:&quot;nack&quot;
+  }
+  &lt;/data:gcm&gt;
+&lt;/message&gt;</pre>
+
+
+<p>The following table lists some of the more common NACK error codes.</p>
+
+<p class="table-caption" id="table1">
+  <strong>Table 1.</strong> NACK error codes.</p>
+
+<table border="1">
+<tr>
+<th>Error Code</th>
+<th>Description</th>
+</tr>
+<tr>
+<td>{@code BAD_REGISTRATION}</td>
+<td>The device has a registration ID, but it's invalid.</td>
+</tr>
+<tr>
+<td>{@code DEVICE_UNREGISTERED}</td>
+<td>The device is not registered.</td>
+</tr>
+<tr>
+<td>{@code INTERNAL_SERVER_ERROR}</td>
+<td>The server encountered an error while trying to process the request.</td>
+</tr>
+<tr>
+<td>{@code SERVICE_UNAVAILABLE}</td>
+<td>The CCS connection server is temporarily unavailable, try again later
+(using exponential backoff, etc.).</td>
+</tr>
+<tr>
+<td>{@code BAD_ACK}</td>
+<td>The ACK message is improperly formed.</td>
+</tr>
+<tr>
+<td>{@code AUTHENTICATION_FAILED}</td>
+<td>This is a 401 error indicating that there was an error authenticating the sender account.</td>
+</tr>
+<tr>
+<td>{@code INVALID_TTL}</td>
+<td>There was an error in the supplied "time to live" value.</td>
+</tr>
+<tr>
+<td>{@code JSON_TYPE_ERROR}</td>
+<td>There was an error in the supplied JSON data type.</td>
+</tr>
+</table>
+
+<h4 id="stanza">Stanza error</h4>
+
+<p>You can also get a stanza error in certain cases.
+A stanza error contains:</p>
+<ul>
+<li>Stanza error code.</li>
+<li>Stanza error description (free text).</li>
+</ul>
+<p>For example:</p>
+
+<pre>&lt;message id=&quot;3&quot; type=&quot;error&quot; to=&quot;123456789@gcm.googleapis.com/ABC&quot;&gt;
+  &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
+     {&quot;random&quot;: &quot;text&quot;}
   &lt;/gcm&gt;
+  &lt;error code=&quot;400&quot; type=&quot;modify&quot;&gt;
+    &lt;bad-request xmlns=&quot;urn:ietf:params:xml:ns:xmpp-stanzas&quot;/&gt;
+    &lt;text xmlns=&quot;urn:ietf:params:xml:ns:xmpp-stanzas&quot;&gt;
+      InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n
+    &lt;/text&gt;
+  &lt;/error&gt;
 &lt;/message&gt;
 </pre>
 
-<h4>Upstream Messages</h4>
 
-<p>Using CCS and the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">GoogleCloudMessaging</a> API, you can send messages from a user's device to the cloud.</p>
+<h2 id="upstream">Upstream Messages</h2>
 
-<p>Here is how you send an upstream message using the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">GoogleCloudMessaging</a> API. For a complete example, see <a href="gs.html#gs_example">Getting Started</a>:</p>
+<p>Using CCS and the
+<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a>
+API, you can send messages from a user's device to the cloud.</p>
+
+<p>Here is how you send an upstream message using the
+<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a>
+API. For a complete example, see <a href="client.html">Implementing GCM Client</a>:</p>
 
 <pre>GoogleCloudMessaging gcm = GoogleCloudMessaging.get(context);
 String GCM_SENDER_ID = "Your-Sender-ID";
@@ -198,12 +340,15 @@
 // Bundle data consists of a key-value pair
 data.putString("hello", "world");
 // "time to live" parameter
+// This is optional. It specifies a value in seconds up to 4 weeks.
 int ttl = [0 seconds, 4 weeks]
 
 gcm.send(GCM_SENDER_ID + "&#64;gcm.googleapis.com", id, ttl, data);
 </pre>
 
-<p>This call generates the necessary XMPP stanza for sending the upstream message. The message goes from the app on the device to CCS to the 3rd-party server. The stanza has the following format:</p>
+<p>This call generates the necessary XMPP stanza for sending the upstream message.
+The message goes from the app on the device to CCS to the 3rd-party app server.
+The stanza has the following format:</p>
 
 <pre>&lt;message id=&quot;&quot;&gt;
   &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
@@ -219,7 +364,8 @@
   &lt;/gcm&gt;
 &lt;/message&gt;</pre>
 
-<p>Here is the format of the ACK expected by CCS from 3rd-party servers in response to the above message:</p>
+<p>Here is the format of the ACK expected by CCS from 3rd-party app servers in
+response to the above message:</p>
 
 <pre>&lt;message id=&quot;&quot;&gt;
   &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
@@ -231,13 +377,478 @@
   &lt;/gcm&gt;
 &lt;/message&gt;</pre>
 
-
 <h2 id="flow">Flow Control</h2>
 
-<p>Every message sent to CCS receives either an ACK or a NACK response. Messages that haven't received one of these responses are considered pending. If the pending message count reaches 1000, the 3rd-party server should stop sending new messages and wait for CCS to acknowledge some of the existing pending messages.</p>
+<p>Every message sent to CCS receives either an ACK or a NACK response. Messages
+that haven't received one of these responses are considered pending. If the pending
+message count reaches 1000, the 3rd-party app server should stop sending new messages
+and wait for CCS to acknowledge some of the existing pending messages as illustrated in
+figure 1:</p>
 
-<p>Conversely, to avoid overloading the 3rd-party server, CCS will stop sending if there are too many unacknowledged messages. Therefore, the 3rd-party server should "ACK" received messages as soon as possible to maintain a constant flow of incoming messages. The aforementioned pending message limit doesn't apply to these ACKs. Even if the pending message count reaches 1000, the 3rd-party server should continue sending ACKs to avoid blocking delivery of new messages.</p>
+<img src="{@docRoot}images/gcm/CCS-ack.png">
 
-<p>ACKs are only valid within the context of one connection. If the connection is closed before a message can be ACKed, the 3rd-party server should wait for CCS to resend the message before ACKing it again.
+<p class="img-caption">
+  <strong>Figure 1.</strong> Message/ack flow.
 </p>
 
+<p>Conversely, to avoid overloading the 3rd-party app server, CCS will stop sending
+if there are too many unacknowledged messages. Therefore, the 3rd-party app server
+should "ACK" upstream messages, received from the client application via CCS, as soon as possible
+to maintain a constant flow of incoming messages. The aforementioned pending message limit doesn't
+apply to these ACKs. Even if the pending message count reaches 1000, the 3rd-party app server
+should continue sending ACKs for messages received from CCS to avoid blocking delivery of new
+upstream messages.</p>
+
+<p>ACKs are only valid within the context of one connection. If the connection is
+closed before a message can be ACKed, the 3rd-party app server should wait for CCS
+to resend the upstream message before ACKing it again. Similarly, all pending messages for which an
+ACK/NACK was not received from CCS before the connection was closed should be sent again.
+</p>
+
+<h2 id="implement">Implementing an XMPP-based App Server</h2>
+
+<p>This section gives examples of implementing an app server that works with CCS.
+Note that a full GCM implementation requires a client-side implementation, in
+addition to the server. For more information, see <a href="client.html">
+Implementing GCM Client</a>.</a>
+
+<h3 id="smack">Java sample using the Smack library</h3>
+
+<p>Here is a sample app server written in Java, using the
+<a href="http://www.igniterealtime.org/projects/smack/">Smack</a> library.</p>
+
+<pre>import org.jivesoftware.smack.ConnectionConfiguration;
+import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
+import org.jivesoftware.smack.ConnectionListener;
+import org.jivesoftware.smack.PacketInterceptor;
+import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.XMPPConnection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
+import org.jivesoftware.smack.packet.DefaultPacketExtension;
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.jivesoftware.smack.provider.ProviderManager;
+import org.jivesoftware.smack.util.StringUtils;
+import org.json.simple.JSONValue;
+import org.json.simple.parser.ParseException;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.net.ssl.SSLSocketFactory;
+/**
+ * Sample Smack implementation of a client for GCM Cloud Connection Server.
+ *
+ * &lt;p&gt;For illustration purposes only.
+ */
+public class SmackCcsClient {
+
+  Logger logger = Logger.getLogger(&quot;SmackCcsClient&quot;);
+
+  public static final String GCM_SERVER = &quot;gcm.googleapis.com&quot;;
+  public static final int GCM_PORT = 5235;
+
+  public static final String GCM_ELEMENT_NAME = &quot;gcm&quot;;
+  public static final String GCM_NAMESPACE = &quot;google:mobile:data&quot;;
+
+  static Random random = new Random();
+  XMPPConnection connection;
+  ConnectionConfiguration config;
+
+  /**
+   * XMPP Packet Extension for GCM Cloud Connection Server.
+   */
+  class GcmPacketExtension extends DefaultPacketExtension {
+    String json;
+
+    public GcmPacketExtension(String json) {
+      super(GCM_ELEMENT_NAME, GCM_NAMESPACE);
+      this.json = json;
+    }
+
+    public String getJson() {
+      return json;
+    }
+
+    &#64;Override
+    public String toXML() {
+      return String.format(&quot;&lt;%s xmlns=\&quot;%s\&quot;&gt;%s&lt;/%s&gt;&quot;, GCM_ELEMENT_NAME,
+          GCM_NAMESPACE, json, GCM_ELEMENT_NAME);
+    }
+
+    &#64;SuppressWarnings(&quot;unused&quot;)
+    public Packet toPacket() {
+      return new Message() {
+        // Must override toXML() because it includes a &lt;body&gt;
+        &#64;Override
+        public String toXML() {
+
+          StringBuilder buf = new StringBuilder();
+          buf.append(&quot;&lt;message&quot;);
+          if (getXmlns() != null) {
+            buf.append(&quot; xmlns=\&quot;&quot;).append(getXmlns()).append(&quot;\&quot;&quot;);
+          }
+          if (getLanguage() != null) {
+            buf.append(&quot; xml:lang=\&quot;&quot;).append(getLanguage()).append(&quot;\&quot;&quot;);
+          }
+          if (getPacketID() != null) {
+            buf.append(&quot; id=\&quot;&quot;).append(getPacketID()).append(&quot;\&quot;&quot;);
+          }
+          if (getTo() != null) {
+            buf.append(&quot; to=\&quot;&quot;).append(StringUtils.escapeForXML(getTo())).append(&quot;\&quot;&quot;);
+          }
+          if (getFrom() != null) {
+            buf.append(&quot; from=\&quot;&quot;).append(StringUtils.escapeForXML(getFrom())).append(&quot;\&quot;&quot;);
+          }
+          buf.append(&quot;&gt;&quot;);
+          buf.append(GcmPacketExtension.this.toXML());
+          buf.append(&quot;&lt;/message&gt;&quot;);
+          return buf.toString();
+        }
+      };
+    }
+  }
+
+  public SmackCcsClient() {
+    // Add GcmPacketExtension
+    ProviderManager.getInstance().addExtensionProvider(GCM_ELEMENT_NAME,
+        GCM_NAMESPACE, new PacketExtensionProvider() {
+
+      &#64;Override
+      public PacketExtension parseExtension(XmlPullParser parser)
+          throws Exception {
+        String json = parser.nextText();
+        GcmPacketExtension packet = new GcmPacketExtension(json);
+        return packet;
+      }
+    });
+  }
+
+  /**
+   * Returns a random message id to uniquely identify a message.
+   *
+   * &lt;p&gt;Note:
+   * This is generated by a pseudo random number generator for illustration purpose,
+   * and is not guaranteed to be unique.
+   *
+   */
+  public String getRandomMessageId() {
+    return &quot;m-&quot; + Long.toString(random.nextLong());
+  }
+
+  /**
+   * Sends a downstream GCM message.
+   */
+  public void send(String jsonRequest) {
+    Packet request = new GcmPacketExtension(jsonRequest).toPacket();
+    connection.sendPacket(request);
+  }
+
+  /**
+   * Handles an upstream data message from a device application.
+   *
+   * &lt;p&gt;This sample echo server sends an echo message back to the device.
+   * Subclasses should override this method to process an upstream message.
+   */
+  public void handleIncomingDataMessage(Map&lt;String, Object&gt; jsonObject) {
+    String from = jsonObject.get(&quot;from&quot;).toString();
+
+    // PackageName of the application that sent this message.
+    String category = jsonObject.get(&quot;category&quot;).toString();
+
+    // Use the packageName as the collapseKey in the echo packet
+    String collapseKey = &quot;echo:CollapseKey&quot;;
+    &#64;SuppressWarnings(&quot;unchecked&quot;)
+    Map&lt;String, String&gt; payload = (Map&lt;String, String&gt;) jsonObject.get(&quot;data&quot;);
+    payload.put(&quot;ECHO&quot;, &quot;Application: &quot; + category);
+
+    // Send an ECHO response back
+    String echo = createJsonMessage(from, getRandomMessageId(), payload, collapseKey, null, false);
+    send(echo);
+  }
+
+  /**
+   * Handles an ACK.
+   *
+   * &lt;p&gt;By default, it only logs a {@code INFO} message, but subclasses could override it to
+   * properly handle ACKS.
+   */
+  public void handleAckReceipt(Map&lt;String, Object&gt; jsonObject) {
+    String messageId = jsonObject.get(&quot;message_id&quot;).toString();
+    String from = jsonObject.get(&quot;from&quot;).toString();
+    logger.log(Level.INFO, &quot;handleAckReceipt() from: &quot; + from + &quot;, messageId: &quot; + messageId);
+  }
+
+  /**
+   * Handles a NACK.
+   *
+   * &lt;p&gt;By default, it only logs a {@code INFO} message, but subclasses could override it to
+   * properly handle NACKS.
+   */
+  public void handleNackReceipt(Map&lt;String, Object&gt; jsonObject) {
+    String messageId = jsonObject.get(&quot;message_id&quot;).toString();
+    String from = jsonObject.get(&quot;from&quot;).toString();
+    logger.log(Level.INFO, &quot;handleNackReceipt() from: &quot; + from + &quot;, messageId: &quot; + messageId);
+  }
+
+  /**
+   * Creates a JSON encoded GCM message.
+   *
+   * &#64;param to RegistrationId of the target device (Required).
+   * &#64;param messageId Unique messageId for which CCS will send an &quot;ack/nack&quot; (Required).
+   * &#64;param payload Message content intended for the application. (Optional).
+   * &#64;param collapseKey GCM collapse_key parameter (Optional).
+   * &#64;param timeToLive GCM time_to_live parameter (Optional).
+   * &#64;param delayWhileIdle GCM delay_while_idle parameter (Optional).
+   * &#64;return JSON encoded GCM message.
+   */
+  public static String createJsonMessage(String to, String messageId, Map&lt;String, String&gt; payload,
+      String collapseKey, Long timeToLive, Boolean delayWhileIdle) {
+    Map&lt;String, Object&gt; message = new HashMap&lt;String, Object&gt;();
+    message.put(&quot;to&quot;, to);
+    if (collapseKey != null) {
+      message.put(&quot;collapse_key&quot;, collapseKey);
+    }
+    if (timeToLive != null) {
+      message.put(&quot;time_to_live&quot;, timeToLive);
+    }
+    if (delayWhileIdle != null &amp;&amp; delayWhileIdle) {
+      message.put(&quot;delay_while_idle&quot;, true);
+    }
+    message.put(&quot;message_id&quot;, messageId);
+    message.put(&quot;data&quot;, payload);
+    return JSONValue.toJSONString(message);
+  }
+
+  /**
+   * Creates a JSON encoded ACK message for an upstream message received from an application.
+   *
+   * &#64;param to RegistrationId of the device who sent the upstream message.
+   * &#64;param messageId messageId of the upstream message to be acknowledged to CCS.
+   * &#64;return JSON encoded ack.
+   */
+  public static String createJsonAck(String to, String messageId) {
+    Map&lt;String, Object&gt; message = new HashMap&lt;String, Object&gt;();
+    message.put(&quot;message_type&quot;, &quot;ack&quot;);
+    message.put(&quot;to&quot;, to);
+    message.put(&quot;message_id&quot;, messageId);
+    return JSONValue.toJSONString(message);
+  }
+
+  /**
+   * Connects to GCM Cloud Connection Server using the supplied credentials.
+   *
+   * &#64;param username GCM_SENDER_ID&#64;gcm.googleapis.com
+   * &#64;param password API Key
+   * &#64;throws XMPPException
+   */
+  public void connect(String username, String password) throws XMPPException {
+    config = new ConnectionConfiguration(GCM_SERVER, GCM_PORT);
+    config.setSecurityMode(SecurityMode.enabled);
+    config.setReconnectionAllowed(true);
+    config.setRosterLoadedAtLogin(false);
+    config.setSendPresence(false);
+    config.setSocketFactory(SSLSocketFactory.getDefault());
+
+    // NOTE: Set to true to launch a window with information about packets sent and received
+    config.setDebuggerEnabled(true);
+
+    // -Dsmack.debugEnabled=true
+    XMPPConnection.DEBUG_ENABLED = true;
+
+    connection = new XMPPConnection(config);
+    connection.connect();
+
+    connection.addConnectionListener(new ConnectionListener() {
+
+      &#64;Override
+      public void reconnectionSuccessful() {
+        logger.info(&quot;Reconnecting..&quot;);
+      }
+
+      &#64;Override
+      public void reconnectionFailed(Exception e) {
+        logger.log(Level.INFO, &quot;Reconnection failed.. &quot;, e);
+      }
+
+      &#64;Override
+      public void reconnectingIn(int seconds) {
+        logger.log(Level.INFO, &quot;Reconnecting in %d secs&quot;, seconds);
+      }
+
+      &#64;Override
+      public void connectionClosedOnError(Exception e) {
+        logger.log(Level.INFO, &quot;Connection closed on error.&quot;);
+      }
+
+      &#64;Override
+      public void connectionClosed() {
+        logger.info(&quot;Connection closed.&quot;);
+      }
+    });
+
+    // Handle incoming packets
+    connection.addPacketListener(new PacketListener() {
+
+      &#64;Override
+      public void processPacket(Packet packet) {
+        logger.log(Level.INFO, &quot;Received: &quot; + packet.toXML());
+        Message incomingMessage = (Message) packet;
+        GcmPacketExtension gcmPacket =
+            (GcmPacketExtension) incomingMessage.getExtension(GCM_NAMESPACE);
+        String json = gcmPacket.getJson();
+        try {
+          &#64;SuppressWarnings(&quot;unchecked&quot;)
+          Map&lt;String, Object&gt; jsonObject =
+              (Map&lt;String, Object&gt;) JSONValue.parseWithException(json);
+
+          // present for &quot;ack&quot;/&quot;nack&quot;, null otherwise
+          Object messageType = jsonObject.get(&quot;message_type&quot;);
+
+          if (messageType == null) {
+            // Normal upstream data message
+            handleIncomingDataMessage(jsonObject);
+
+            // Send ACK to CCS
+            String messageId = jsonObject.get(&quot;message_id&quot;).toString();
+            String from = jsonObject.get(&quot;from&quot;).toString();
+            String ack = createJsonAck(from, messageId);
+            send(ack);
+          } else if (&quot;ack&quot;.equals(messageType.toString())) {
+            // Process Ack
+            handleAckReceipt(jsonObject);
+          } else if (&quot;nack&quot;.equals(messageType.toString())) {
+            // Process Nack
+            handleNackReceipt(jsonObject);
+          } else {
+            logger.log(Level.WARNING, &quot;Unrecognized message type (%s)&quot;,
+                messageType.toString());
+          }
+        } catch (ParseException e) {
+          logger.log(Level.SEVERE, &quot;Error parsing JSON &quot; + json, e);
+        } catch (Exception e) {
+          logger.log(Level.SEVERE, &quot;Couldn't send echo.&quot;, e);
+        }
+      }
+    }, new PacketTypeFilter(Message.class));
+
+
+    // Log all outgoing packets
+    connection.addPacketInterceptor(new PacketInterceptor() {
+      &#64;Override
+      public void interceptPacket(Packet packet) {
+        logger.log(Level.INFO, &quot;Sent: {0}&quot;,  packet.toXML());
+      }
+    }, new PacketTypeFilter(Message.class));
+
+    connection.login(username, password);
+  }
+
+  public static void main(String [] args) {
+    final String userName = &quot;Your GCM Sender Id&quot; + &quot;&#64;gcm.googleapis.com&quot;;
+    final String password = &quot;API Key&quot;;
+
+    SmackCcsClient ccsClient = new SmackCcsClient();
+
+    try {
+      ccsClient.connect(userName, password);
+    } catch (XMPPException e) {
+      e.printStackTrace();
+    }
+
+    // Send a sample hello downstream message to a device.
+    String toRegId = &quot;RegistrationIdOfTheTargetDevice&quot;;
+    String messageId = ccsClient.getRandomMessageId();
+    Map&lt;String, String&gt; payload = new HashMap&lt;String, String&gt;();
+    payload.put(&quot;Hello&quot;, &quot;World&quot;);
+    payload.put(&quot;CCS&quot;, &quot;Dummy Message&quot;);
+    payload.put(&quot;EmbeddedMessageId&quot;, messageId);
+    String collapseKey = &quot;sample&quot;;
+    Long timeToLive = 10000L;
+    Boolean delayWhileIdle = true;
+    ccsClient.send(createJsonMessage(toRegId, messageId, payload, collapseKey,
+        timeToLive, delayWhileIdle));
+  }
+}</pre>
+<h3 id="python">Python sample</h3>
+
+<p>Here is an example of a CCS app server written in Python. This sample echo
+server sends an initial message, and for every upstream message received, it sends
+a dummy response back to the application that sent the upstream message. This
+example illustrates how to connect, send, and receive GCM messages using XMPP. It
+shouldn't be used as-is on a production deployment.</p>
+
+<pre>
+#!/usr/bin/python
+import sys, json, xmpp, random, string
+
+SERVER = 'gcm.googleapis.com'
+PORT = 5235
+USERNAME = "Your GCM Sender Id"
+PASSWORD = "API Key"
+REGISTRATION_ID = "Registration Id of the target device"
+
+unacked_messages_quota = 1000
+send_queue = []
+
+# Return a random alphanumerical id
+def random_id():
+  rid = ''
+  for x in range(8): rid += random.choice(string.ascii_letters + string.digits)
+  return rid
+
+def message_callback(session, message):
+  global unacked_messages_quota
+  gcm = message.getTags('gcm')
+  if gcm:
+    gcm_json = gcm[0].getData()
+    msg = json.loads(gcm_json)
+    if not msg.has_key('message_type'):
+      # Acknowledge the incoming message immediately.
+      send({'to': msg['from'],
+            'message_type': 'ack',
+            'message_id': msg['message_id']})
+      # Queue a response back to the server.
+      if msg.has_key('from'):
+        # Send a dummy echo response back to the app that sent the upstream message.
+        send_queue.append({'to': msg['from'],
+                           'message_id': random_id(),
+                           'data': {'pong': 1}})
+    elif msg['message_type'] == 'ack' or msg['message_type'] == 'nack':
+      unacked_messages_quota += 1
+
+def send(json_dict):
+  template = (&quot;&lt;message&gt;&lt;gcm xmlns='google:mobile:data'&gt;{1}&lt;/gcm&gt;&lt;/message&gt;&quot;)
+  client.send(xmpp.protocol.Message(
+      node=template.format(client.Bind.bound[0], json.dumps(json_dict))))
+
+def flush_queued_messages():
+  global unacked_messages_quota
+  while len(send_queue) and unacked_messages_quota &gt; 0:
+    send(send_queue.pop(0))
+    unacked_messages_quota -= 1
+
+client = xmpp.Client('gcm.googleapis.com', debug=['socket'])
+client.connect(server=(SERVER,PORT), secure=1, use_srv=False)
+auth = client.auth(USERNAME, PASSWORD)
+if not auth:
+  print 'Authentication failed!'
+  sys.exit(1)
+
+client.RegisterHandler('message', message_callback)
+
+send_queue.append({'to': REGISTRATION_ID,
+                   'message_id': 'reg_id',
+                   'data': {'message_destination': 'RegId',
+                            'message_id': random_id()}})
+
+while True:
+  client.Process(1)
+  flush_queued_messages()</pre>
diff --git a/docs/html/google/gcm/client.jd b/docs/html/google/gcm/client.jd
index 7604932..916ecee 100644
--- a/docs/html/google/gcm/client.jd
+++ b/docs/html/google/gcm/client.jd
@@ -1,24 +1,665 @@
-page.title=GCM Client
-page.tags="cloud","push","messaging"
+page.title=Implementing GCM Client
+page.tags=cloud,push,messaging
 @jd:body
 
 <div id="qv-wrapper">
 <div id="qv">
 
+
+<h2>In this document</h2>
+
+<ol class="toc">
+<li><a href="#play-services">Set Up Google Play Services</a></li>
+<li><a href="#manifest">Edit Your Application's Manifest</a></li>
+<li><a href="#app">Write Your Application</a>
+  <ol class="toc">
+    <li><a href="#sample-play">Check for Google Play Services APK</a></li>
+    <li><a href="#sample-register">Register for GCM</a></li>
+    <li><a href="#sample-send">Send a message</a></li>
+    <li><a href="#sample-receive">Receive a message</a></li>
+  </ol>
+  <li><a href="#run">Running the Sample</a></li>
+  <li><a href="#stats">Viewing Statistics</a></li>
+</li>
+
+</ol>
+
 <h2>See Also</h2>
 
 <ol class="toc">
 <li><a href="gs.html">Getting Started</a></li>
-<li><a href="server.html">GCM Server</a></li>
+<li><a href="server.html">Implementing GCM Server</a></li>
 </ol>
 
 </div>
 </div>
 
-<p>A GCM client is a GCM-enabled app that runs on an Android device. To write your client code, we recommend that you use the new <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs. The client helper library that was offered in previous versions of GCM still works, but it has been superseded by the more efficient <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs.</p>
+<p>A GCM client is a GCM-enabled app that runs on an Android device. To write your
+client code, we recommend that you use the
+<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a> APIs.
+The client helper library that was offered in previous versions of GCM still works,
+but it has been superseded by the more efficient
+<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a> APIs.</p>
 
-<p>A full GCM implementation requires both a client implementation and a server-side implementation. For a step-by-step guide to creating a complete sample implementation that includes both client and server, see <a href="gs.html">Getting Started</a>. </p>
+<p>A full GCM implementation requires both a client implementation and a server
+implementation. For more
+information about implementing the server side, see <a href="server.html">
+Implementing GCM Server</a>.</p>
 
-<p>
+<p>The following sections walk you through the steps involved in writing a GCM
+client-side application. Your client app can be arbitrarily complex, but at bare
+minimum, a GCM client app must include code to register (and thereby get a
+registration ID), and a broadcast receiver to receive messages sent by GCM.
+</p>
 
+<h2 id="play-services">Step 1: Set Up Google Play Services</h2>
+
+<p>To write your client application, use the
+<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a> API.
+To use this API, you must set up your project to use the Google Play services SDK,
+as described in <a href="/google/play-services/setup.html">Setup Google Play
+Services SDK</a>.</p>
+
+<p class="note"><strong>Caution:</strong> When you add the Play Services library to
+your project, be sure to add it <em>with resources</em>, as described in
+<a href="{@docRoot}google/play-services/setup.html#Setup">
+Setup Google Play Services SDK</a>. The key point is that you must
+<em>reference</em> the library&mdash;simply adding a {@code .jar} file to
+your Eclipse project will not work. You must follow the directions
+for referencing a library, or your app won't be able to access
+the library's resources, and it won't run properly.
+If you're using Android Studio, this is the string to add to the
+{@code dependency} section of your application's {@code build.gradle} file:</p>
+
+<pre>dependencies {
+   compile: "com.google.android.gms:play-services:3.1.+"
+}
+</pre>
+
+
+<h2 id="manifest">Step 2: Edit Your Application's Manifest</h2>
+
+<p>Add the following to your application's manifest:</p>
+<ul>
+  <li>The <code>com.google.android.c2dm.permission.RECEIVE</code> permission so
+the Android application can register and receive messages.</li>
+  <li>The <code>android.permission.INTERNET</code> permission so the Android
+application can send the registration ID to the 3rd party server.</li>
+  <li>The <code>android.permission.GET_ACCOUNTS</code> permission as GCM requires
+a Google account (necessary only if if the device is running a version lower than
+Android 4.0.4)</li>
+  <li>The <code>android.permission.WAKE_LOCK</code> permission so the application
+can keep the processor from sleeping when a message is received. Optional&mdash;use
+only if the app wants to keep the device from sleeping.</li>
+  <li>An <code>applicationPackage + &quot;.permission.C2D_MESSAGE&quot;</code>
+permission to prevent other Android applications from registering and receiving
+the Android application's messages. The permission name must exactly match this
+pattern&mdash;otherwise the Android application will not receive the messages.</li>
+   <li>A receiver for <code>com.google.android.c2dm.intent.RECEIVE</code>, with
+the category set
+as <code>applicationPackage</code>. The receiver should require the
+<code>com.google.android.c2dm.SEND</code> permission, so that only the GCM
+Framework can send a message to it. If your app uses an {@link android.app.IntentService}
+(not required, but a common pattern), this receiver should be an instance of
+{@link android.support.v4.content.WakefulBroadcastReceiver}.
+A {@link android.support.v4.content.WakefulBroadcastReceiver} takes care of
+creating and managing a
+<a href="{@docRoot}reference/android/os/PowerManager.html#PARTIAL_WAKE_LOCK">
+partial wake lock</a> for your app.</li>
+
+<li>A {@link android.app.Service} (typically an {@link android.app.IntentService})
+to which the {@link android.support.v4.content.WakefulBroadcastReceiver} passes off
+the work of handling the GCM message, while ensuring that the device does not
+go back to sleep in the process. Including an {@link android.app.IntentService} is
+optional&mdash;you could choose to process your messages in a regular
+{@link android.content.BroadcastReceiver} instead, but realistically, most apps will
+use a {@link android.app.IntentService}.
+</li>
+  <li>If the GCM feature is critical to the Android application's function, be sure to
+set <code>android:minSdkVersion=&quot;8&quot;</code> or higher in the manifest. This
+ensures that the Android application cannot be installed in an environment in which it
+could not run properly. </li>
+</ul>
+
+<p>Here are excerpts from a sample manifest that supports GCM:</p>
+
+<pre class="prettyprint pretty-xml">
+&lt;manifest package="com.example.gcm" ...&gt;
+
+    &lt;uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/&gt;
+    &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
+    &lt;uses-permission android:name="android.permission.GET_ACCOUNTS" /&gt;
+    &lt;uses-permission android:name="android.permission.WAKE_LOCK" /&gt;
+    &lt;uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /&gt;
+
+    &lt;permission android:name="com.example.gcm.permission.C2D_MESSAGE"
+        android:protectionLevel="signature" /&gt;
+    &lt;uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" /&gt;
+
+    &lt;application ...&gt;
+        &lt;receiver
+            android:name=".GcmBroadcastReceiver"
+            android:permission="com.google.android.c2dm.permission.SEND" &gt;
+            &lt;intent-filter&gt;
+                &lt;action android:name="com.google.android.c2dm.intent.RECEIVE" /&gt;
+                &lt;category android:name="com.example.gcm" /&gt;
+            &lt;/intent-filter&gt;
+        &lt;/receiver&gt;
+        &lt;service android:name=".GcmIntentService" /&gt;
+    &lt;/application&gt;
+
+&lt;/manifest&gt;
+</pre>
+
+<h2 id="app"> Step 3: Write Your Application</h2>
+
+<p>Finally, write your application. This section features a sample client
+application that illustrates how to use the
+<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a> APIs. The sample consists of a main activity
+({@code DemoActivity}), a {@link android.support.v4.content.WakefulBroadcastReceiver}
+({@code GcmBroadcastReceiver}), and an {@link android.app.IntentService}
+({@code GcmIntentService}). You can find the complete source code for this sample at the
+<a href="http://code.google.com/p/gcm">open source site</a>.</p>
+
+<p>Note the following:</p>
+
+<ul>
+  <li>Among other things, the sample illustrates registration and upstream
+(device-to-cloud) messaging. Upstream messaging only applies to apps that are running against a
+<a href="ccs.html">CCS</a> (XMPP) server; HTTP-based servers don't support upstream messaging.</li>
+  <li>The <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+  {@code GoogleCloudMessaging}</a>
+registration APIs replace the old registration process, which was based on the
+now-obsolete client helper library. While the old registration process still works,
+we encourage you to use the newer
+<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a>
+registration APIs, regardless of your underlying server.</li>
+</ul>
+
+<h3 id="sample-play">Check for Google Play Services APK</h3>
+
+<p>As described in <a href="{@docRoot}google/play-services/setup.html">
+Setup Google Play Services SDK</a>, apps that rely on the Play Services SDK
+should always check the device for a compatible Google Play services APK before
+accessing Google Play services features. In the sample app this check is done in
+two places: in the main activity's {@code onCreate()} method, and in its
+{@code onResume()} method. The check in {@code onCreate()} ensures that the app
+can't be used without a successful check. The check in {@code onResume()} ensures
+that if the user returns to the running app through some other means, such as
+through the back button, the check is still performed. If the
+device doesn't have a compatible Google Play services APK, your app can call
+{@code GooglePlayServicesUtil.getErrorDialog()} to allow users to download the
+APK from the Google Play Store or enable it in the device's system settings.
+For example:</p>
+
+<pre>private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
+...
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+
+    setContentView(R.layout.main);
+    mDisplay = (TextView) findViewById(R.id.display);
+
+    context = getApplicationContext();
+
+    // Check device for Play Services APK.
+    if (checkPlayServices()) {
+        // If this check succeeds, proceed with normal processing.
+        // Otherwise, prompt user to get valid Play Services APK.
+        ...
+    }
+}
+
+// You need to do the Play Services APK check here too.
+&#64;Override
+protected void onResume() {
+    super.onResume();
+    checkPlayServices();
+}
+
+/**
+ * Check the device to make sure it has the Google Play Services APK. If
+ * it doesn't, display a dialog that allows users to download the APK from
+ * the Google Play Store or enable it in the device's system settings.
+ */
+private boolean checkPlayServices() {
+    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
+    if (resultCode != ConnectionResult.SUCCESS) {
+        if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
+            GooglePlayServicesUtil.getErrorDialog(resultCode, this,
+                    PLAY_SERVICES_RESOLUTION_REQUEST).show();
+        } else {
+            Log.i(TAG, "This device is not supported.");
+            finish();
+        }
+        return false;
+    }
+    return true;
+}</pre>
+
+<h3 id="sample-register">Register for GCM</h3>
+<p>An Android application needs to register with GCM servers before it can receive
+messages. When an app registers, it receives a registration ID, which it can then
+store for future use. In the following snippet the {@code onCreate()} method in the sample app's
+main activity checks to see if the app is already registered with GCM and with
+the server:</p>
+
+<pre>/**
+ * Main UI for the demo app.
+ */
+public class DemoActivity extends Activity {
+
+    public static final String EXTRA_MESSAGE = "message";
+    public static final String PROPERTY_REG_ID = "registration_id";
+    private static final String PROPERTY_APP_VERSION = "appVersion";
+    private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
+
+    /**
+     * Substitute you own sender ID here. This is the project number you got
+     * from the API Console, as described in "Getting Started."
+     */
+    String SENDER_ID = "Your-Sender-ID";
+
+    /**
+     * Tag used on log messages.
+     */
+    static final String TAG = "GCMDemo";
+
+    TextView mDisplay;
+    GoogleCloudMessaging gcm;
+    AtomicInteger msgId = new AtomicInteger();
+    SharedPreferences prefs;
+    Context context;
+
+    String regid;
+
+    &#64;Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.main);
+        mDisplay = (TextView) findViewById(R.id.display);
+
+        context = getApplicationContext();
+
+        // Check device for Play Services APK. If check succeeds, proceed with
+        //  GCM registration.
+        if (checkPlayServices()) {
+            gcm = GoogleCloudMessaging.getInstance(this);
+            regid = getRegistrationId(context);
+
+            if (regid.isEmpty()) {
+                registerInBackground();
+            }
+        } else {
+            Log.i(TAG, "No valid Google Play Services APK found.");
+        }
+    }
+...
+}</pre>
+
+<p>The app calls {@code getRegistrationId()} to see whether there is an existing
+registration ID stored in shared preferences:</p>
+
+<pre>/**
+ * Gets the current registration ID for application on GCM service.
+ * &lt;p&gt;
+ * If result is empty, the app needs to register.
+ *
+ * &#64;return registration ID, or empty string if there is no existing
+ *         registration ID.
+ */
+private String getRegistrationId(Context context) {
+    final SharedPreferences prefs = getGCMPreferences(context);
+    String registrationId = prefs.getString(PROPERTY_REG_ID, "");
+    if (registrationId.isEmpty()) {
+        Log.i(TAG, "Registration not found.");
+        return "";
+    }
+    // Check if app was updated; if so, it must clear the registration ID
+    // since the existing regID is not guaranteed to work with the new
+    // app version.
+    int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
+    int currentVersion = getAppVersion(context);
+    if (registeredVersion != currentVersion) {
+        Log.i(TAG, "App version changed.");
+        return "";
+    }
+    return registrationId;
+}
+...
+/**
+ * &#64;return Application's {&#64;code SharedPreferences}.
+ */
+private SharedPreferences getGCMPreferences(Context context) {
+    // This sample app persists the registration ID in shared preferences, but
+    // how you store the regID in your app is up to you.
+    return getSharedPreferences(DemoActivity.class.getSimpleName(),
+            Context.MODE_PRIVATE);
+}</pre>
+
+<p>If the registration ID doesn't exist or the app was updated,
+{@code getRegistrationId()} returns an empty string
+to indicate that the app needs to get a new regID. {@code getRegistrationId()} calls
+the following method to check the app version:</p>
+
+<pre>/**
+ * &#64;return Application's version code from the {&#64;code PackageManager}.
+ */
+private static int getAppVersion(Context context) {
+    try {
+        PackageInfo packageInfo = context.getPackageManager()
+                .getPackageInfo(context.getPackageName(), 0);
+        return packageInfo.versionCode;
+    } catch (NameNotFoundException e) {
+        // should never happen
+        throw new RuntimeException("Could not get package name: " + e);
+    }
+}</pre>
+
+
+<p>If there isn't a valid existing registration ID, {@code DemoActivity} calls the
+following {@code registerInBackground()} method to register. Note that because the GCM
+methods {@code register()} and {@code unregister()} are blocking, this has to
+take place on a background thread. This sample uses {@link android.os.AsyncTask}
+to accomplish this:</p>
+
+<pre>
+/**
+ * Registers the application with GCM servers asynchronously.
+ * &lt;p&gt;
+ * Stores the registration ID and app versionCode in the application's
+ * shared preferences.
+ */
+private void registerInBackground() {
+    new AsyncTask<Void, Void, String>() {
+        &#64;Override
+        protected String doInBackground(Void... params) {
+            String msg = "";
+            try {
+                if (gcm == null) {
+                    gcm = GoogleCloudMessaging.getInstance(context);
+                }
+                regid = gcm.register(SENDER_ID);
+                msg = "Device registered, registration ID=" + regid;
+
+                // You should send the registration ID to your server over HTTP,
+                // so it can use GCM/HTTP or CCS to send messages to your app.
+                // The request to your server should be authenticated if your app
+                // is using accounts.
+                sendRegistrationIdToBackend();
+
+                // For this demo: we don't need to send it because the device
+                // will send upstream messages to a server that echo back the
+                // message using the 'from' address in the message.
+
+                // Persist the regID - no need to register again.
+                storeRegistrationId(context, regid);
+            } catch (IOException ex) {
+                msg = "Error :" + ex.getMessage();
+                // If there is an error, don't just keep trying to register.
+                // Require the user to click a button again, or perform
+                // exponential back-off.
+            }
+            return msg;
+        }
+
+        &#64;Override
+        protected void onPostExecute(String msg) {
+            mDisplay.append(msg + "\n");
+        }
+    }.execute(null, null, null);
+    ...
+}</pre>
+
+<p>Once you've received your registration ID, send it to your server:</p>
+<pre>
+/**
+ * Sends the registration ID to your server over HTTP, so it can use GCM/HTTP
+ * or CCS to send messages to your app. Not needed for this demo since the
+ * device sends upstream messages to a server that echoes back the message
+ * using the 'from' address in the message.
+ */
+private void sendRegistrationIdToBackend() {
+    // Your implementation here.
+}</pre>
+
+<p>After registering, the app calls {@code storeRegistrationId()} to store the
+registration ID in shared preferences for future use. This is just one way of
+persisting a regID. You might choose to use a different approach in your app:</p>
+
+<pre>/**
+ * Stores the registration ID and app versionCode in the application's
+ * {&#64;code SharedPreferences}.
+ *
+ * &#64;param context application's context.
+ * &#64;param regId registration ID
+ */
+private void storeRegistrationId(Context context, String regId) {
+    final SharedPreferences prefs = getGCMPreferences(context);
+    int appVersion = getAppVersion(context);
+    Log.i(TAG, "Saving regId on app version " + appVersion);
+    SharedPreferences.Editor editor = prefs.edit();
+    editor.putString(PROPERTY_REG_ID, regId);
+    editor.putInt(PROPERTY_APP_VERSION, appVersion);
+    editor.commit();
+}</pre>
+
+<h3 id="sample-send">Send a message</h3>
+<p>When the user clicks the app's <strong>Send</strong> button, the app sends an
+upstream message using the
+<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a> APIs. In order to receive the upstream message,
+your server should be connected to CCS. You can use one of the demo servers in
+<a href="ccs.html#implement">Implementing an XMPP-based App Server</a> to run the sample and connect
+to CCS.</p>
+
+<pre>public void onClick(final View view) {
+    if (view == findViewById(R.id.send)) {
+        new AsyncTask<Void, Void, String>() {
+            &#64;Override
+            protected String doInBackground(Void... params) {
+                String msg = "";
+                try {
+                    Bundle data = new Bundle();
+                        data.putString("my_message", "Hello World");
+                        data.putString("my_action",
+                                "com.google.android.gcm.demo.app.ECHO_NOW");
+                        String id = Integer.toString(msgId.incrementAndGet());
+                        gcm.send(SENDER_ID + "@gcm.googleapis.com", id, data);
+                        msg = "Sent message";
+                } catch (IOException ex) {
+                    msg = "Error :" + ex.getMessage();
+                }
+                return msg;
+            }
+
+            &#64;Override
+            protected void onPostExecute(String msg) {
+                mDisplay.append(msg + "\n");
+            }
+        }.execute(null, null, null);
+    } else if (view == findViewById(R.id.clear)) {
+        mDisplay.setText("");
+    }
+}</pre>
+
+<h3 id="sample-receive">Receive a message</h3>
+
+<p>As described above in <a href="#manifest">Step 2</a>, the app includes a
+{@link android.support.v4.content.WakefulBroadcastReceiver} for the <code>com.google.android.c2dm.intent.RECEIVE</code>
+intent. A broadcast receiver is the mechanism GCM uses to deliver messages. When {@code onClick()}
+calls {@code gcm.send()}, it triggers the broadcast receiver's {@code onReceive()}
+method, which has the responsibility of making sure that the GCM message gets handled.</p>
+<p>A {@link android.support.v4.content.WakefulBroadcastReceiver} is a special type of
+broadcast receiver that takes care of
+creating and managing a
+<a href="{@docRoot}reference/android/os/PowerManager.html#PARTIAL_WAKE_LOCK">
+partial wake lock</a> for your app.
+It passes off the work of processing the GCM message to a
+{@link android.app.Service} (typically an
+{@link android.app.IntentService}), while ensuring that the device does not
+go back to sleep in the transition. If you don't hold a wake lock while transitioning
+the work to a service, you are effectively allowing the device to go back to sleep before
+the work completes. The net result is that the app might not finish processing
+the GCM message until some arbitrary point in the future, which is not what you want.</p>
+
+<p class="note"><strong>Note:</strong> Using {@link android.support.v4.content.WakefulBroadcastReceiver}
+is not a requirement. If you have a relatively simple app that doesn't require
+a service, you can intercept the GCM message in a regular {@link android.content.BroadcastReceiver}
+and do your processing there. Once you get the intent that GCM passes into
+your broadcast receiver's {@code onReceive()} method, what you do with it
+is up to you.</p>
+
+<p>This snippet starts {@code GcmIntentService} with the method
+{@link android.support.v4.content.WakefulBroadcastReceiver#startWakefulService startWakefulService()}.
+This method is comparable to {@link android.content.Context#startService startService()}, except that
+the {@link android.support.v4.content.WakefulBroadcastReceiver} is holding a
+wake lock when the service starts. The intent that is passed with
+{@link android.support.v4.content.WakefulBroadcastReceiver#startWakefulService startWakefulService()}
+holds an extra identifying the wake lock:</p>
+
+
+<pre>public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
+    &#64;Override
+    public void onReceive(Context context, Intent intent) {
+        // Explicitly specify that GcmIntentService will handle the intent.
+        ComponentName comp = new ComponentName(context.getPackageName(),
+                GcmIntentService.class.getName());
+        // Start the service, keeping the device awake while it is launching.
+        startWakefulService(context, (intent.setComponent(comp)));
+        setResultCode(Activity.RESULT_OK);
+    }
+}</pre>
+
+<p>The intent service shown below does the actual work of handling the GCM
+message. When the service is finished, it calls
+{@link android.support.v4.content.WakefulBroadcastReceiver#completeWakefulIntent GcmBroadcastReceiver.completeWakefulIntent()}
+to release the wake lock. The
+{@link android.support.v4.content.WakefulBroadcastReceiver#completeWakefulIntent completeWakefulIntent()}
+method has as its parameter the same intent that was
+passed in from the {@link android.support.v4.content.WakefulBroadcastReceiver}.
+</p>
+
+<p>This snippet processes the GCM message based on message type, and posts the
+result in a notification. But what you do with GCM messages in your app is up to
+you&mdash;the possibilities are endless. For example, the message might be a ping,
+telling the app to sync to a server to retrieve new content, or it might be a
+chat message that you display in the UI.</p>
+
+<pre>
+public class GcmIntentService extends IntentService {
+    public static final int NOTIFICATION_ID = 1;
+    private NotificationManager mNotificationManager;
+    NotificationCompat.Builder builder;
+
+    public GcmIntentService() {
+        super("GcmIntentService");
+    }
+
+    &#64;Override
+    protected void onHandleIntent(Intent intent) {
+        Bundle extras = intent.getExtras();
+        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
+        // The getMessageType() intent parameter must be the intent you received
+        // in your BroadcastReceiver.
+        String messageType = gcm.getMessageType(intent);
+
+        if (!extras.isEmpty()) {  // has effect of unparcelling Bundle
+            /*
+             * Filter messages based on message type. Since it is likely that GCM
+             * will be extended in the future with new message types, just ignore
+             * any message types you're not interested in, or that you don't
+             * recognize.
+             */
+            if (GoogleCloudMessaging.
+                    MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
+                sendNotification("Send error: " + extras.toString());
+            } else if (GoogleCloudMessaging.
+                    MESSAGE_TYPE_DELETED.equals(messageType)) {
+                sendNotification("Deleted messages on server: " +
+                        extras.toString());
+            // If it's a regular GCM message, do some work.
+            } else if (GoogleCloudMessaging.
+                    MESSAGE_TYPE_MESSAGE.equals(messageType)) {
+                // This loop represents the service doing some work.
+                for (int i=0; i<5; i++) {
+                    Log.i(TAG, "Working... " + (i+1)
+                            + "/5 @ " + SystemClock.elapsedRealtime());
+                    try {
+                        Thread.sleep(5000);
+                    } catch (InterruptedException e) {
+                    }
+                }
+                Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
+                // Post notification of received message.
+                sendNotification("Received: " + extras.toString());
+                Log.i(TAG, "Received: " + extras.toString());
+            }
+        }
+        // Release the wake lock provided by the WakefulBroadcastReceiver.
+        GcmBroadcastReceiver.completeWakefulIntent(intent);
+    }
+
+    // Put the message into a notification and post it.
+    // This is just one simple example of what you might choose to do with
+    // a GCM message.
+    private void sendNotification(String msg) {
+        mNotificationManager = (NotificationManager)
+                this.getSystemService(Context.NOTIFICATION_SERVICE);
+
+        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+                new Intent(this, DemoActivity.class), 0);
+
+        NotificationCompat.Builder mBuilder =
+                new NotificationCompat.Builder(this)
+        .setSmallIcon(R.drawable.ic_stat_gcm)
+        .setContentTitle("GCM Notification")
+        .setStyle(new NotificationCompat.BigTextStyle()
+        .bigText(msg))
+        .setContentText(msg);
+
+        mBuilder.setContentIntent(contentIntent);
+        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
+    }
+}</pre>
+
+<h2 id="run">Running the Sample</h2>
+
+<p>To run the sample:</p>
+
+<ol>
+  <li>Follow the instructions in <a href="gs.html">Getting Started</a> to get your sender ID and
+  API key.</li>
+  <li>Implement your client app, as described in this document. You can find the complete source
+  code for the client app at the <a href="http://code.google.com/p/gcm">open source site</a>.</li>
+  <li>Run one of the demo servers (Java or Python) provided in
+<a href="ccs.html#implement">Implementing an XMPP-based App Server</a>. Whichever demo server you
+ choose, don't forget to edit its code before running it to supply
+your sender ID and API key.
+</li>
+
+</ol>
+
+<h2 id="stats">Viewing Statistics</h2>
+
+<p>To view  statistics and any error messages for your GCM applications:</p>
+<ol>
+  <li> Go to the <code><a href="http://play.google.com/apps/publish">Developer Console</a></code>.</li>
+  <li>Login with your developer account.
+  <p>You will see a page that has a list of all of your apps.</p></li>
+  <li> Click on the &quot;statistics&quot; link next to the app for which you
+want to view GCM stats.
+  <p>Now you are on the statistics page.</p> </li>
+  <li>Go to the drop-down menu and select the GCM metric you want to view.
+  </li>
+</ol>
+<p class="note"><strong>Note:</strong> Stats on the Google API Console are not
+enabled for GCM. You must use the <a href="http://play.google.com/apps/publish">Developer Console</a>.</p>
 
diff --git a/docs/html/google/gcm/gcm.jd b/docs/html/google/gcm/gcm.jd
index ceb82b0..88bf659 100644
--- a/docs/html/google/gcm/gcm.jd
+++ b/docs/html/google/gcm/gcm.jd
@@ -1,48 +1,23 @@
-page.title=GCM Architectural Overview
+page.title=Overview
 @jd:body
 
 <div id="qv-wrapper">
 <div id="qv">
 
-<h2>Quickview</h2>
-
-<ul>
-<li>Get an introduction to key GCM terms and concepts.</li>
-<li>Learn the basic features of a GCM application.</li>
-<li>Understand the role of the 3rd-party application server, and how to send messages and process results.</li>
-</ul>
-
-
 <h2>In this document</h2>
 
 <ol class="toc">
-  <li><a href="#intro">Introduction</a> </li>
-  <li><a href="#arch">Architectural Overview</a>
-    <ol>
-      <li><a href="#lifecycle">Lifecycle Flow</a></li>
-        <ol>
-          <li><a href="#register">Enable GCM</a></li>
-          <li><a href="#push-process">Send a message</a></li>
-          <li><a href="#receiving">Receive a message</a></li>
-        </ol>
-      <li><a href="#user">What Does the User See?</a></li>
-    </ol>
-  </li>
-  <li><a href="#server">Role of  the 3rd-party Application Server</a>
+  <li><a href="#key">Key Concepts</a></li>
+  <li><a href="#arch">Architectural Overview</a></li>
+  <li><a href="#lifecycle">Lifecycle Flow</a>
     <ol class="toc">
-      <li><a href="#send-msg">Sending Messages</a>
-        <ol>
-          <li><a href="#request">Request format</a></li>
-          <li><a href="#response">Response format</a></li>
-        </ol>
-      </li>
+      <li><a href="#register">Enable GCM</a></li>
+      <li><a href="#push-process">Send a message</a></li>
+      <li><a href="#receiving">Receive a message</a></li>
     </ol>
-    <li><a href="#stats">Viewing Statistics</a>
   </li>
 </ol>
 
-
-
 </div>
 </div>
 
@@ -50,24 +25,15 @@
 developers  send data from servers to their Android applications on  Android
 devices, and upstream messages from the user's device back to the cloud.
 This could be a lightweight message telling the Android application
-that there is new data to be fetched from the server (for instance, a movie
-uploaded by a friend), or it could be a message containing up to 4kb of payload
+that there is new data to be fetched from the server (for instance, a "new email"
+notification informing the application that it is out of sync with the back end),
+or it could be a message containing up to 4kb of payload
 data (so apps like instant messaging can consume the message directly). The GCM
 service handles all aspects  of queueing of messages and delivery to the target
 Android application running  on the target device.</p>
-
-<p>GCM introduces GCM Cloud Connection Server (CCS), which you can use
-in tandem with GCM HTTP service/endpoint/APIs.
-CCS uses XMPP, and it offers asynchronous, bidirectional
-messaging. For more information, see
-<a href="ccs.html">GCM Cloud Connection Server</a>.
-  
   
 <p class="note"> To jump right into using GCM with your Android
-  applications, see the instructions in <a href="gs.html">Getting Started</a>.</p>
-
-
-<h2 id="intro">Introduction</h2>
+  applications, see <a href="gs.html">Getting Started</a>.</p>
 
 <p>Here are the primary characteristics of Google Cloud 
 Messaging (GCM):</p>
@@ -75,9 +41,11 @@
 <ul>
   <li>It allows 3rd-party application servers to send messages to
 their Android applications.</li>
-  <li>Using the <a href="ccs.html">GCM Cloud Connection Server</a>, you can receive upstream messages from the user's device.</li>
+  <li>Using the <a href="ccs.html">GCM Cloud Connection Server</a>, you can receive
+upstream messages from the user's device.</li>
   <li>An Android application on an Android device doesn't need to be running to receive
-messages. The system will wake up the Android application via Intent broadcast when the  message arrives, as long as the application is set up with the proper
+messages. The system will wake up the Android application via Intent broadcast
+when the  message arrives, as long as the application is set up with the proper
 broadcast receiver and permissions.</li>
   <li>It does not provide any  built-in user interface or other handling for
 message data. GCM  simply passes raw message data received straight to the
@@ -85,57 +53,67 @@
 application might post a notification, display a custom user interface, or 
 silently sync data.</li>
   <li>It requires devices running Android 2.2 or higher that also have the
-Google Play Store application installed, or or an emulator running Android 2.2 with Google APIs. However, you are not limited to deploying your
+Google Play Store application installed, or or an emulator running Android 2.2
+with Google APIs. However, you are not limited to deploying your
 Android applications through Google Play Store.</li>
-  <li>It uses an existing connection for Google services. For pre-3.0 devices, this requires users to
-set up their Google account on their mobile devices. A Google account is not a requirement on devices running Android 4.0.4 or higher.</li>
+  <li>It uses an existing connection for Google services. For pre-3.0 devices,
+this requires users to
+set up their Google account on their mobile devices. A Google account is not a
+requirement on devices running Android 4.0.4 or higher.</li>
 </ul>
-<h2 id="arch">Architectural Overview</h2>
-<p>This section gives an overview of how GCM works. </p>
+
+<h2 id="key">Key Concepts</h2>
+
 <p>This table summarizes the key terms and concepts involved in GCM. It is
 divided into these categories:</p>
 <ul>
-  <li><strong>Components</strong> &mdash; The physical entities that play a role in
+  <li><strong>Components</strong> &mdash; The entities that play a primary role in
 GCM.</li>
   <li><strong>Credentials</strong> &mdash; The IDs and tokens that are used in
 different stages of GCM to ensure that all parties have been authenticated, and
 that the message is going to the correct place.</li>
 </ul>
 
+<p class="table-caption" id="table1">
+  <strong>Table 1.</strong> GCM components and credentials.</p>
+
 <table>
   <tr>
     <th colspan="2">Components</th>
   </tr>
   <tr>
-    <td width="165"><strong>Mobile Device</strong></td>
-    <td width="1176">The device that is running an Android application that uses
-GCM. This must be a 2.2 Android device that has Google Play Store installed, and it must
-have at least one logged in Google account if the device is running a version lower than Android 4.0.4. Alternatively, for testing you can use an emulator running Android 2.2 with Google APIs.</td>
+    <td width="165"><strong>Client App</strong></td>
+    <td width="1176">The GCM-enabled Android application that is running on a
+    device. This must be a 2.2 Android device that has Google Play Store installed, and it must
+have at least one logged in Google account if the device is running a version
+lower than Android 4.0.4. Alternatively, for testing you can use an emulator
+running Android 2.2 with Google APIs.</td>
   </tr>
   <tr>
     <td><strong>3rd-party Application Server</strong></td>
-    <td>An application server that  developers  set up as part of implementing
-GCM in their applications. The 3rd-party application server sends data to an
-Android application on the device via the GCM server.</td>
+    <td>An application server that you write as part of implementing
+GCM. The 3rd-party application server sends data to an
+Android application on the device via the GCM connection server.</td>
   </tr>
   <tr>
-    <td><strong>GCM Servers</strong></td>
-    <td>The Google servers involved in taking messages from the 3rd-party
+    <td><strong>GCM Connection Servers</strong></td>
+    <td>The Google-provided servers involved in taking messages from the 3rd-party
 application server and sending them to the device. </td>
   </tr>
   <tr>
-    <th colspan="2"><strong>Credentials</strong></th>
+    <th colspan="2">Credentials</th>
   </tr>
   <tr>
-    <td><strong>Sender ID</strong></td>
-    <td>A project number you acquire from the API console, as described in <a href="gs.html#create-proj">Getting Started</a>. The sender
-ID is used in the <a href="#registering">registration process</a> to identify an
-Android application that is permitted to send messages to the device.</td>
+    <td id="senderid"><strong>Sender ID</strong></td>
+    <td>A project number you acquire from the API console, as described in
+<a href="gs.html#create-proj">Getting Started</a>. The sender
+ID is used in the <a href="#register">registration process</a> to identify a
+3rd-party application server that is permitted to send messages to the device.</td>
   </tr>
   <tr>
     <td><strong>Application ID</strong></td>
     <td>The Android application that is registering to receive messages. The Android application
-is identified by the package name from the <a href="#manifest">manifest</a>.
+is identified by the package name from the <a href="client.html#manifest">manifest</a>.
 This  ensures that the messages are targeted to the correct Android application.</td>
   </tr>
   <tr>
@@ -158,34 +136,56 @@
   </tr>
   <tr>
     <td><strong>Google User Account</strong></td>
-    <td>For GCM to work, the mobile device must include at least one Google account if the device is running a version lower than Android 4.0.4.</td>
+    <td>For GCM to work, the mobile device must include at least one Google
+account if the device is running a version lower than Android 4.0.4.</td>
   </tr>
   <tr>
-    <td><strong>Sender Auth Token</strong></td>
+    <td id="apikey"><strong>Sender Auth Token</strong></td>
     <td>An API key that is saved on the 3rd-party application
 server that gives the application server authorized access to Google services.
 The API key is included in the header of POST requests  that send messages.</td>
   </tr>
 
-  <tr>
-    <td><strong>Notification Key</strong></td>
-    <td>Part of the user notifications feature, which provides a mapping between a user and instances of an app running on multiple devices owned by the user. The {@code notification_key} is the token that GCM uses to fan out notifications to all devices whose registration IDs are associated with the key. For more discussion of this topic, see <a href="notifications.html">User Notifications</a>.</td>
-  </tr>
-
-<tr>
-    <td><strong>Notification Key Name</strong></td>
-    <td>Part of the user notifications feature. The {@code notification_key_name} is a name or identifier (can be a username for a 3rd-party app) that is unique to a given user. It is used by third parties to group together registration IDs for a single user. For more discussion of this topic, see <a href="notifications.html">User Notifications</a>.</td>
-  </tr>
-
 </table>
 
-<h3 id="lifecycle">Lifecycle Flow</h3>
+<h2 id="arch">Architectural Overview</h2>
+
+<p>A GCM implementation includes a Google-provided
+connection server, a 3rd-party app server that interacts with the connection
+server, and a GCM-enabled client app running on an Android device:</p>
+
+<img src="{@docRoot}images/gcm/GCM-arch.png">
+
+<p class="img-caption">
+  <strong>Figure 1.</strong> GCM Architecture.
+</p>
+
+<p>This is how these components interact:</p>
+<ul>
+  <li>Google-provided <strong>GCM Connection Servers</strong> take messages from
+a 3rd-party application server and send these messages to a
+GCM-enabled Android application (the &quot;client app&quot;) running on a device.
+Currently Google provides connection servers for <a href="http.html">HTTP</a>
+and <a href="ccs.html">XMPP</a>.</li>
+  <li>The <strong>3rd-Party Application Server</strong> is a component that you
+implement to work with your chosen GCM connection server(s). App servers send
+messages to a GCM connection server; the connection server enqueues and stores the
+message, and then sends it to the device when the device is online.
+For more information, see <a href="server.html">Implementing GCM Server</a>.</li>
+  <li>The <strong>Client App</strong> is a GCM-enabled Android application running
+on a device. To receive GCM messages, this app must register with GCM and get a
+registration ID. If you are using the <a href="ccs.html">XMPP</a> (CCS) connection
+server, the client app can send "upstream" messages back to the connection server.
+For more information on how to implement the client app, see
+<a href="client.html">Implementing GCM Client</a>.</li>
+</ul>
+
+<h2 id="lifecycle">Lifecycle Flow</h2>
 
 <ul>
   <li><a href="#register">Enable GCM</a>. An Android application running on a
 mobile device registers to receive messages.</li>
- <li><a href="notifications.html">User Notifications</a>. A 3rd-party server can optionally group multiple registration IDs
-in a {@code notification_key} to send messages to multiple devices owned by a single user.</li>
+
   <li><a href="#push-process">Send a message</a>. A 3rd-party application
 server sends messages to the device.</li>
   <li><a href="#receiving">Receive a message</a>. An Android application
@@ -194,62 +194,18 @@
 
 <p>These processes are described in more detail below.</p>
 
-<h4 id="register">Enable GCM</h4>
+<h3 id="register">Enable GCM</h3>
 
-<p>This is the sequence of events that occurs when an Android application
-running on a mobile device registers to receive messages:<span
-class="red-text"></span></p>
-
-<ol>
-  <li>The first time the Android application needs to use the messaging service, it
-fires off a registration Intent to a GCM server.
-    <p>This registration Intent
-(<code>com.google.android.c2dm.intent.REGISTER</code>) includes the sender ID, and the Android application ID.</p>
-<p class="note"><strong>Note:</strong> Because there is no lifecycle method that is called when the application is run for
-the first time, the registration intent should be sent on <code>onCreate()</code>, but only if the application is not registered yet.
+<p>The first time the Android application needs to use the messaging service, it
+calls the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a> method {@code register()}, as discussed in
+<a href="client.html">Implementing GCM Client</a>.
+The {@code register()} method returns a registration ID. The Android
+application should store this ID for later use (for instance,
+to check in <code>onCreate()</code> if it is already registered).
 </p>
-  </li>
-  <li>If the registration is successful, the GCM server broadcasts a <code>com.google.android.c2dm.intent.REGISTRATION</code> intent which gives the Android application  a registration
-ID. 
-    <p>The Android application should store this ID for later use (for instance, to check on <code>onCreate()</code> if it is already registered).
-Note that Google may periodically refresh the registration ID, so you should design your Android application
-with the understanding that the <code>com.google.android.c2dm.intent.REGISTRATION</code> intent may be called
-multiple times. Your Android application needs to be able to respond
-accordingly.</p></li>
-  <li>To complete the registration, the Android application sends the registration ID to
-the application server. The application server typically stores the registration
-ID in a database. </li>
-</ol>
 
-<p>The registration ID lasts until the Android application explicitly unregisters
-itself, or until Google refreshes the registration ID for your Android application.</p>
-
-<p class="note"><strong>Note:</strong> When users uninstall an application, it is not automatically unregistered on GCM. It is only  unregistered when the GCM server tries to send a message to the device and the device answers that the application is uninstalled or it does not have a broadcast receiver configured to receive <code>com.google.android.c2dm.intent.RECEIVE</code> intents. At that point, your server should mark the device as unregistered (the server will receive a <code><a href="#unreg_device">NotRegistered</a></code> error).</p>
-  <p>
-Note that it might take a few minutes for the registration ID to be completely removed from the GCM server. So if the 3rd-party server sends a message during this time, it will get a valid message ID, even though the message will not be delivered to the device.</p>
-
-
-
-
-<h4 id="push-process">Send a Message</h4>
-
-<p>For an application server to send a  message to an Android application, the following things must be in
-place:</p>
-
-<ul>
-  <li>The Android application has stored a target that it can specify as the recipient of a message. This can be one of the following:
-  <ul>
-    <li>A single registration ID (or an array of registration IDs) that allows the app to receive messages
-for a particular device.</li>
-    <li>A {@code notification_key} and corresponding {@code notification_key_name}, used to map a single user to multiple registration IDs. For more discussion of this topic, see <a href="notifications.html">User Notifications</a>.</li>
-  </ul>
-    </li>
-
-<li>An API key. This is something that the developer must have already
-set up on the application server for the Android application (for more discussion, see
-<a href="#server">Role of the 3rd-party Application Server</a>). Now it will
-get used to send messages to the device. </li>
-</ul>
+<h3 id="push-process">Send a message</h3>
 
 <p>Here is the sequence of events that occurs when the application server sends a 
 message:</p>
@@ -264,13 +220,14 @@
 targeted Android application gets the message. This wakes the Android application up. The
 Android application does not need to be running beforehand to receive the message.</li>
   <li>The Android application processes the message. If the Android application is doing
-non-trivial processing, you may want to grab a {@link android.os.PowerManager.WakeLock} and do any processing in a Service.</li>
+non-trivial processing, you may want to grab a
+{@link android.os.PowerManager.WakeLock} and do any processing in a service.</li>
 </ol>
 
 <p> An Android application can  unregister GCM if it no longer wants to receive 
 messages.</p>
 
-<h4 id="receiving">Receive a Message</h4>
+<h3 id="receiving">Receive a message</h3>
 
 <p>This is the sequence of events that occurs when an Android application
 installed on a mobile device receives a message:</p>
@@ -282,482 +239,8 @@
 in a <code>com.google.android.c2dm.intent.RECEIVE</code> Intent as a set of
 extras.</li>
   <li>The Android application extracts the raw data
-from the <code>com.google.android.c2dm.intent.RECEIVE</code><code> </code>Intent by key and processes the data.</li>
+from the <code>com.google.android.c2dm.intent.RECEIVE</code><code> </code>Intent
+by key and processes the data.</li>
 </ol>
 
-<h3 id="user">What Does the User See?</h3>
-
-<p>When mobile device users install Android applications that include GCM, the Google Play Store will inform them that the Android application
-includes GCM. They must approve the use of this feature to install the
-Android application. </p>
-
-
-<h2 id="server">Role of the 3rd-party Application Server</h2>
-
-<p>Before you can write client Android applications that use the GCM feature, you must
-have an  application server that meets the following criteria:</p>
-
-<ul>
-  <li>Able to communicate with your client.</li>
-  <li>Able to  fire off HTTPS requests to the GCM server.</li>
-  <li>Able to handle requests and resend them as needed, using <a href="http://en.wikipedia.org/wiki/Exponential_backoff">exponential back-off.</a></li>
-  <li>Able to store the API key and client registration IDs. The
-API key is included in the header of POST requests that send
-messages.</li>
-</ul>
-
-<h3 id="send-msg">Sending Messages</h3>
-<p>This section describes how the 3rd-party application server sends messages to one or more mobile devices. Note the following:</p>
-<ul>
-  <li>A 3rd-party application server can either send messages to a single device or to multiple devices. A message sent to multiple devices simultaneously is called a <em>multicast message</em>.</li>
-  <li>To send a single message to multiple devices owned by a single user, you can use a {@code notification_key}, as described in <a href="notifications.html">User Notifications</a>.
-  
-  <li>You have 2 choices in how you construct requests and responses: plain text or JSON.</li>
-  <li>However, to send multicast messages, you must use JSON. Plain text will not work.</li>
-</ul>
-<p>Before the 3rd-party application server can send a  message to an
-  Android application, it must have received a registration ID from it.</p>
-<h4 id="request">Request format</h4>
-<p>To send a  message, the application server issues a POST request to <code>https://android.googleapis.com/gcm/send</code>.</p>
-<p>A  message request is made of 2 parts: HTTP header and HTTP body.</p>
-
-<p>The HTTP header must contain the following headers:</p>
-<ul>
-  <li><code>Authorization</code>: key=YOUR_API_KEY</li>
-  <li><code>Content-Type</code>: <code>application/json</code> for JSON; <code>application/x-www-form-urlencoded;charset=UTF-8</code> for plain text.
-  </li>
-</ul>
-
-<p>For example:
-</p>
-<pre>Content-Type:application/json
-Authorization:key=AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA
-
-{
-  "registration_ids" : ["APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx..."],
-  "data" : {
-    ...
-  },
-}</pre>
-<p class="note">
-  <p><strong>Note:</strong> If <code>Content-Type</code> is omitted, the format is assumed to be plain text.</p>
-</p>
-
-<p>The HTTP body content depends on whether you're using JSON or plain text. For JSON, it must contain a string representing a JSON object with the following fields:</p>
-<table>
-  <tr>
-    <th>Field</th>
-    <th>Description</th>
-  </tr>
-  <tr>
-    <td><code>registration_ids</code></td>
-    <td>A string array with the list of devices (registration IDs) receiving the message. It must contain at least 1 and at most 1000 registration IDs. To send a multicast message, you must use JSON. For sending a single message to a single device, you could use a JSON object with just 1 registration id, or plain text (see below). A request must include a recipient&mdash;this can be either a registration ID, an array of registration IDs, or a {@code notification_key}.</td>
-  </tr>
- <tr>
-    <td><code>notification_key</code></td>
-    <td>A string that maps a single user to multiple registration IDs associated with that user. This
-allows a 3rd-party server to send a single message to multiple app instances (typically on multiple devices) owned by a single user. A 3rd-party server can use {@code notification_key} as the target for a message instead of an individual registration ID (or array of registration IDs). The maximum number of members allowed for a {@code notification_key} is 10. For more discussion of this topic, see <a href="notifications.html">User Notifications</a>. Optional.</td>
-  </tr>
-
-<tr>
-    <td><code>notification_key_name</code></td>
-    <td>A name or identifier (can be a username for a 3rd-party app) that is unique to a given user. It is used by 3rd parties to group together registration IDs for a single user. The <code>notification_key_name</code> should be uniquely named per app in case you have multiple apps for the same project ID. This ensures that notifications only go to the intended target app. For more discussion of this topic, see <a href="notifications.html">User Notifications</a>.</td>
-  </tr>
-
-  <tr>
-    <td><code>collapse_key</code></td>
-    <td>An arbitrary string (such as &quot;Updates Available&quot;) that is used to collapse a group of like messages
-when the device is offline, so that only the last message gets sent to the
-client. This is intended to avoid sending too many messages to the phone when it
-comes back online. Note that since there is no guarantee of the order in which
-messages get sent, the &quot;last&quot; message may not actually be the last
-message sent by the application server. See <a href="adv.html#collapsible">Advanced Topics</a> for more discussion of this topic. Optional.</td>
-  </tr>
-  <tr>
-    <td><code>data</code></td>
-    <td>A JSON object whose fields represents the key-value pairs of the message's payload data. If present, the payload data it will be
-included in the Intent as application data, with the key being the extra's name. For instance, <code>"data":{"score":"3x1"}</code> would result in an intent extra named <code>score</code> whose value is the string <code>3x1</code>. 
-
-There is no limit on the number of key/value pairs, though there is a limit on the total size of the message (4kb). The values could be any JSON object, but we recommend using strings, since the values will be converted to strings in the GCM server anyway. If you want to include objects or other non-string data types (such as integers or booleans), you have to do the conversion to string yourself. Also note that the key cannot be a reserved word (<code>from</code> or any word starting with <code>google.</code>). To complicate things slightly, there are some reserved words (such as <code>collapse_key</code>) that are technically allowed in payload data. However, if the request also contains the word, the value in the request will overwrite the value in the payload data. Hence using words that are defined as field names in this table is not recommended, even in cases where they are technically allowed. Optional.</td>
-
-
-  </tr>
-  <tr>
-    <td><code>delay_while_idle</code></td>
-    <td>If included, indicates that the message should not be sent immediately
-if the device is idle. The server will wait for the device to become active, and
-then only the last message for each <code>collapse_key</code> value will be
-sent. Optional. The default value is <code>false</code>, and must be a JSON boolean.</td>
-  </tr>
-  <tr>
-    <td><code>time_to_live</code></td>
-    <td>How long (in seconds) the message should be kept on GCM storage if the device is offline. Optional (default time-to-live is 4 weeks, and must be set as a JSON number).</td>
-  </tr>
-<tr>
-  <td><code>restricted_package_name</code></td>
-  <td>A string containing the package name of your application. When set, messages will only be sent to registration IDs that match the package name. Optional.
-  </td>
-</tr>
-<tr>
-  <td><code>dry_run</code></td>
-  <td>If included, allows developers to test their request without actually sending a message. Optional. The default value is <code>false</code>, and must be a JSON boolean.
-  </td>
-</tr>
-</table>
-
-<p>If you are using plain text instead of JSON, the message fields must be set as HTTP parameters sent in the body, and their syntax is slightly different, as described below:
-<table>
-  <tr>
-    <th>Field</th>
-    <th>Description</th>
-  </tr>
-  <tr>
-    <td><code>registration_id</code></td>
-    <td>Must contain the registration ID of the single device receiving the message. Required.</td>
-  </tr>
-  <tr>
-    <td><code>collapse_key</code></td>
-    <td>Same as JSON (see previous table). Optional.</td>
-  </tr>
-  <tr>
-    <td><code>data.&lt;key&gt;</code></td>
-
-    <td>Payload data, expressed as parameters prefixed with <code>data.</code> and suffixed as the key. For instance, a parameter of <code>data.score=3x1</code> would result in an intent extra named <code>score</code> whose value is the string <code>3x1</code>. There is no limit on the number of key/value parameters, though there is a limit on the total size of the  message. Also note that the key cannot be a reserved word (<code>from</code> or any word starting with 
-<code>google.</code>). To complicate things slightly, there are some reserved words (such as <code>collapse_key</code>) that are technically allowed in payload data. However, if the request also contains the word, the value in the request will overwrite the value in the payload data. Hence using words that are defined as field names in this table is not recommended, even in cases where they are technically allowed. Optional.</td>
-
-  </tr>
-  <tr>
-    <td><code>delay_while_idle</code></td>
-    <td>Should be represented as <code>1</code> or <code>true</code> for <code>true</code>, anything else for <code>false</code>. Optional. The default value is <code>false</code>.</td>
-  </tr>
-  <tr>
-    <td><code>time_to_live</code></td>
-    <td>Same as JSON (see previous table). Optional.</td>
-  </tr>
-<tr>
-  <td><code>restricted_package_name</code></td>
-  <td>Same as JSON (see previous table). Optional.
-  </td>
-</tr>
-<tr>
-  <td><code>dry_run</code></td>
-  <td>Same as JSON (see previous table). Optional.
-  </td>
-</tr>
-</table>
-
-<p>If you want to test your request (either JSON or plain text) without delivering the message to the devices, you can set an optional HTTP or JSON parameter called <code>dry_run</code> with the value <code>true</code>. The result will be almost identical to running the request without this parameter, except that the message will not be delivered to the devices. Consequently, the response will contain fake IDs for the message and multicast fields (see <a href="#response">Response format</a>).</p>
-
-  <h4 id="example-requests">Example requests</h4>
-  <p>Here is the smallest possible request (a message without any parameters and just one recipient) using JSON:</p>
-  <pre class="prettyprint pretty-json">{ &quot;registration_ids&quot;: [ &quot;42&quot; ] }</pre>
-  
-  <p>And here the same example using plain text:</p>
-  <pre class="prettyprint">registration_id=42</pre>
-  
-  <p> Here is a message with a payload and 6 recipients:</p>
-  <pre class="prettyprint pretty-HTML">{ "data": {
-    "score": "5x1",
-    "time": "15:10"
-  },
-  "registration_ids": ["4", "8", "15", "16", "23", "42"]
-}</pre>
-  <p>Here is a message with all optional fields set and 6 recipients:</p>
-  <pre class="prettyprint pretty-json">{ "collapse_key": "score_update",
-  "time_to_live": 108,
-  "delay_while_idle": true,
-  "data": {
-    "score": "4x8",
-    "time": "15:16.2342"
-  },
-  "registration_ids":["4", "8", "15", "16", "23", "42"]
-}</pre>
-  <p>And here is the same message using plain-text format (but just 1 recipient):  </p>
-  
-  <pre class="prettyprint">collapse_key=score_update&amp;time_to_live=108&amp;delay_while_idle=1&amp;data.score=4x8&amp;data.time=15:16.2342&amp;registration_id=42
-  </pre>
-
-<p class="note"><strong>Note:</strong> If your organization has a firewall 
-that restricts the traffic to or 
-from the Internet, you need to configure it to allow connectivity with GCM in order for
-your Android devices to receive messages. 
-The ports to open are: 5228, 5229, and 5230. GCM typically only uses 5228, but
-it sometimes uses 5229 and 5230. GCM doesn't provide specific IPs, so you should allow
-your firewall to accept outgoing connections to all IP addresses
-contained in the IP blocks listed in Google's ASN of 15169.</p>
-
-
-<h4 id="response">Response format</h4>
-
-<p>There are two possible outcomes when trying to send a message:</p>
-<ul>
-  <li>The message is processed successfully.</li>
-  <li>The GCM server rejects the request.</li>
-</ul>
-
-<p>When the message is processed successfully, the HTTP response has a 200 status and the body contains more information about the status of the message (including possible errors). When the request is rejected, 
-the HTTP response contains a non-200 status code (such as 400, 401, or 503).</p>
-
-<p>The following table summarizes the statuses that the HTTP response header might contain. Click the troubleshoot link for advice on how to deal with each type of error.</p>
-<table border=1>
-  <tr>
-    <th>Response</th>
-    <th>Description</th>
-  </tr>
-  <tr>
-    <td>200</td>
-    <td>Message was processed successfully. The response body will contain more details about the message status, but its format will depend whether the request was JSON or plain text. See <a href="#success">Interpreting a success response</a> for more details.</td>
-  </tr>
-  <tr>
-    <td>400</td>
-    <td><span id="internal-source-marker_0.2">Only applies for JSON requests. Indicates that the request could not be parsed as JSON, or it contained invalid fields (for instance, passing a string where a number was expected). The exact failure reason is described in the response and the problem should be addressed before the request can be retried.</td>
-  </tr>
-  <tr>
-    <td>401</td>
-    <td>There was an error authenticating the sender account. <a href="#auth_error">Troubleshoot</a></td>
-  </tr>
-  <tr>
-    <td>5xx</td>
-    <td>Errors in the 500-599 range (such as 500 or 503) indicate that there was an internal error in the GCM server while trying to process the request, or that the server is temporarily unavailable (for example, because of timeouts). Sender must retry later, honoring any <code>Retry-After</code> header included in the response. Application servers must implement exponential back-off. <a href="#internal_error">Troubleshoot</a></td>
-  </tr>
-</table>
-
-<h4 id="success">Interpreting a success response</h4>
-<p>When a JSON request is successful (HTTP status code 200), the response body contains a JSON object with the following fields:</p>
-<table>
-  <tr>
-    <th>Field</th>
-    <th>Description</th>
-  </tr>
-  <tr>
-    <td><code>multicast_id</code></td>
-    <td>Unique ID (number) identifying the multicast message.</td>
-  </tr>
-  <tr>
-    <td><code>success</code></td>
-    <td>Number of messages that were processed without an error.</td>
-  </tr>
-  <tr>
-    <td><code>failure</code></td>
-    <td>Number of messages that could not be processed.</td>
-  </tr>
-  <tr>
-    <td><code>canonical_ids</code></td>
-    <td>Number of results that contain a canonical registration ID. See <a href="adv.html#canonical">Advanced Topics</a> for more discussion of this topic.</td>
-  </tr>
-  <tr>
-    <td><code>results</code></td>
-    <td>Array of objects representing the status of the messages processed. The objects are listed in the same order as the request (i.e., for each registration ID in the request, its result is listed in the same index in the response) and they can have these fields:<br>
-      <ul>
-        <li><code>message_id</code>: String representing the message when it was successfully processed.</li>
-        <li><code>registration_id</code>: If set,  means that GCM processed the message but it has another canonical registration ID for that device, so sender should replace the IDs on future requests (otherwise they might be rejected). This field is never set if there is an error in the request.
-        </li>
-        <li><code>error</code>: String describing an error that occurred while processing the message for that recipient. The possible values are the same as documented in the above table, plus &quot;Unavailable&quot;  (meaning GCM servers were busy and could not process the message for that  particular recipient, so it could be retried).</li>
-    </ul></td>
-  </tr>
-</table>
-<p>If the value of <code>failure</code> and <code>canonical_ids</code> is 0, it's not necessary to parse the remainder of the response. Otherwise, we recommend that you iterate through the results field and do the following for each object in that list:</p>
-<ul>
-  <li>If <code>message_id</code> is set, check for <code>registration_id</code>:
-    <ul>
-      <li>If <code>registration_id</code> is set, replace the original ID with the new value (canonical ID) in your server database. Note that the original ID is not part of the result, so you need to obtain it from the list of <code>registration_ids</code> passed in the request (using the same index).</li>
-    </ul>
-  </li>
-  <li>Otherwise, get the value of <code>error</code>:
-    <ul>
-      <li>If it is <code>Unavailable</code>, you could retry to send it in another request.</li>
-      <li>If it is <code>NotRegistered</code>, you should remove the registration ID from your server database because the application was uninstalled from the device or it does not have a broadcast receiver configured to receive <code>com.google.android.c2dm.intent.RECEIVE</code> intents.</li>
-      <li>Otherwise, there is something wrong in the registration ID passed in the request; it is probably a non-recoverable error that will also require removing the registration from the server database. See <a href="#error_codes">Interpreting an error response</a> for all possible error values.</li>
-    </ul>
-  </li>
-</ul>
-
-<p>When a plain-text request is successful (HTTP status code 200), the response body contains 1 or 2 lines in the form of key/value pairs.
-The first line is always available and its content is either <code>id=<em>ID of sent message</em></code> or <code>Error=<em>GCM error code</em></code>. The second line, if available, 
-has the format of <code>registration_id=<em>canonical ID</em></code>. The second line is optional, and it can only be sent if the first line is not an error. We recommend handling the plain-text response in a similar way as handling the JSON response:</p>
-<ul>
-  <li>If first line starts with <code>id</code>, check second line:
-    <ul>
-      <li>If second line starts with <code>registration_id</code>, gets its value and replace the registration IDs in your server database.</li>
-    </ul>
-  </li>
-  <li>Otherwise, get the value of <code>Error</code>:
-    <ul>
-      <li>If it is <code>NotRegistered</code>, remove the registration ID from your server database.</li>
-      <li>Otherwise, there is probably a non-recoverable error (<strong>Note: </strong>Plain-text requests will never return <code>Unavailable</code> as the error code, they would have returned a 500 HTTP status instead).</li>
-    </ul>
-  </li>
-</ul>
-
-<h4 id="error_codes">Interpreting an error response</h4>
-<p>Here are the recommendations for handling the different types of error that might occur when trying to send a message to a device:</p>
-
-<dl>
-<dt id="missing_reg"><strong>Missing Registration ID</strong></dt>
-<dd>Check that the request contains a registration ID (either in the <code>registration_id</code> parameter in a plain text message, or in the <code>registration_ids</code> field in JSON). 
-<br/>Happens when error code is <code>MissingRegistration</code>.</dd>
-
-<dt id="invalid_reg"><strong>Invalid Registration ID</strong></dt>
-<dd>Check the formatting of the registration ID that you pass to the server. Make sure it matches the registration ID the phone receives in the <code>com.google.android.c2dm.intent.REGISTRATION</code> intent and that you're not truncating it or adding additional characters. 
-<br/>Happens when error code is <code>InvalidRegistration</code>.</dd>
-
-<dt id="mismatched_sender"><strong>Mismatched Sender</strong></dt>
-<dd>A registration ID is tied to a certain group of senders. When an application registers for GCM usage, it must specify which senders are allowed to send messages. Make sure you're using one of those when trying to send messages to the device. If you switch to a different sender, the existing registration IDs won't work. 
-Happens when error code is <code>MismatchSenderId</code>.</dd>
-
-<dt id="unreg_device"><strong>Unregistered Device</strong></dt>
-<dd>An existing registration ID may cease to be valid in a number of scenarios, including:
-<ul>
-  <li>If the application manually unregisters by issuing a <span class="prettyprint pretty-java"><code>com.google.android.c2dm.intent.UNREGISTER</code></span><code> </code>intent.</li>
-  <li>If the application is automatically unregistered, which can happen (but is not guaranteed) if the user uninstalls the application.</li>
-  <li>If the registration ID expires. Google might decide to refresh registration IDs. </li>
-  <li>If the application is updated but the new version does not have a broadcast receiver configured to receive <code>com.google.android.c2dm.intent.RECEIVE</code> intents.</li>
-</ul>
-For all these cases, you should remove this registration ID from the 3rd-party server and stop using it to send 
-messages. 
-<br/>Happens when error code is <code>NotRegistered</code>.</dd>
-
-<dt id="big_msg"><strong>Message Too Big</strong></dt>
-  <dd>The total size of the payload data that is included in a message can't exceed 4096 bytes. Note that this includes both the size of the keys as well as the values. 
-<br/>Happens when error code is <code>MessageTooBig</code>.</dd>
-
-<dt id="invalid_datakey"><strong>Invalid Data Key</strong></dt>
-<dd>The payload data contains a key (such as <code>from</code> or any value prefixed by <code>google.</code>) that is used internally by GCM in the  <code>com.google.android.c2dm.intent.RECEIVE</code> Intent and cannot be used. Note that some words (such as <code>collapse_key</code>) are also used by GCM but are allowed in the payload, in which case the payload value will be overridden by the GCM value. 
-<br />
-Happens when the error code is <code>InvalidDataKey</code>.</dd>
-
-<dt id="ttl_error"><strong>Invalid Time To Live</strong></dt>
-  <dd>The value for the Time to Live field must be an integer representing a duration in seconds between 0 and 2,419,200 (4 weeks). Happens when error code is <code>InvalidTtl</code>.
-</dd>
-
-  <dt id="auth_error"><strong>Authentication Error</strong></dt>
-  <dd>The sender account that you're trying to use to send a message couldn't be authenticated. Possible causes are: <ul>
-<li>Authorization header missing or with invalid syntax.</li>
-<li>Invalid project number sent as key.</li>
-<li>Key valid but with GCM service disabled.</li>
-<li>Request originated from a server not whitelisted in the Server Key IPs.</li>
-
-</ul>
-Check that the token you're sending inside the <code>Authorization</code> header is the correct API key associated with your project. You can check the validity of your API key by running the following command:<br/>
-
-<pre># api_key=YOUR_API_KEY
-
-# curl --header "Authorization: key=$api_key" --header Content-Type:"application/json" https://android.googleapis.com/gcm/send  -d "{\"registration_ids\":[\"ABC\"]}"</pre>
-
-
-
-If you receive a 401 HTTP status code, your API key is not valid. Otherwise you should see something like this:<br/>
-
-<pre>
-{"multicast_id":6782339717028231855,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
-</pre>
-If you want to confirm the validity of a registration ID, you can do so by replacing "ABC" with the registration ID.
-<br/>
-Happens when the HTTP status code is 401.
-
-  <dt id="timeout"><strong>Timeout</strong></dt>
-
-<dd>The server couldn't process the request in time. You should retry the
-same request, but you MUST obey the following requirements:
-
-<ul>
-
-<li>Honor the <code>Retry-After</code> header if it's included in the response from the GCM server.</li>
-        
-        
-<li>Implement exponential back-off in your retry mechanism. This means an
-exponentially increasing delay after each failed retry (e.g. if you waited one
-second before the first retry, wait at least two second before the next one,
-then 4 seconds and so on). If you're sending multiple messages, delay each one
-independently by an additional random amount to avoid issuing a new request for
-all messages at the same time.</li>
-    
-
-Senders that cause problems risk being blacklisted. 
-<br />
-Happens when the HTTP status code is between 501 and 599, or when the <code>error</code> field of a JSON object in the results array is <code>Unavailable</code>.
-</dd>
-
-<dt id="internal_error"><strong>Internal Server Error</strong></dt>
-
-<dd>
-The server encountered an error while trying to process the request. You
-could retry the same request (obeying the requirements listed in the <a href="#timeout">Timeout</a>
-section), but if the error persists, please report the problem in the <a href="https://groups.google.com/forum/?fromgroups#!forum/android-gcm">android-gcm group</a>.
-<br />
-Happens when the HTTP status code is 500, or when the <code>error</code> field of a JSON
-object in the results array is <code>InternalServerError</code>.
-</dd>
-
-<dt id="restricted_package_name"><strong>Invalid Package Name</strong></dt>
-
-<dd>
-A message was addressed to a registration ID whose package name did not match the value passed in the request. Happens when error code is 
-<code>InvalidPackageName</code>.
-</dd>
-
-
-</dl>
-<h4>Example responses</h4>
-<p>This section shows a few examples of responses indicating messages that were processed successfully. See <a href="#example-requests">Example requests</a> for the requests these responses are based on.</p>
-<p> Here is a simple case of a JSON message successfully sent to one recipient without canonical IDs in the response:</p>
-<pre class="prettyprint pretty-json">{ "multicast_id": 108,
-  "success": 1,
-  "failure": 0,
-  "canonical_ids": 0,
-  "results": [
-    { "message_id": "1:08" }
-  ]
-}</pre>
-
-<p>Or if the request was in plain-text format:</p>
-<pre class="prettyprint">id=1:08
-</pre>
-
-<p>Here are JSON results for 6 recipients (IDs 4, 8, 15, 16, 23, and 42 respectively) with 3 messages successfully processed, 1 canonical registration ID returned, and 3 errors:</p>
-<pre class="prettyprint pretty-json">{ "multicast_id": 216,
-  "success": 3,
-  "failure": 3,
-  "canonical_ids": 1,
-  "results": [
-    { "message_id": "1:0408" },
-    { "error": "Unavailable" },
-    { "error": "InvalidRegistration" },
-    { "message_id": "1:1516" },
-    { "message_id": "1:2342", "registration_id": "32" },
-    { "error": "NotRegistered"}
-  ]
-}
-</pre>
-<p> In this example:</p>
-<ul>
-  <li>First message: success, not required.</li>
-  <li>Second message: should be resent (to registration ID 8).</li>
-  <li>Third message: had an unrecoverable error (maybe the value got corrupted in the database).</li>
-  <li>Fourth message: success, nothing required.</li>
-  <li>Fifth message: success, but the registration ID should be updated in the server database (from 23 to 32).</li>
-  <li>Sixth message: registration ID (42) should be removed from the server database because the application was uninstalled from the device.</li>
-</ul>
-<p>Or if just the 4th message above was sent using plain-text format:</p>
-<pre class="prettyprint">Error=InvalidRegistration
-</pre>
-<p>If the 5th message above was also sent using plain-text format:</p>
-<pre class="prettyprint">id=1:2342
-registration_id=32
-</pre>
-
-<h3 id="stats">Viewing Statistics</h3>
-
-<p>To view  statistics and any error messages for your GCM applications:</p>
-<ol>
-  <li> Go to the <code><a href="http://play.google.com/apps/publish">Developer Console</a></code>.</li>
-  <li>Login with your developer account. 
-  <p>You will see a page that has a list of all of your apps.</p></li>
-  <li> Click on the &quot;statistics&quot; link next to the app for which you want to view GCM stats. 
-  <p>Now you are on the statistics page.</p> </li>
-  <li>Go to the drop-down menu and select the GCM metric you want to view. 
-  </li>
-</ol>
-<p class="note"><strong>Note:</strong> Stats on the Google API Console are not enabled for GCM. You must use the <a href="http://play.google.com/apps/publish">Developer Console</a>.</p>
-
 
diff --git a/docs/html/google/gcm/gs.jd b/docs/html/google/gcm/gs.jd
index 8ceea0cc..3f02907 100644
--- a/docs/html/google/gcm/gs.jd
+++ b/docs/html/google/gcm/gs.jd
@@ -1,5 +1,5 @@
-page.title=Getting Started with GCM
-page.tags="cloud","push","messaging"
+page.title=Getting Started
+page.tags=cloud,push,messaging
 @jd:body
 
 <div id="qv-wrapper">
@@ -12,512 +12,92 @@
 <li><a href="#create-proj">Creating a Google API Project</a></li>
 <li><a href="#gcm-service">Enabling the GCM Service</a></li>
 <li><a href="#access-key">Obtaining an API Key</a></li>
-<li><a href="#client">Writing a Client App</a></li>
-<li><a href="#server">Writing the Server Code</a></li>
+<li><a href="#next">Next Steps</a></li>
 </ol>
 
 <h2>See Also</h2>
 
 <ol class="toc">
-<li><a href="https://code.google.com/apis/console">Google APIs Console page</a></li>
+<li><a href="https://cloud.google.com/console">Google Cloud Console</a></li>
+<li><a href="https://developers.google.com/console/help/new/">Google Cloud Console Help</a></li>
 <li><a href="https://services.google.com/fb/forms/gcm/" class="external-link" target="_android">CCS and User Notifications Signup Form</a></li>
 </ol>
 
 </div>
 </div>
 
-<p>The sections below guide you through the process of setting up a GCM
+<p>This document tells you how to get started setting up a GCM
 implementation.
-Before you start, make sure to <a href="/google/play-services/setup.html">set up
-the Google Play Services SDK</a>. You need this SDK to use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> methods.</p>
-
-<p>Note that a full GCM implementation requires a server-side implementation, in addition to the client implementation in your app. This document offers a complete example that includes both the client and server.</p>
-
+Before you begin, make sure to <a href="/google/play-services/setup.html">set up
+the Google Play Services SDK</a>. You need this SDK to use the
+<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a> methods.</p>
 
 <h2 id="create-proj">Creating a Google API project</h2>
 <p>To create a Google API project:</p>
 <ol>
-  <li>Open the <a href="https://code.google.com/apis/console">Google APIs Console page</a>.
+  <li>Open the <a href="https://cloud.google.com/console">Google Cloud Console</a>.
   </li>
-  <li>If you haven't created an API project yet, this page will prompt you to do so:
-  <p><img src="{@docRoot}images/gcm/gcm-create-api-proj.png" class="screenshot" /></p>
-<p class="note"><strong>Note:</strong> If you already have existing projects, the first page you see will be the <strong>Dashboard</strong> page. From there you can create a new project by opening the project drop-down menu (upper left corner) and choosing <strong>Other projects > Create</strong>.</p></li>
-  <li> Click <strong>Create project</strong>.
-    Your browser URL will change to something like:</li>
+  <li>If you haven't created an API project yet, click <strong>Create Project</strong>.</li>
 
-<pre> https://code.google.com/apis/console/#project:<strong>4815162342</strong></pre>
+ <li>Supply a project name and click <strong>Create</strong>.
 
-  <li> Take note of the value after <code>#project:</code> (4815162342 in this example). This is your project number, and it will be used later on as the GCM sender ID.</li>
+<p>Once the project has been created, a page appears that displays your project ID and
+project number. For example, <strong>Project Number: 670330094152</strong>.</p></li>
+
+  <li>Copy down your project number. You will use it later on as the
+  <a href="{@docRoot}google/gcm/gcm.html#senderid">GCM sender ID</a>.</li>
   
 </ol>
 <h2 id="gcm-service">Enabling the GCM Service</h2>
 <p>To enable the GCM service:</p>
 <ol>
-  <li> In the main Google APIs Console page, select <strong>Services</strong>.</li>
-  <li>Turn the <strong>Google Cloud Messaging</strong> toggle to ON.</li>
-  <li>In the Terms of Service page, accept the terms.
-  </li>
+  <li>In the sidebar on the left, select <strong>APIs &amp; auth</strong>. </li>
+  <li>In the displayed list of APIs, turn the <strong>Google Cloud Messaging for Android
+  </strong> toggle to ON.</li>
+
 </ol>
 <h2 id="access-key">Obtaining an API Key</h2>
 <p>To obtain an API  key:</p>
 <ol>
-  <li> In the main Google APIs Console page, select <strong>API Access</strong>. You will see a screen that resembles the following:</li><br />
+ <li>In the sidebar on the left, select <strong>APIs &amp; auth > Registered apps</strong>.</li>
+<li>Click <strong>Register app</strong>. </li>
 
+<li>In the <strong>Name</strong> field, type your app's name.</li>
+<li>Click <strong>Android > Accessing APIs directly from Android</strong>.</li>
+<li>Under <strong>Android identification</strong>, type the package name for your app.</li>
+<li>Enter an SHA1 fingerprint. To get this value, follow the instructions in the
+<a href="http://developers.google.com/console/help/new/#installedapplications">console
+help</a>.</li>
+<li>Click <strong>Register</strong>.</li>
 
-<img src="{@docRoot}images/gcm/gcm-api-access.png" style="width:400px;padding:4px;margin-bottom:0em;">
+<li>In the new page, open the <strong>Android Key</strong> section and copy the
+<a href="{@docRoot}google/gcm/gcm.html#apikey">API key</a>.
+You will need the API key later on to perform authentication in your application server.</li>
 
-
-  <li>Click  <strong>Create new Server key</strong>. Either a server key or a browser key should work. The advantage to using a server key is that it allows you to whitelist IP addresses. The following screen appears:</li><br />
-
-
-<img src="{@docRoot}images/gcm/gcm-config-server-key.png" style="width:400px;padding:4px;margin-bottom:0em;">
-
-  
-  <li>Click <strong>Create</strong>:</li><br />
-  
-
-<img src="{@docRoot}images/gcm/gcm-api-key.png" style="width:400px;padding:4px;margin-bottom:0em;">
-
-
-
+<p class="note"><strong>Note:</strong> If you need to rotate the key, click
+the "recycle key" icon. A new key  will be created. If you think the key has been compromised
+and you want to delete it immediately, you can accomplish this by deleting the app from
+the console. Then create a new entry for the app with the same SHA1 and package name.</p>
 </ol>
-<p> Take note of the <strong>API key</strong> value (<code>YourKeyWillBeShownHere</code>) in this example, as it will be used later on.</p>
-<p class="note"><strong>Note:</strong> If you need to rotate the key, click  <strong>Generate new key</strong>. A new key  will be created while the old one will still be active for up to 24 hours. If you want to get rid of the old key immediately (for example, if you feel it was compromised), click <strong>Delete key</strong>.</p>
 
-<p>The following sections walk you through the steps of creating client and server-side code.</p>
+<h2 id="next">Next Steps</h2>
 
-<h2 id="client">Writing a Client App</h2>
+<p>Once you've finished the tasks listed above, you're ready to start
+implementing GCM. Here is an overview of the basic steps:</p>
 
-<p>This section walks you through the steps involved in writing a client-side application&mdash;that is, the GCM-enabled application that runs on an Android device. This client sample is designed to work in conjunction with the server code shown in <a href="#server">Writing the Server Code</a>, below.</p>
-
-
-
-<h3 id="manifest">Step 1: Edit Your App's Manifest</h3>
-<ul>
-  <li>The <code>com.google.android.c2dm.permission.RECEIVE</code> permission so the Android application can register and receive messages.</li>
-  <li>The <code>android.permission.INTERNET</code> permission so the Android application can send the registration ID to the 3rd party server.</li>
-  <li>The <code>android.permission.GET_ACCOUNTS</code> permission as GCM requires a Google account (necessary only if if the device is running a version lower than Android 4.0.4)</li>
-  <li>The <code>android.permission.WAKE_LOCK</code> permission so the application can keep the processor from sleeping when a message is received. Optional&mdash;use only if the app wants to keep the device from sleeping.</li>
-  <li>An <code>applicationPackage + &quot;.permission.C2D_MESSAGE&quot;</code> permission to prevent other Android applications from registering and receiving the Android application's
-messages. The permission name must exactly match this pattern&mdash;otherwise the Android application will not receive the messages.</li>
-   <li>A receiver for <code>com.google.android.c2dm.intent.RECEIVE</code>, with the category set
-as <code>applicationPackage</code>. The receiver should require the <code>com.google.android.c2dm.SEND</code> permission, so that only the GCM
-Framework can send a message to it. Note that the receiving
-of messages is implemented as an <a href="{@docRoot}guide/components/intents-filters.html">intent</a>.</li>
-  <li>An intent service to handle the intents received by the broadcast receiver. Optional.</li>
-  <li>If the GCM feature is critical to the Android application's function, be sure to
-set <code>android:minSdkVersion=&quot;8&quot;</code> in the manifest. This
-ensures that the Android application cannot be installed in an environment in which it
-could not run properly. </li>
-</ul>
-
-<p>Here are excerpts from a manifest that supports GCM:</p>
-
-<pre class="prettyprint pretty-xml">
-&lt;manifest package="com.example.gcm" ...&gt;
-
-    &lt;uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/&gt;
-    &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
-    &lt;uses-permission android:name="android.permission.GET_ACCOUNTS" /&gt;
-    &lt;uses-permission android:name="android.permission.WAKE_LOCK" /&gt;
-    &lt;uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /&gt;
-
-    &lt;permission android:name="com.example.gcm.permission.C2D_MESSAGE" 
-        android:protectionLevel="signature" /&gt;
-    &lt;uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" /&gt;
-
-    &lt;application ...&gt;
-        &lt;receiver
-            android:name=".MyBroadcastReceiver"
-            android:permission="com.google.android.c2dm.permission.SEND" &gt;
-            &lt;intent-filter&gt;
-                &lt;action android:name="com.google.android.c2dm.intent.RECEIVE" /&gt;
-                &lt;category android:name="com.example.gcm" /&gt;
-            &lt;/intent-filter&gt;
-        &lt;/receiver&gt;
-        &lt;service android:name=".MyIntentService" /&gt;
-    &lt;/application&gt;
-
-&lt;/manifest&gt;
-</pre>
-
-
-<h3 id="register">Step 2: Register for GCM</h3>
-
-<p>An Android application running on a mobile device registers to receive messages by calling 
-the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> method 
-<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html#register">{@code register(senderID...)}</a>.
-This method registers the application for GCM and returns the registration ID. This streamlined approach replaces the previous
-GCM registration process. See the example below for details.</p>
-
-<h3 id="app"> Step 3: Write Your Application</h3>
-
-<p>Finally, write your application. GCM offers a variety of ways to get the job done:</p>
-
-<ul>
-  <li>For your messaging server, you can either use the new <a href="ccs.html">GCM Cloud Connection Server</a> (CCS), the older <a href="gcm.html">GCM HTTP server</a>, or both in tandem. For more discussion, see see <a href="server.html">GCM Server</a>.</li>
-  <li>To write your client application (that is, the GCM-enabled app that runs on an Android device), use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs as shown below. Don't forget to set up your project to use the Google Play services SDK as described in <a href="/google/play-services/setup.html">Setup Google Play Services SDK</a>.</li>
-</ul>
-</li>
-  
-</ul>
-
-<h4 id="example">Example</h4>
-
-<p>Here is a sample client application that illustrates how to use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs. The sample consists of a main activity ({@code DemoActivity}) and a broadcast receiver ({@code GcmBroadcastReceiver}). You can use this client sample code in conjunction with the server code shown in <a href="#server">Writing the Server Code</a>.</p>
-
-<p>Note the following:</p>
-
-<ul>
-  <li>The sample primarily illustrates two things: registration, and upstream messaging. Upstream messaging only applies to apps that are running against a <a href="ccs.html">CCS</a> server; HTTP-based servers don't support upstream messaging.</li>
-  <li>The <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> registration APIs replace the old registration process, which was based on the now-obsolete client helper library. While the old registration process still works, we encourage you to use the newer <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> registration APIs, regardless of your underlying server.</li>
-</ul>
-
-<h5>Registering</h5>
-<p>An Android application needs to register with GCM servers before it can receive messages. So in its {@code onCreate()} method, {@code DemoActivity} checks to see whether the app is registered with GCM and with the server:</p>
-
-<pre>/**
- * Main UI for the demo app.
- */
-public class DemoActivity extends Activity {
-
-    public static final String EXTRA_MESSAGE = "message";
-    public static final String PROPERTY_REG_ID = "registration_id";
-    private static final String PROPERTY_APP_VERSION = "appVersion";
-    private static final String PROPERTY_ON_SERVER_EXPIRATION_TIME =
-            "onServerExpirationTimeMs";
-    /**
-     * Default lifespan (7 days) of a reservation until it is considered expired.
-     */
-    public static final long REGISTRATION_EXPIRY_TIME_MS = 1000 * 3600 * 24 * 7;
-
-    /**
-     * Substitute you own sender ID here.
-     */
-    String SENDER_ID = "Your-Sender-ID";
-
-    /**
-     * Tag used on log messages.
-     */
-    static final String TAG = "GCMDemo";
-
-    TextView mDisplay;
-    GoogleCloudMessaging gcm;
-    AtomicInteger msgId = new AtomicInteger();
-    SharedPreferences prefs;
-    Context context;
-
-    String regid;
-
-    &#64;Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        setContentView(R.layout.main);
-        mDisplay = (TextView) findViewById(R.id.display);
-
-        context = getApplicationContext();
-        regid = getRegistrationId(context);
-
-        if (regid.length() == 0) {
-            registerBackground();
-        }
-        gcm = GoogleCloudMessaging.getInstance(this);
-    }
-...
-}</pre>
-
-<p>The app calls {@code getRegistrationId()} to see whether there is an existing registration ID stored in shared preferences:</p>
-
-<pre>/**
- * Gets the current registration id for application on GCM service.
- * &lt;p&gt;
- * If result is empty, the registration has failed.
- *
- * &#64;return registration id, or empty string if the registration is not
- *         complete.
- */
-private String getRegistrationId(Context context) {
-    final SharedPreferences prefs = getGCMPreferences(context);
-    String registrationId = prefs.getString(PROPERTY_REG_ID, "");
-    if (registrationId.length() == 0) {
-        Log.v(TAG, "Registration not found.");
-        return "";
-    }
-    // check if app was updated; if so, it must clear registration id to
-    // avoid a race condition if GCM sends a message
-    int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
-    int currentVersion = getAppVersion(context);
-    if (registeredVersion != currentVersion || isRegistrationExpired()) {
-        Log.v(TAG, "App version changed or registration expired.");
-        return "";
-    }
-    return registrationId;
-}
-
-...
-
-/**
- * &#64;return Application's {&#64;code SharedPreferences}.
- */
-private SharedPreferences getGCMPreferences(Context context) {
-    return getSharedPreferences(DemoActivity.class.getSimpleName(), 
-            Context.MODE_PRIVATE);
-}</pre>
-
-<p>If the registration ID doesn't exist, or the app was updated, or the registration ID has expired, {@code getRegistrationId()} returns an empty string to indicate that the app needs to get a new regID. {@code getRegistrationId()} calls the following methods to check the app version and whether the regID has expired:</p>
-
-<pre>/**
- * &#64;return Application's version code from the {&#64;code PackageManager}.
- */
-private static int getAppVersion(Context context) {
-    try {
-        PackageInfo packageInfo = context.getPackageManager()
-                .getPackageInfo(context.getPackageName(), 0);
-        return packageInfo.versionCode;
-    } catch (NameNotFoundException e) {
-        // should never happen
-        throw new RuntimeException("Could not get package name: " + e);
-    }
-}
-
-/**
- * Checks if the registration has expired.
- *
- * &lt;p&gt;To avoid the scenario where the device sends the registration to the
- * server but the server loses it, the app developer may choose to re-register
- * after REGISTRATION_EXPIRY_TIME_MS.
- *
- * &#64;return true if the registration has expired.
- */
-private boolean isRegistrationExpired() {
-    final SharedPreferences prefs = getGCMPreferences(context);
-    // checks if the information is not stale
-    long expirationTime =
-            prefs.getLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, -1);
-    return System.currentTimeMillis() > expirationTime;
-}</pre>
-
-
-<p>If there isn't a valid existing registration ID, {@code DemoActivity} calls the following {@code registerBackground()} method to register. Note that because GCM methods are blocking, this has to take place on a background thread. This sample uses {@link android.os.AsyncTask} to accomplish this:</p>
-
-<pre>
-/**
- * Registers the application with GCM servers asynchronously.
- * &lt;p&gt;
- * Stores the registration id, app versionCode, and expiration time in the 
- * application's shared preferences.
- */
-private void registerBackground() {
-    new AsyncTask<Void, Void, String>() {
-        &#64;Override
-        protected String doInBackground(Void... params) {
-            String msg = "";
-            try {
-                if (gcm == null) {
-                    gcm = GoogleCloudMessaging.getInstance(context);
-                }
-                regid = gcm.register(SENDER_ID);
-                msg = "Device registered, registration id=" + regid;
-
-                // You should send the registration ID to your server over HTTP,
-                // so it can use GCM/HTTP or CCS to send messages to your app.
-
-                // For this demo: we don't need to send it because the device
-                // will send upstream messages to a server that echo back the message
-                // using the 'from' address in the message.
-
-                // Save the regid - no need to register again.
-                setRegistrationId(context, regid);
-            } catch (IOException ex) {
-                msg = "Error :" + ex.getMessage();
-            }
-            return msg;
-        }
-
-        &#64;Override
-        protected void onPostExecute(String msg) {
-            mDisplay.append(msg + "\n");
-        }
-    }.execute(null, null, null);
-}</pre>
-
-<p>After registering, the app calls {@code setRegistrationId()} to store the registration ID in shared preferences for future use:</p>
-
-<pre>/**
- * Stores the registration id, app versionCode, and expiration time in the
- * application's {&#64;code SharedPreferences}.
- *
- * &#64;param context application's context.
- * &#64;param regId registration id
- */
-private void setRegistrationId(Context context, String regId) {
-    final SharedPreferences prefs = getGCMPreferences(context);
-    int appVersion = getAppVersion(context);
-    Log.v(TAG, "Saving regId on app version " + appVersion);
-    SharedPreferences.Editor editor = prefs.edit();
-    editor.putString(PROPERTY_REG_ID, regId);
-    editor.putInt(PROPERTY_APP_VERSION, appVersion);
-    long expirationTime = System.currentTimeMillis() + REGISTRATION_EXPIRY_TIME_MS;
-
-    Log.v(TAG, "Setting registration expiry time to " +
-            new Timestamp(expirationTime));
-    editor.putLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, expirationTime);
-    editor.commit();
-}</pre>
-
-<h5>Sending a message</h5>
-<p>When the user clicks the app's <strong>Send</strong> button, the app sends an upstream message using the new <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs. In order to receive the upstream message, your server should be connected to CCS. You can use the code shown in <a href="#server">Writing the Server Code</a> as a sample XMPP client to connect to CCS.</p>
-
-<pre>public void onClick(final View view) {
-    if (view == findViewById(R.id.send)) {
-        new AsyncTask<Void, Void, String>() {
-            &#64;Override
-            protected String doInBackground(Void... params) {
-                String msg = "";
-                try {
-                    Bundle data = new Bundle();
-                    data.putString("hello", "World");
-                    String id = Integer.toString(msgId.incrementAndGet());
-                    gcm.send(SENDER_ID + "&#64;gcm.googleapis.com", id, data);
-                    msg = "Sent message";
-                } catch (IOException ex) {
-                    msg = "Error :" + ex.getMessage();
-                }
-                return msg;
-            }
-
-            &#64;Override
-            protected void onPostExecute(String msg) {
-                mDisplay.append(msg + "\n");
-            }
-        }.execute(null, null, null);
-    } else if (view == findViewById(R.id.clear)) {
-        mDisplay.setText("");
-    } 
-}</pre>
-
-<p>As described above in <a href="#manifest">Step 1</a>, the app includes a broadcast receiver for the <code>com.google.android.c2dm.intent.RECEIVE</code> intent. This is the mechanism GCM uses to deliver messages. When {@code onClick()} calls {@code gcm.send()}, it triggers the broadcast receiver's {@code onReceive()} method, which has the responsibility of handling the GCM message. In this sample the receiver's {@code onReceive()} method calls {@code sendNotification()} to put the message into a notification:</p>
-
-<pre>/**
- * Handling of GCM messages.
- */
-public class GcmBroadcastReceiver extends BroadcastReceiver {
-    static final String TAG = "GCMDemo";
-    public static final int NOTIFICATION_ID = 1;
-    private NotificationManager mNotificationManager;
-    NotificationCompat.Builder builder;
-    Context ctx;
-    &#64;Override
-    public void onReceive(Context context, Intent intent) {
-        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
-        ctx = context;
-        String messageType = gcm.getMessageType(intent);
-        if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
-            sendNotification("Send error: " + intent.getExtras().toString());
-        } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
-            sendNotification("Deleted messages on server: " +
-                    intent.getExtras().toString());
-        } else {
-            sendNotification("Received: " + intent.getExtras().toString());
-        }
-        setResultCode(Activity.RESULT_OK);
-    }
-
-    // Put the GCM message into a notification and post it.
-    private void sendNotification(String msg) {
-        mNotificationManager = (NotificationManager)
-                ctx.getSystemService(Context.NOTIFICATION_SERVICE);
-
-        PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0,
-                new Intent(ctx, DemoActivity.class), 0);
-
-        NotificationCompat.Builder mBuilder =
-                new NotificationCompat.Builder(ctx)
-        .setSmallIcon(R.drawable.ic_stat_gcm)
-        .setContentTitle("GCM Notification")
-        .setStyle(new NotificationCompat.BigTextStyle()
-        .bigText(msg))
-        .setContentText(msg);
-
-        mBuilder.setContentIntent(contentIntent);
-        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
-    }
-}</pre>
-
-<h2 id="server">Writing the Server Code</h2>
-
-<p>Here is an example of a CCS server written in Python. You can use this in conjunction with the sample client code shown above. This sample echo server sends an initial message, and for every upstream message received, it sends a dummy response back to the application that sent the upstream message. This example illustrates how to connect,
-send, and receive GCM messages using XMPP. It shouldn't be used as-is
-on a production deployment. For examples of HTTP-based servers, see <a href="server.html">GCM Server</a>.</p>
-
-<pre>
-#!/usr/bin/python
-import sys, json, xmpp, random, string
-
-SERVER = 'gcm.googleapis.com'
-PORT = 5235
-USERNAME = ''
-PASSWORD = ''
-REGISTRATION_ID = ''
-
-unacked_messages_quota = 1000
-send_queue = []
-
-# Return a random alphanumerical id
-def random_id():
-  rid = ''
-  for x in range(8): rid += random.choice(string.ascii_letters + string.digits)
-  return rid
-
-def message_callback(session, message):
-  global unacked_messages_quota
-  gcm = message.getTags('gcm')
-  if gcm:
-    gcm_json = gcm[0].getData()
-    msg = json.loads(gcm_json)
-    if not msg.has_key('message_type'):
-      # Acknowledge the incoming message immediately.
-      send({'to': msg['from'],
-            'message_type': 'ack',
-            'message_id': msg['message_id']})
-      # Queue a response back to the server.
-      if msg.has_key('from'):
-        # Send a dummy echo response back to the app that sent the upstream message.
-        send_queue.append({'to': msg['from'],
-                           'message_id': random_id(),
-                           'data': {'pong': 1}})
-    elif msg['message_type'] == 'ack' or msg['message_type'] == 'nack':
-      unacked_messages_quota += 1
-
-def send(json_dict):
-  template = (&quot;&lt;message&gt;&lt;gcm xmlns='google:mobile:data'&gt;{1}&lt;/gcm&gt;&lt;/message&gt;&quot;)
-  client.send(xmpp.protocol.Message(
-      node=template.format(client.Bind.bound[0], json.dumps(json_dict))))
-
-def flush_queued_messages():
-  global unacked_messages_quota
-  while len(send_queue) and unacked_messages_quota &gt; 0:
-    send(send_queue.pop(0))
-    unacked_messages_quota -= 1
-
-client = xmpp.Client('gcm.googleapis.com', debug=['socket'])
-client.connect(server=(SERVER,PORT), secure=1, use_srv=False)
-auth = client.auth(USERNAME, PASSWORD)
-if not auth:
-  print 'Authentication failed!'
-  sys.exit(1)
-
-client.RegisterHandler('message', message_callback)
-
-send_queue.append({'to': REGISTRATION_ID,
-                   'message_id': 'reg_id',
-                   'data': {'message_destination': 'RegId',
-                            'message_id': random_id()}})
-
-while True:
-  client.Process(1)
-  flush_queued_messages()</pre>
-
-
+<ol>
+  <li>Decide which Google-provided GCM connection server you want to use&mdash;
+  <a href="http.html">HTTP</a> or <a href="ccs.html">XMPP</a> (CCS). GCM connection servers
+take messages from a 3rd-party application
+server (written by you) and send them to a GCM-enabled Android application (the
+"client app," also written by you) running on a device. </li>
+  <li>Implement an application server (the "3rd-party application server") to interact
+with your chosen GCM connection server. The app server sends data to a
+GCM-enabled Android client application via the GCM connection server. For more
+information about implementing the server side, see <a href="server.html">
+Implementing GCM Server</a>.</li>
+<li>Write your client app. This is the GCM-enabled Android application that runs
+on a device. See <a href="client.html">Implementing GCM Client</a> for more information.</li>
+</ol>
 
diff --git a/docs/html/google/gcm/helper.jd b/docs/html/google/gcm/helper.jd
index e7f2f73..19dcdc5 100644
--- a/docs/html/google/gcm/helper.jd
+++ b/docs/html/google/gcm/helper.jd
@@ -1,5 +1,5 @@
 page.title=Using the GCM Helper Libraries
-page.tags="cloud","push","messaging"
+page.tags=cloud,push,messaging
 @jd:body
 
 <div id="deprecatedSticker">
diff --git a/docs/html/google/gcm/http.jd b/docs/html/google/gcm/http.jd
new file mode 100644
index 0000000..b8d8659
--- /dev/null
+++ b/docs/html/google/gcm/http.jd
@@ -0,0 +1,618 @@
+page.title=GCM HTTP Connection Server
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+
+<h2>In this document</h2>
+
+<ol class="toc">
+  <li><a href="#auth">Authentication</a> </li>
+  <li><a href="#request">Request Format</a> </li>
+  <li><a href="#response">Response Format</a>
+  <ol class="toc">
+    <li><a href="#success">Interpreting a success response</a>
+    <li><a href="#error_codes">Interpreting an error response</a>
+    <li><a href="#example-responses">Example responses</a>
+  </ol>
+  </li>
+  <li><a href="#app-server">Implementing an HTTP-Based App Server</a>
+</ol>
+
+<h2>See Also</h2>
+
+<ol class="toc">
+<li><a href="gs.html">Getting Started</a></li>
+<li><a href="client.html">Implementing GCM Client</a></li>
+<li><a href="ccs.html">Cloud Connection Server</a></li>
+
+
+</ol>
+
+</div>
+</div>
+
+<p>This document describes the GCM HTTP connection server. Connection servers
+are the Google-provided servers that take messages from the 3rd-party
+application server and sending them to the device.</p>
+
+
+
+<p class="note"><strong>Note:</strong> See
+<a href="server.html#params">Implementing GCM Server</a> for a list of all the message
+parameters and which connection server(s) supports them.</p>
+
+
+<h2 id="auth">Authentication</h2>
+
+<p>To send a  message, the application server issues a POST request to
+<code>https://android.googleapis.com/gcm/send</code>.</p>
+<p>A  message request is made of 2 parts: HTTP header and HTTP body.</p>
+
+<p>The HTTP header must contain the following headers:</p>
+<ul>
+  <li><code>Authorization</code>: key=YOUR_API_KEY</li>
+  <li><code>Content-Type</code>: <code>application/json</code> for JSON; <code>application/x-www-form-urlencoded;charset=UTF-8</code> for plain text.
+  </li>
+</ul>
+
+<p>For example:
+</p>
+<pre>Content-Type:application/json
+Authorization:key=AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA
+
+{
+  "registration_ids" : ["APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx..."],
+  "data" : {
+    ...
+  },
+}</pre>
+<p class="note">
+  <p><strong>Note:</strong> If <code>Content-Type</code> is omitted, the format
+is assumed to be plain text.</p>
+</p>
+
+<p>The HTTP body content depends on whether you're using JSON or plain text.
+See
+<a href="server.html#params">Implementing GCM Server</a> for a list of all the
+parameters your JSON or plain text message can contain.</p>
+
+
+  <h2 id="request">Request Format</h2>
+  <p>Here is the smallest possible request (a message without any parameters and
+just one recipient) using JSON:</p>
+  <pre class="prettyprint pretty-json">{ &quot;registration_ids&quot;: [ &quot;42&quot; ] }</pre>
+
+  <p>And here the same example using plain text:</p>
+  <pre class="prettyprint">registration_id=42</pre>
+
+  <p> Here is a message with a payload and 6 recipients:</p>
+  <pre class="prettyprint pretty-HTML">{ "data": {
+    "score": "5x1",
+    "time": "15:10"
+  },
+  "registration_ids": ["4", "8", "15", "16", "23", "42"]
+}</pre>
+  <p>Here is a message with all optional fields set and 6 recipients:</p>
+  <pre class="prettyprint pretty-json">{ "collapse_key": "score_update",
+  "time_to_live": 108,
+  "delay_while_idle": true,
+  "data": {
+    "score": "4x8",
+    "time": "15:16.2342"
+  },
+  "registration_ids":["4", "8", "15", "16", "23", "42"]
+}</pre>
+  <p>And here is the same message using plain-text format (but just 1 recipient):  </p>
+
+  <pre class="prettyprint">collapse_key=score_update&amp;time_to_live=108&amp;delay_while_idle=1&amp;data.score=4x8&amp;data.time=15:16.2342&amp;registration_id=42
+  </pre>
+
+<p class="note"><strong>Note:</strong> If your organization has a firewall
+that restricts the traffic to or
+from the Internet, you need to configure it to allow connectivity with GCM in order for
+your Android devices to receive messages.
+The ports to open are: 5228, 5229, and 5230. GCM typically only uses 5228, but
+it sometimes uses 5229 and 5230. GCM doesn't provide specific IPs, so you should allow
+your firewall to accept outgoing connections to all IP addresses
+contained in the IP blocks listed in Google's ASN of 15169.</p>
+
+
+
+<h2 id="response">Response format</h2>
+
+<p>There are two possible outcomes when trying to send a message:</p>
+<ul>
+  <li>The message is processed successfully.</li>
+  <li>The GCM server rejects the request.</li>
+</ul>
+
+<p>When the message is processed successfully, the HTTP response has a 200 status
+and the body contains more information about the status of the message
+(including possible errors). When the request is rejected,
+the HTTP response contains a non-200 status code (such as 400, 401, or 503).</p>
+
+<p>The following table summarizes the statuses that the HTTP response header might
+contain. Click the troubleshoot link for advice on how to deal with each type of
+error.</p>
+<table border=1>
+  <tr>
+    <th>Response</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td>200</td>
+    <td>Message was processed successfully. The response body will contain more
+details about the message status, but its format will depend whether the request
+was JSON or plain text. See <a href="#success">Interpreting a success response</a>
+for more details.</td>
+  </tr>
+  <tr>
+    <td>400</td>
+    <td><span id="internal-source-marker_0.2">Only applies for JSON requests.
+Indicates that the request could not be parsed as JSON, or it contained invalid
+fields (for instance, passing a string where a number was expected). The exact
+failure reason is described in the response and the problem should be addressed
+before the request can be retried.</td>
+  </tr>
+  <tr>
+    <td>401</td>
+    <td>There was an error authenticating the sender account.
+<a href="#auth_error">Troubleshoot</a></td>
+  </tr>
+  <tr>
+    <td>5xx</td>
+    <td>Errors in the 500-599 range (such as 500 or 503) indicate that there wa
+an internal error in the GCM server while trying to process the request, or that
+the server is temporarily unavailable (for example, because of timeouts). Sender
+must retry later, honoring any <code>Retry-After</code> header included in the
+response. Application servers must implement exponential back-off.
+<a href="#internal_error">Troubleshoot</a></td>
+  </tr>
+</table>
+
+<h3 id="success">Interpreting a success response</h3>
+<p>When a JSON request is successful (HTTP status code 200), the response body
+contains a JSON object with the following fields:</p>
+<table>
+  <tr>
+    <th>Field</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td><code>multicast_id</code></td>
+    <td>Unique ID (number) identifying the multicast message.</td>
+  </tr>
+  <tr>
+    <td><code>success</code></td>
+    <td>Number of messages that were processed without an error.</td>
+  </tr>
+  <tr>
+    <td><code>failure</code></td>
+    <td>Number of messages that could not be processed.</td>
+  </tr>
+  <tr>
+    <td><code>canonical_ids</code></td>
+    <td>Number of results that contain a canonical registration ID. See
+<a href="adv.html#canonical">Advanced Topics</a> for more discussion of this topic.</td>
+  </tr>
+  <tr>
+    <td><code>results</code></td>
+    <td>Array of objects representing the status of the messages processed. The
+objects are listed in the same order as the request (i.e., for each registration
+ID in the request, its result is listed in the same index in the response) and
+they can have these fields:<br>
+      <ul>
+        <li><code>message_id</code>: String representing the message when it was
+successfully processed.</li>
+        <li><code>registration_id</code>: If set,  means that GCM processed the
+message but it has another canonical registration ID for that device, so sender
+should replace the IDs on future requests (otherwise they might be rejected).
+This field is never set if there is an error in the request.
+        </li>
+        <li><code>error</code>: String describing an error that occurred while
+processing the message for that recipient. The possible values are the same as
+documented in the above table, plus &quot;Unavailable&quot;  (meaning GCM servers
+were busy and could not process the message for that  particular recipient, so
+it could be retried).</li>
+    </ul></td>
+  </tr>
+</table>
+<p>If the value of <code>failure</code> and <code>canonical_ids</code> is 0, it's
+not necessary to parse the remainder of the response. Otherwise, we recommend
+that you iterate through the results field and do the following for each object
+in that list:</p>
+<ul>
+  <li>If <code>message_id</code> is set, check for <code>registration_id</code>:
+    <ul>
+      <li>If <code>registration_id</code> is set, replace the original ID with
+the new value (canonical ID) in your server database. Note that the original ID
+is not part of the result, so you need to obtain it from the list of
+code>registration_ids</code> passed in the request (using the same index).</li>
+    </ul>
+  </li>
+  <li>Otherwise, get the value of <code>error</code>:
+    <ul>
+      <li>If it is <code>Unavailable</code>, you could retry to send it in another
+request.</li>
+      <li>If it is <code>NotRegistered</code>, you should remove the registration
+ID from your server database because the application was uninstalled from the
+device or it does not have a broadcast receiver configured to receive
+<code>com.google.android.c2dm.intent.RECEIVE</code> intents.</li>
+      <li>Otherwise, there is something wrong in the registration ID passed in
+the request; it is probably a non-recoverable error that will also require removing
+the registration from the server database. See <a href="#error_codes">Interpreting
+an error response</a> for all possible error values.</li>
+    </ul>
+  </li>
+</ul>
+
+<p>When a plain-text request is successful (HTTP status code 200), the response
+body contains 1 or 2 lines in the form of key/value pairs.
+The first line is always available and its content is either <code>id=<em>ID of
+sent message</em></code> or <code>Error=<em>GCM error code</em></code>. The second
+line, if available,
+has the format of <code>registration_id=<em>canonical ID</em></code>. The second
+line is optional, and it can only be sent if the first line is not an error. We
+recommend handling the plain-text response in a similar way as handling the
+JSON response:</p>
+<ul>
+  <li>If first line starts with <code>id</code>, check second line:
+    <ul>
+      <li>If second line starts with <code>registration_id</code>, gets its value
+and replace the registration IDs in your server database.</li>
+    </ul>
+  </li>
+  <li>Otherwise, get the value of <code>Error</code>:
+    <ul>
+      <li>If it is <code>NotRegistered</code>, remove the registration ID from
+your server database.</li>
+      <li>Otherwise, there is probably a non-recoverable error (<strong>Note:
+</strong>Plain-text requests will never return <code>Unavailable</code> as the
+error code, they would have returned a 500 HTTP status instead).</li>
+    </ul>
+  </li>
+</ul>
+
+<h3 id="error_codes">Interpreting an error response</h3>
+<p>Here are the recommendations for handling the different types of error that
+might occur when trying to send a message to a device:</p>
+
+<dl>
+<dt id="missing_reg"><strong>Missing Registration ID</strong></dt>
+<dd>Check that the request contains a registration ID (either in the
+<code>registration_id</code> parameter in a plain text message, or in the
+<code>registration_ids</code> field in JSON).
+<br/>Happens when error code is <code>MissingRegistration</code>.</dd>
+
+<dt id="invalid_reg"><strong>Invalid Registration ID</strong></dt>
+<dd>Check the formatting of the registration ID that you pass to the server. Make
+sure it matches the registration ID the phone receives in the
+<code>com.google.android.c2dm.intent.REGISTRATION</code> intent and that you're
+not truncating it or adding additional characters.
+<br/>Happens when error code is <code>InvalidRegistration</code>.</dd>
+
+<dt id="mismatched_sender"><strong>Mismatched Sender</strong></dt>
+<dd>A registration ID is tied to a certain group of senders. When an application
+registers for GCM usage, it must specify which senders are allowed to send messages.
+Make sure you're using one of those when trying to send messages to the device.
+If you switch to a different sender, the existing registration IDs won't work.
+Happens when error code is <code>MismatchSenderId</code>.</dd>
+
+<dt id="unreg_device"><strong>Unregistered Device</strong></dt>
+<dd>An existing registration ID may cease to be valid in a number of scenarios, including:
+<ul>
+  <li>If the application manually unregisters by issuing a
+<span class="prettyprint pretty-java">
+<code>com.google.android.c2dm.intent.UNREGISTER</code></span><code>
+</code>intent.</li>
+  <li>If the application is automatically unregistered, which can happen
+(but is not guaranteed) if the user uninstalls the application.</li>
+  <li>If the registration ID expires. Google might decide to refresh registration
+IDs. </li>
+  <li>If the application is updated but the new version does not have a broadcast
+receiver configured to receive <code>com.google.android.c2dm.intent.RECEIVE</code>
+intents.</li>
+</ul>
+For all these cases, you should remove this registration ID from the 3rd-party
+server and stop using it to send
+messages.
+<br/>Happens when error code is <code>NotRegistered</code>.</dd>
+
+<dt id="big_msg"><strong>Message Too Big</strong></dt>
+  <dd>The total size of the payload data that is included in a message can't
+exceed 4096 bytes. Note that this includes both the size of the keys as well
+as the values.
+<br/>Happens when error code is <code>MessageTooBig</code>.</dd>
+
+<dt id="invalid_datakey"><strong>Invalid Data Key</strong></dt>
+<dd>The payload data contains a key (such as <code>from</code> or any value
+prefixed by <code>google.</code>) that is used internally by GCM in the
+<code>com.google.android.c2dm.intent.RECEIVE</code> Intent and cannot be used.
+Note that some words (such as <code>collapse_key</code>) are also used by GCM
+but are allowed in the payload, in which case the payload value will be
+overridden by the GCM value.
+<br />
+Happens when the error code is <code>InvalidDataKey</code>.</dd>
+
+<dt id="ttl_error"><strong>Invalid Time To Live</strong></dt>
+  <dd>The value for the Time to Live field must be an integer representing
+a duration in seconds between 0 and 2,419,200 (4 weeks). Happens when error code
+is <code>InvalidTtl</code>.
+</dd>
+
+  <dt id="auth_error"><strong>Authentication Error</strong></dt>
+  <dd>The sender account that you're trying to use to send a message couldn't be
+authenticated. Possible causes are: <ul>
+<li>Authorization header missing or with invalid syntax.</li>
+<li>Invalid project number sent as key.</li>
+<li>Key valid but with GCM service disabled.</li>
+<li>Request originated from a server not whitelisted in the Server Key IPs.</li>
+
+</ul>
+Check that the token you're sending inside the <code>Authorization</code> header
+is the correct API key associated with your project. You can check the validity
+of your API key by running the following command:<br/>
+
+<pre># api_key=YOUR_API_KEY
+
+# curl --header "Authorization: key=$api_key" --header Content-Type:"application/json" https://android.googleapis.com/gcm/send  -d "{\"registration_ids\":[\"ABC\"]}"</pre>
+
+
+
+If you receive a 401 HTTP status code, your API key is not valid. Otherwise you
+should see something like this:<br/>
+
+<pre>
+{"multicast_id":6782339717028231855,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
+</pre>
+If you want to confirm the validity of a registration ID, you can do so by
+replacing "ABC" with the registration ID.
+<br/>
+Happens when the HTTP status code is 401.
+
+  <dt id="timeout"><strong>Timeout</strong></dt>
+
+<dd>The server couldn't process the request in time. You should retry the
+same request, but you MUST obey the following requirements:
+
+<ul>
+
+<li>Honor the <code>Retry-After</code> header if it's included in the response
+from the GCM server.</li>
+
+
+<li>Implement exponential back-off in your retry mechanism. This means an
+exponentially increasing delay after each failed retry (e.g. if you waited one
+second before the first retry, wait at least two second before the next one,
+then 4 seconds and so on). If you're sending multiple messages, delay each one
+independently by an additional random amount to avoid issuing a new request for
+all messages at the same time.</li>
+
+
+Senders that cause problems risk being blacklisted.
+<br />
+Happens when the HTTP status code is between 501 and 599, or when the
+<code>error</code> field of a JSON object in the results array is <code>Unavailable</code>.
+</dd>
+
+<dt id="internal_error"><strong>Internal Server Error</strong></dt>
+
+<dd>
+The server encountered an error while trying to process the request. You
+could retry the same request (obeying the requirements listed in the <a href="#timeout">Timeout</a>
+section), but if the error persists, please report the problem in the
+<a href="https://groups.google.com/forum/?fromgroups#!forum/android-gcm">android-gcm group</a>.
+<br />
+Happens when the HTTP status code is 500, or when the <code>error</code> field of a JSON
+object in the results array is <code>InternalServerError</code>.
+</dd>
+
+<dt id="restricted_package_name"><strong>Invalid Package Name</strong></dt>
+
+<dd>
+A message was addressed to a registration ID whose package name did not match
+the value passed in the request. Happens when error code is
+<code>InvalidPackageName</code>.
+</dd>
+</dl>
+
+<h3 id="example-responses">Example responses</h3>
+<p>This section shows a few examples of responses indicating messages that were
+processed successfully. See <a href="#request">Request Format</a> for
+the requests these responses are based on.</p>
+<p> Here is a simple case of a JSON message successfully sent to one recipient
+without canonical IDs in the response:</p>
+<pre class="prettyprint pretty-json">{ "multicast_id": 108,
+  "success": 1,
+  "failure": 0,
+  "canonical_ids": 0,
+  "results": [
+    { "message_id": "1:08" }
+  ]
+}</pre>
+
+<p>Or if the request was in plain-text format:</p>
+<pre class="prettyprint">id=1:08
+</pre>
+
+<p>Here are JSON results for 6 recipients (IDs 4, 8, 15, 16, 23, and 42 respectively)
+with 3 messages successfully processed, 1 canonical registration ID returned,
+and 3 errors:</p>
+<pre class="prettyprint pretty-json">{ "multicast_id": 216,
+  "success": 3,
+  "failure": 3,
+  "canonical_ids": 1,
+  "results": [
+    { "message_id": "1:0408" },
+    { "error": "Unavailable" },
+    { "error": "InvalidRegistration" },
+    { "message_id": "1:1516" },
+    { "message_id": "1:2342", "registration_id": "32" },
+    { "error": "NotRegistered"}
+  ]
+}
+</pre>
+<p> In this example:</p>
+<ul>
+  <li>First message: success, not required.</li>
+  <li>Second message: should be resent (to registration ID 8).</li>
+  <li>Third message: had an unrecoverable error (maybe the value got corrupted
+in the database).</li>
+  <li>Fourth message: success, nothing required.</li>
+  <li>Fifth message: success, but the registration ID should be updated in the
+server database (from 23 to 32).</li>
+  <li>Sixth message: registration ID (42) should be removed from the server database
+because the application was uninstalled from the device.</li>
+</ul>
+<p>Or if just the 4th message above was sent using plain-text format:</p>
+<pre class="prettyprint">Error=InvalidRegistration
+</pre>
+<p>If the 5th message above was also sent using plain-text format:</p>
+<pre class="prettyprint">id=1:2342
+registration_id=32
+</pre>
+
+
+<h2 id="app-server">Implementing an HTTP-Based App Server</h2>
+
+<p>This section gives examples of implementing an app server that works with the
+GCM HTTP connection server. Note that a full GCM implementation requires a
+client-side implementation, in addition to the server.</a>
+
+
+<p>Requirements</p>
+<p>For the web server:</p>
+<ul>
+  <li> <a href="http://ant.apache.org/">Ant 1.8</a> (it might work with earlier versions, but it's not guaranteed).</li>
+  <li>One of the following:
+    <ul>
+      <li>A running web server compatible with Servlets API version 2.5, such as
+<a href="http://tomcat.apache.org/">Tomcat 6</a> or <a href="http://jetty.codehaus.org/">Jetty</a>, or</li>
+      <li><a href="http://code.google.com/appengine/">Java App Engine SDK</a>
+version 1.6 or later.</li>
+    </ul>
+  </li>
+  <li>A Google account registered to use GCM.</li>
+  <li>The API  key for that account.</li>
+</ul>
+<p>For the Android application:</p>
+<ul>
+  <li>Emulator (or device) running Android 2.2 with Google APIs.</li>
+  <li>The Google API project number of the account registered to use GCM.</li>
+</ul>
+
+<h3 id="gcm-setup">Setting Up GCM</h3>
+<p>Before proceeding with the server and client setup, it's necessary to register
+a Google account with the Google API Console, enable Google Cloud Messaging in GCM,
+and obtain an API key from the <a href="https://code.google.com/apis/console">
+Google API Console</a>.</p>
+<p>For instructions on how to set up GCM, see <a href="gs.html">Getting Started</a>.</p>
+
+
+<h3 id="server-setup">Setting Up an HTTP Server</h3>
+<p>This section describes the different options for setting up an HTTP server.</p>
+
+<h4 id="webserver-setup">Using a standard web server</h4>
+<p>To set up the server using a standard, servlet-compliant web server:</p>
+<ol>
+  <li>From the <a href="http://code.google.com/p/gcm">open source site</a>,
+download the following directories: <code>gcm-server</code>,
+<code>samples/gcm-demo-server</code>, and <code>samples/gcm-demo-appengine</code>.</p>
+
+
+  <li>In a text editor, edit the <code>samples/gcm-demo-server/WebContent/WEB-INF/classes/api.key</code> and replace the existing text with the API key obtained above.</li>
+  <li>In a shell window, go to the <code>samples/gcm-demo-server</code> directory.</li>
+  <li>Generate the server's WAR file by running <code>ant war</code>:</li>
+
+  <pre class="prettyprint">$ ant war
+
+Buildfile:build.xml
+
+init:
+   [mkdir] Created dir: build/classes
+   [mkdir] Created dir: dist
+
+compile:
+   [javac] Compiling 6 source files to build/classes
+
+war:
+     [war] Building war: <strong>dist/gcm-demo.war</strong>
+
+BUILD SUCCESSFUL
+Total time: 0 seconds
+</pre>
+
+  <li>Deploy the <code>dist/gcm-demo.war</code> to your running server. For instance, if you're using Jetty, copy <code>gcm-demo.war</code> to the <code>webapps</code> directory of the Jetty installation.</li>
+  <li>Open the server's main page in a browser. The URL depends on the server you're using and your machine's IP address, but it will be something like <code>http://192.168.1.10:8080/gcm-demo/home</code>, where <code>gcm-demo</code> is the application context and <code>/home</code> is the path of the main servlet.
+
+  </li>
+</ol>
+<p class="note"><strong>Note:</strong> You can get the IP by running <code>ifconfig</code> on Linux or MacOS, or <code>ipconfig</code> on Windows. </p>
+
+<p> You server is now ready.</p>
+
+<h4 id="appengine-setup">Using App Engine for Java</h4>
+
+<p>To set up the server using a standard App Engine for Java:</p>
+<ol>
+  <li>Get the files from the <a href="http://code.google.com/p/gcm">open source
+site</a>, as described above.</p>
+  </li>
+  <li>In a text editor, edit
+<code>samples/gcm-demo-appengine/src/com/google/android/gcm/demo/server/ApiKeyInitializer.java</code>
+and replace the existing text with the API key obtained above.
+
+  <p class="note"><strong>Note:</strong> The API key value set in that class will
+be used just once to create a persistent entity on App Engine. If you deploy
+the application, you can use App Engine's <code>Datastore Viewer</code> to change
+it later.</p>
+
+  </li>
+  <li>In a shell window, go to the <code>samples/gcm-demo-appengine</code> directory.</li>
+  <li>Start the development App Engine server by <code>ant runserver</code>,
+using the <code>-Dsdk.dir</code> to indicate the location of the App Engine SDK
+and <code>-Dserver.host</code> to set your server's hostname or IP address:</li>
+
+<pre class="prettyprint">
+$ ant -Dsdk.dir=/opt/google/appengine-java-sdk runserver -Dserver.host=192.168.1.10
+Buildfile: gcm-demo-appengine/build.xml
+
+init:
+    [mkdir] Created dir: gcm-demo-appengine/dist
+
+copyjars:
+
+compile:
+
+datanucleusenhance:
+  [enhance] DataNucleus Enhancer (version 1.1.4) : Enhancement of classes
+  [enhance] DataNucleus Enhancer completed with success for 0 classes. Timings : input=28 ms, enhance=0 ms, total=28 ms. Consult the log for full details
+  [enhance] DataNucleus Enhancer completed and no classes were enhanced. Consult the log for full details
+
+runserver:
+     [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.jetty.JettyLogger info
+     [java] INFO: Logging to JettyLogger(null) via com.google.apphosting.utils.jetty.JettyLogger
+     [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.config.AppEngineWebXmlReader readAppEngineWebXml
+     [java] INFO: Successfully processed gcm-demo-appengine/WebContent/WEB-INF/appengine-web.xml
+     [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.config.AbstractConfigXmlReader readConfigXml
+     [java] INFO: Successfully processed gcm-demo-appengine/WebContent/WEB-INF/web.xml
+     [java] Jun 15, 2012 8:46:09 PM com.google.android.gcm.demo.server.ApiKeyInitializer contextInitialized
+     [java] SEVERE: Created fake key. Please go to App Engine admin console, change its value to your API Key (the entity type is 'Settings' and its field to be changed is 'ApiKey'), then restart the server!
+     [java] Jun 15, 2012 8:46:09 PM com.google.appengine.tools.development.DevAppServerImpl start
+     [java] INFO: The server is running at http://192.168.1.10:8080/
+     [java] Jun 15, 2012 8:46:09 PM com.google.appengine.tools.development.DevAppServerImpl start
+     [java] INFO: The admin console is running at http://192.168.1.10:8080/_ah/admin
+</pre>
+
+  <li>Open the server's main page in a browser. The URL depends on the server
+you're using and your machine's IP address, but it will be something like
+<code>http://192.168.1.10:8080/home</code>, where <code>/home</code>
+is the path of the main servlet.</li>
+
+  <p class="note"><strong>Note:</strong> You can get the IP by running <code>ifconfig</code>
+on Linux or MacOS, or <code>ipconfig</code> on Windows.</p>
+
+</ol>
+<p> You server is now ready.</p>
diff --git a/docs/html/google/gcm/index.jd b/docs/html/google/gcm/index.jd
index 8f325b8..70f7a9c 100644
--- a/docs/html/google/gcm/index.jd
+++ b/docs/html/google/gcm/index.jd
@@ -1,5 +1,5 @@
 page.title=Google Cloud Messaging for Android
-page.tags="gcm"
+page.tags=gcm
 header.hide=1
 @jd:body
 
diff --git a/docs/html/google/gcm/notifications.jd b/docs/html/google/gcm/notifications.jd
index 5171850..43a7368 100644
--- a/docs/html/google/gcm/notifications.jd
+++ b/docs/html/google/gcm/notifications.jd
@@ -14,14 +14,15 @@
 <h2>In this document</h2>
 
 <ol class="toc">
-  <li><a href="#what">What are User Notifications?</a> </li>
-  <li><a href="#examples">Examples</a>
-    <ol>
-      <li><a href="#create">Generate a notification key</a></li>
-      <li><a href="#add">Add registration IDs</a></li>
-      <li><a href="#remove">Remove registration IDs</a></li>
-      <li><a href="#upstream">Send upstream messages</a></li>
-      <li><a href="#response">Response formats</a></li>
+  <li><a href="#request">Request Format</a></li>
+  <li><a href="#create">Generate a Notification Key</a></li>
+  <li><a href="#add">Add Registration IDs</a></li>
+  <li><a href="#remove">Remove Registration IDs</a></li>
+  <li><a href="#upstream">Send Upstream Messages</a></li>
+  <li><a href="#response">Response Formats</a>
+    <ol class="toc">
+      <li><a href="#response-create">Create/add/remove operations</a>
+      <li><a href="#response-send">Send operations</a>
     </ol>
   </li>
 </ol>
@@ -38,32 +39,51 @@
 
 <p class="note"><strong>Note:</strong> To try out this feature, sign up using <a href="https://services.google.com/fb/forms/gcm/">this form</a>.</p>
 
-<p>The upstream messaging (device-to-cloud) feature described in this document is part of the Google Play services platform. Upstream messaging is available through the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">GoogleCloudMessaging</a> APIs. To use upstream messaging and the new streamlined registration process, you must <a href="{@docRoot}google/play-services/setup.html">set up</a> the Google Play services SDK.</p>
 
-<h2 id="what">What are User Notifications?</h2>
-
-<p>Third party servers can send a single message to multiple instance of an app running on devices owned by a single user. This feature is called <em>user notifications</em>. User notifications make it possible for every app instance that a user owns to reflect the latest messaging state. For example:</p>
+<p>With user notifications, 3rd-party app servers can send a single message to
+multiple instance of an app running on devices owned by a single user. This feature
+is called <em>user notifications</em>. User notifications make it possible for every
+app instance that a user owns to reflect the latest messaging state. For example:</p>
 
   <ul>
-  <li>If a message has been handled on one device, the GCM message on the other devices are dismissed. For example, if a user has handled a calendar notification on one device, the notification will go away on the user's other devices.</li>
-  <li>If a message has not been delivered yet to a device and but it has been handled, the GCM server removes it from the unsent queue for the other devices.</li>
-  <li>Likewise, a device can send messages to the {@code notification_key}, which is the token that GCM uses to fan out notifications to all devices whose registration IDs are associated with the key.</li>
+  <li>If a message has been handled on one device, the GCM message on the other
+devices are dismissed. For example, if a user has handled a calendar notification
+on one device, the notification will go away on the user's other devices.</li>
+
+  <li>If a message has not been delivered yet to a device and but it has been handled,
+the GCM server removes it from the unsent queue for the other devices.</li>
+
+  <li>Likewise, a device can send messages to the {@code notification_key}, which
+is the token that GCM uses to fan out notifications to all devices whose
+registration IDs are associated with the key.</li>
 </ul>
 
-<p>The way this works is that during registration, the 3rd-party server requests a {@code notification_key}. The {@code notification_key} maps a particular user to all of the user's associated registration IDs (a regID represents a particular Android application running on a particular device). Then instead of sending one message to one regID at a time, the 3rd-party server can send a message to to the {@code notification_key}, which then sends the message to all of the user's regIDs.</p>
+<p>The way this works is that during registration, the 3rd-party server requests
+a {@code notification_key}. The {@code notification_key} maps a particular user
+to all of the user's associated registration IDs (a regID represents a particular
+Android application running on a particular device). Then instead of sending one
+message to one regID at a time, the 3rd-party server can send a message to to the
+{@code notification_key}, which then sends the message to all of the user's regIDs.</p>
 
-<p class="note"><strong>Note:</strong> A notification dismissal message is like any other upstream message, meaning that it will be delivered to the other devices that belong to the specified {@code notification_key}. You should design your app to handle cases where the app receives a dismissal message, but has not yet displayed the notification that is being dismissed. You can solve this by caching the dismissal and then reconciling it with the corresponding notification.
+<p class="note"><strong>Note:</strong> A notification dismissal message is like any
+other upstream message, meaning that it will be delivered to the other devices that
+belong to the specified {@code notification_key}. You should design your app to
+handle cases where the app receives a dismissal message, but has not yet displayed
+the notification that is being dismissed. You can solve this by caching the dismissal
+and then reconciling it with the corresponding notification.
 </p>
 
-<p>You can use this feature with either the new <a href="ccs.html">GCM Cloud Connection Server</a> (CCS), or the older <a href="gcm.html">GCM HTTP server</a>.</p>
+<p>You can use this feature with either the <a href="ccs.html">XMPP</a> (CCS) or
+<a href="http.html">HTTP</a> connection server.</p>
 
 
-<h3 id="examples">Examples</h3>
+<p>The examples below show you how to perform generate/add/remove operations,
+and how to send upstream messages. For generate/add/remove operations, the
+message body is JSON.</p>
 
-<p>The examples in this section show you how to perform generate/add/remove operations, and how to send upstream messages. For generate/add/remove operations, the message body is JSON.</p>
-
-<h4 id="request">Request format</h4>
-<p>To send a  message, the application server issues a POST request to <code>https://android.googleapis.com/gcm/notification</code>.</p>
+<h2 id="request">Request Format</h2>
+<p>To send a  message, the application server issues a POST request to
+<code>https://android.googleapis.com/gcm/notification</code>.</p>
 
 <p>Here is the HTTP request header you should use for all create/add/remove operations:</p>
 
@@ -72,12 +92,22 @@
 Header: "Authorization", "key=API_KEY"
 </pre>
 
-<h4 id="create">Generate a notification key</h4>
+<h2 id="create">Generate a Notification Key</h2>
 
-<p>This example shows how to create a new <code>notification_key</code> for a <code>notification_key_name</code> called <code>appUser-Chris</code>. The {@code notification_key_name} is a name or identifier (can be a username for a 3rd-party app) that is unique to a given user. It is used by third parties to group together registration IDs for a single user. Note that <code>notification_key_name</code> and <code>notification_key</code> are unique to a group of registration IDs. It is also important that <code>notification_key_name</code> be uniquely named per app in case you have multiple apps for the same project ID. This ensures that notifications only go to the intended target app.</p>
+<p>This example shows how to create a new <code>notification_key</code> for a
+<code>notification_key_name</code> called <code>appUser-Chris</code>.
+The {@code notification_key_name} is a name or identifier (can be a username for
+a 3rd-party app) that is unique to a given user. It is used by third parties to
+group together registration IDs for a single user. Note that <code>notification_key_name</code>
+and <code>notification_key</code> are unique to a group of registration IDs. It is also
+important that <code>notification_key_name</code> be uniquely named per app in case
+you have multiple apps for the same project ID. This ensures that notifications
+only go to the intended target app.</p>
 
 
-<p>A create operation returns a token (<code>notification_key</code>). Third parties must save this token (as well as its mapping to the <code>notification_key_name</code>) to use in subsequent operations:</p>
+<p>A create operation returns a token (<code>notification_key</code>). Third parties
+must save this token (as well as its mapping to the <code>notification_key_name</code>)
+to use in subsequent operations:</p>
 
 <pre>request:
 { 
@@ -86,11 +116,14 @@
    &quot;registration_ids&quot;: [&quot;4&quot;, &quot;8&quot;, &quot;15&quot;, &quot;16&quot;, &quot;23&quot;, &quot;42&quot;]
 }</pre>
 
-<h4 id="add">Add registration IDs</h4>
+<h2 id="add">Add Registration IDs</h2>
 
-<p>This example shows how to add registration IDs for a given notification key. The maximum number of members allowed for a {@code notification_key} is 10.</p>
+<p>This example shows how to add registration IDs for a given notification key.
+The maximum number of members allowed for a {@code notification_key} is 10.</p>
 
-<p>Note that the <code>notification_key_name</code> is not strictly required for adding/removing regIDs. But including it protects you against accidentally using the incorrect <code>notification_key</code>.</p>
+<p>Note that the <code>notification_key_name</code> is not strictly required for
+adding/removing regIDs. But including it protects you against accidentally using
+the incorrect <code>notification_key</code>.</p>
 
 <pre>request:
 { 
@@ -100,7 +133,7 @@
    &quot;registration_ids&quot;: [&quot;4&quot;, &quot;8&quot;, &quot;15&quot;, &quot;16&quot;, &quot;23&quot;, &quot;42&quot;]
 }</pre>
 
-<h4 id="remove">Remove registration IDs</h4>
+<h2 id="remove">Remove Registration IDs</h2>
 
 <p>This example shows how to remove registration IDs for a given notification key:</p>
 <pre>request:
@@ -111,9 +144,14 @@
    &quot;registration_ids&quot;: [&quot;4&quot;, &quot;8&quot;, &quot;15&quot;, &quot;16&quot;, &quot;23&quot;, &quot;42&quot;]
 }</pre>
 
-<h4 id="upstream">Send upstream messages</h4>
+<h2 id="upstream">Send Upstream Messages</h2>
 
-<p>To send an upstream (device-to-cloud) message, you must use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">GoogleCloudMessaging</a> API. Specifying a {@code notification_key} as the target for an upstream message allows a user on one device to send a message to other devices in the notification group&mdash;for example, to dismiss a notification. Here is an example that shows targeting a {@code notification_key}:</p>
+<p>To send an upstream (device-to-cloud) message, you must use the
+<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
+{@code GoogleCloudMessaging}</a> API. Specifying a {@code notification_key} as the target
+for an upstream message allows a user on one device to send a message to other
+devices in the notification group&mdash;for example, to dismiss a notification.
+Here is an example that shows targeting a {@code notification_key}:</p>
 
 <pre>GoogleCloudMessaging gcm = GoogleCloudMessaging.get(context);
 String to = NOTIFICATION_KEY;
@@ -125,17 +163,21 @@
 gcm.send(to, id, data);
 </pre>
 
-<p>This call generates the necessary XMPP stanza for sending the message. The Bundle data consists of a key-value pair.</p>
+<p>This call generates the necessary XMPP stanza for sending the message. The
+Bundle data consists of a key-value pair.</p>
 
-<p>For a complete example, see <a href="gs.html#gs_example">Getting Started</a>. 
+<p>For a complete example, see <a href="client.html">Implementing GCM Client</a>.
 
-<h4 id="response">Response formats</h4>
+<h2 id="response">Response Formats</h2>
 
-<p>This section shows examples of the responses that can be returned for notification key operations.</p>
+<p>This section shows examples of the responses that can be returned for
+notification key operations.</p>
 
-<h5>Response for create/add/remove operations</h5>
+<h3 id="response-create">Create/add/remove operations</h3>
 
-<p>When you make a request to create a {@code notification_key} or to add/remove its the wayregIDs, a successful response always returns the <code>notification_key</code>. This is the {@code notification_key} you will use for sending messages:</p>
+<p>When you make a request to create a {@code notification_key} or to add/remove its
+regIDs, a successful response always returns the <code>notification_key</code>.
+his is the {@code notification_key} you will use for sending messages:</p>
 
 <pre>HTTP status: 200
 { 
@@ -143,18 +185,23 @@
 }</pre>
 
 
-<h5>Response for send operations</h5>
+<h3 id="response-send">Send operations</h3>
 
-<p>For a send operation that has a {@code notification_key} as its target, the possible responses are success, partial success, and failure.</p>
+<p>For a send operation that has a {@code notification_key} as its target, the
+possible responses are success, partial success, and failure.</p>
 
-<p>Here is an example of "success"&mdash;the {@code notification_key} has 2 regIDs associated with it, and the message was successfully sent to both of them:</p>
+<p>Here is an example of "success"&mdash;the {@code notification_key} has 2 regIDs
+associated with it, and the message was successfully sent to both of them:</p>
 
 <pre>{
   "success": 2,
   "failure": 0
 }</pre>
 
-<p>Here is an example of "partial success"&mdash;the {@code notification_key} has 3 regIDs associated with it. The message was successfully send to 1 of the regIDs, but not to the other 2. The response message lists the regIDs that failed to receive the message:</p>
+<p>Here is an example of "partial success"&mdash;the {@code notification_key} has
+3 regIDs associated with it. The message was successfully send to 1 of the regIDs,
+but not to the other 2. The response message lists the regIDs that failed to
+receive the message:</p>
 
 <pre>{
   "success":1,
@@ -165,7 +212,9 @@
   ]
 }</pre>
 
-<p>In the case of failure, the response has HTTP code 503 and no JSON. When a message fails to be delivered to one or more of the regIDs associated with a {@code notification_key}, the 3rd-party server should retry.</p>
+<p>In the case of failure, the response has HTTP code 503 and no JSON. When a message
+fails to be delivered to one or more of the regIDs associated with a {@code notification_key},
+the 3rd-party server should retry.</p>
 
 
 
diff --git a/docs/html/google/gcm/server.jd b/docs/html/google/gcm/server.jd
index 92a1531..7ba1bd5 100644
--- a/docs/html/google/gcm/server.jd
+++ b/docs/html/google/gcm/server.jd
@@ -1,36 +1,34 @@
-page.title=GCM Server
+page.title=Implementing GCM Server
 @jd:body
 
 <div id="qv-wrapper">
 <div id="qv">
 
-<h2>Quickview</h2>
-
-<ul>
-<li>Understand how to set up the server side of a GCM app.</li>
-<li>Become familiar with the <a href="{@docRoot}reference/com/google/android/gcm/server/package-summary.html">GCM server helper library</a>.</li>
-</ul>
-
-
 <h2>In this document</h2>
 
-<ol>
-  <li><a href="#requirements">Requirements</a> </li>
-  <li><a href="#gcm-setup">Setting Up GCM</a></li>
-  <li><a href="#server-setup">Setting Up an HTTP Server</a>
-    <ol>
-      <li><a href="#webserver-setup">Using a standard web server</a></li>
-      <li><a href="#appengine-setup">Using App Engine for Java</a></li>
+<ol class="toc">
+  <li><a href="#choose">Choosing a GCM Connection Server</a></li>
+  <li><a href="#role">Role of the 3rd-party Application Server</a></li>
+    <li><a href="#send-msg">Sending Messages</a>
+    <ol class="toc">
+
+      <li><a href="#target">Target</a></li>
+      <li><a href="#payload">Payload</a></li>
+      <li><a href="#params">Message parameters</a>
     </ol>
+    </li>
+  <li><a href="#receive">Receiving Messages</a> </li>
   </li>
+
 </ol>
 
 <h2>See Also</h2>
 
 <ol class="toc">
 <li><a href="gs.html">Getting Started</a></li>
-<li><a href="client.html">GCM Client</a></li>
-<li><a href="ccs.html">Cloud Connection Server</a></li>
+<li><a href="client.html">Implementing GCM Client</a></li>
+<li><a href="ccs.html">Cloud Connection Server (XMPP)</a></li>
+<li><a href="http.html">HTTP Connection Server</a></li>
 
 
 </ol>
@@ -39,122 +37,342 @@
 </div>
 
 
-
-
-<p>This document gives examples of GCM server-side code for HTTP. For an example of an XMPP server (<a href="ccs.html">Cloud Connection Server</a>), see <a href="gs.html#server">Getting Started</a>. Note that a full GCM implementation requires a client-side implementation, in addition to the server. For a complete working example that includes client and server-side code, see <a href="gs.html">Getting Started</a>.</a>
-
-<h2 id="requirements">Requirements</h2>
-<p>For the web server:</p>
+<p>The server side of GCM consists of 2 components:</p>
 <ul>
-  <li> <a href="http://ant.apache.org/">Ant 1.8</a> (it might work with earlier versions, but it's not guaranteed).</li>
-  <li>One of the following:
-    <ul>
-      <li>A running web server compatible with Servlets API version 2.5, such as <a href="http://tomcat.apache.org/">Tomcat 6</a> or <a href="http://jetty.codehaus.org/">Jetty</a>, or</li>
-      <li><a href="http://code.google.com/appengine/">Java App Engine SDK</a> version 1.6 or later.</li>
+<li>Google-provided <strong>GCM Connection Servers</strong>
+take messages from a 3rd-party application server and send them to a GCM-enabled
+Android application (the &quot;client app&quot;) running on a device. For example,
+Google provides connection servers for <a href="{@docRoot}google/gcm/http.html">
+HTTP</a> and <a href="{@docRoot}google/gcm/ccs.html">CCS</a> (XMPP).</li>
+<li>A <strong>3rd-party application server</strong> that you must implement. This application
+server sends data to a GCM-enabled Android application via the chosen GCM connection server.</li>
+</ul>
+</p>
+
+<p>Here are the basic steps you follow to implement your 3rd-party app server:</p>
+
+<ul>
+      <li>Decide which GCM connection server(s) you want to use. Note that if you want to use
+      upstream messaging from your client applications, you must use CCS. For a more detailed
+      discussion of this, see <a href="#choose">
+      Choosing a GCM Connection Server</a>.</li>
+      <li>Decide how you want to implement your app server. For example:
+        <ul>
+          <li>If you decide to use the HTTP connection server, you can use the
+GCM server helper library and demo app to help in implementing your app server.</li>
+          <li>If you decide to use the XMPP connection server, you can use
+the provided Python or Java <a href="http://www.igniterealtime.org/projects/smack/">
+Smack</a> demo apps as a starting point.</li>
+        <li>Note that Google AppEngine does not support connections to CCS.</li>
+        </ul>
+      </li>
     </ul>
   </li>
-  <li>A Google account registered to use GCM.</li>
-  <li>The API  key for that account.</li>
 </ul>
-<p>For the Android application:</p>
+
+<p>A full GCM implementation requires both a client implementation and a server
+implementation. For more
+information about implementing the client side, see <a href="client.html">
+Implementing GCM Client</a>.</p>
+
+<h2 id="choose">Choosing a GCM Connection Server</h2>
+
+<p>Currently GCM provides two connection servers: <a href="{@docRoot}google/gcm/http.html">
+HTTP</a> and <a href="{@docRoot}google/gcm/ccs.html">CCS</a> (XMPP). You can use them
+separately or in tandem. CCS messaging differs from GCM HTTP messaging in the following ways:</p>
 <ul>
-  <li>Emulator (or device) running Android 2.2 with Google APIs.</li>
-  <li>The Google API project number of the account registered to use GCM.</li>
+  <li>Upstream/Downstream messages
+    <ul>
+      <li>GCM HTTP: Downstream only: cloud-to-device. </li>
+      <li>CCS: Upstream and downstream (device-to-cloud, cloud-to-device). </li>
+    </ul>
+  </li>
+  <li>Asynchronous messaging
+    <ul>
+      <li>GCM HTTP: 3rd-party app servers send messages as HTTP POST requests and
+wait for a response. This mechanism is synchronous and causes the sender to block
+before sending another message.</li>
+      <li>CCS: 3rd-party app servers connect to Google infrastructure using a
+persistent XMPP connection and send/receive messages to/from all their devices
+at full line speed. CCS sends acknowledgment or failure notifications (in the
+form of special ACK and NACK JSON-encoded XMPP messages) asynchronously.</li>
+    </ul>
+  </li>
+
+  <li>JSON
+    <ul>
+      <li>GCM HTTP: JSON messages sent as HTTP POST.</li>
+      <li>CCS: JSON messages encapsulated in XMPP messages.</li>
+    </ul>
+  </li>
 </ul>
-<h2 id="gcm-setup">Setting Up GCM</h2>
-<p>Before proceeding with the server and client setup, it's necessary to register a Google account with the Google API Console, enable Google Cloud Messaging in GCM, and obtain an API key from the <a href="https://code.google.com/apis/console">Google API Console</a>.</p>
-<p>For instructions on how to set up GCM, see <a href="gs.html">Getting Started</a>.</p>
 
+<h2 id="role">Role of the 3rd-party Application Server</h2>
 
-<h2 id="server-setup">Setting Up an HTTP Server</h2>
-<p>This section describes the different options for setting up an HTTP server.</p>
-<h3 id="webserver-setup">Using a standard web server</h3>
-<p>To set up the server using a standard, servlet-compliant web server:</p>
+<p>Before you can write client Android applications that use the GCM feature, you must
+have an  application server that meets the following criteria:</p>
+
+<ul>
+  <li>Able to communicate with your client.</li>
+  <li>Able to  fire off properly formatted requests to the GCM server.</li>
+  <li>Able to handle requests and resend them as needed, using
+<a href="http://en.wikipedia.org/wiki/Exponential_backoff">exponential back-off.</a></li>
+  <li>Able to store the API key and client registration IDs. The
+API key is included in the header of POST requests that send
+messages.</li>
+ <li>Able to store the API key and client registration IDs.</li>
+ <li>Able to generate message IDs to uniquely identify each message it sends.</li>
+</ul>
+
+<h2 id="send-msg">Sending Messages</h2>
+
+<p>Here is the general sequence of events that occurs when a 3rd-party application
+server sends a message:</p>
 <ol>
-  <li>From the <a href="http://code.google.com/p/gcm">open source site</a>, download the following directories: <code>gcm-server</code>, <code>samples/gcm-demo-server</code>, and <code>samples/gcm-demo-appengine</code>.</p>
-
-
-  <li>In a text editor, edit the <code>samples/gcm-demo-server/WebContent/WEB-INF/classes/api.key</code> and replace the existing text with the API key obtained above.</li>
-  <li>In a shell window, go to the <code>samples/gcm-demo-server</code> directory.</li>
-  <li>Generate the server's WAR file by running <code>ant war</code>:</li>
-  
-  <pre class="prettyprint">$ ant war
-
-Buildfile:build.xml
-
-init:
-   [mkdir] Created dir: build/classes
-   [mkdir] Created dir: dist
-
-compile:
-   [javac] Compiling 6 source files to build/classes
-
-war:
-     [war] Building war: <strong>dist/gcm-demo.war</strong>
-
-BUILD SUCCESSFUL
-Total time: 0 seconds
-</pre>
-  
-  <li>Deploy the <code>dist/gcm-demo.war</code> to your running server. For instance, if you're using Jetty, copy <code>gcm-demo.war</code> to the <code>webapps</code> directory of the Jetty installation.</li>
-  <li>Open the server's main page in a browser. The URL depends on the server you're using and your machine's IP address, but it will be something like <code>http://192.168.1.10:8080/gcm-demo/home</code>, where <code>gcm-demo</code> is the application context and <code>/home</code> is the path of the main servlet.
-    
-  </li>
+  <li>The application server sends a message to GCM servers.</li>
+  <li>Google enqueues and stores the message in case the device is offline.</li>
+  <li>When the device is online, Google sends the message to the device.</li>
+  <li>On the device, the system broadcasts the message to the specified Android
+application via Intent broadcast with proper permissions, so that only the targeted
+Android application gets the message. This wakes the Android application up.
+The Android application does not need to be running beforehand to receive the message.</li>
+  <li>The Android application processes the message. </li>
 </ol>
-<p class="note"><strong>Note:</strong> You can get the IP by running <code>ifconfig</code> on Linux or MacOS, or <code>ipconfig</code> on Windows. </p>
 
-<p> You server is now ready.</p>
+<p>The following sections describe the basic requirements for
+sending messages.</p>
 
-<h3 id="appengine-setup">Using App Engine for Java</h3>
+<h3 id="target">Target</h3>
+<p>Required. When your app server sends a message in GCM, it must specify a target.</p>
+<p>For HTTP you must specify the target as one of:</p>
+<ul>
+<li><code>registration_ids</code>: For sending to 1 or more devices (up to 1000).
+When you send a message to multiple registration IDs, that is called a multicast message.</li>
+<li><code>notification_key</code>: For sending to multiple devices owned by a single user.</li>
+</ul>
+<p>For CCS (XMPP):</p>
+<ul>
+<li>You must specify the target as the &quot;to&quot; field, where the &quot;to&quot;
+field may contain a single registration ID or a notification key.
+CCS does not support multicast messaging.</li>
+</ul>
+<h3 id="payload">Payload</h3>
+<p>Optional. If you are including a payload in the message, you use the <code>data</code>
+parameter to include the payload. This applies for both HTTP and CCS.</p>
 
-<p>To set up the server using a standard App Engine for Java:</p>
+<h3 id="params">Message parameters</h3>
+
+<p>The following table lists the parameters that a 3rd-party app server might
+include in the JSON messages it sends to a connection server. See the "Where Supported"
+column for information about which connection servers support that particular
+parameter.</p>
+
+<p class="table-caption" id="table1">
+  <strong>Table 1.</strong> Message parameters.</p>
+
+<table>
+  <tr>
+    <th>Field</th>
+    <th>Description</th>
+<th>Where Supported</th>
+</tr>
+  <td><code>to</code></td>
+<td>In CCS, used in place of <code>registration_ids</code> to specify the
+recipient of a message. Its value must be a registration ID.
+The value is a string. Required.</td>
+<td>CCS</td>
+</tr>
+<tr>
+<td><code>message_id</code></td>
+<td>In CCS, uniquely identifies a message in an XMPP connection. The value is a
+string that uniquely identifies the associated message. The value is a string. Required.</td>
+<td>CCS</td>
+</tr>
+<tr>
+<td><code>message_type</code></td>
+<td>In CCS, indicates a special status message, typically sent by the system.
+However, your app server also uses this parameter to send an 'ack' or 'nack'
+message back to the CCS connection server. For more discussion of this topic, see
+<a href="ccs.html">Cloud Connection Server</a>. The value is a string. Optional.</td>
+<td>CCS</td>
+<tr>
+  <td><code>registration_ids</code></td>
+  <td>A string array with the list of devices (registration IDs) receiving the
+message. It must contain at least 1 and at most 1000 registration IDs. To send a
+multicast message, you must use JSON. For sending a single message to a single
+device, you could use a JSON object with just 1 registration id, or plain text
+(see below). A request must include a recipient&mdash;this can be either a
+registration ID, an array of registration IDs, or a {@code notification_key}.
+Required.</td>
+<td>HTTP</td>
+</tr>
+ <tr>
+    <td><code>notification_key</code></td>
+    <td>A string that maps a single user to multiple registration IDs associated
+with that user. This allows a 3rd-party server to send a single message to
+multiple app instances (typically on multiple devices) owned by a single user.
+A 3rd-party server can use {@code notification_key} as the target for a message
+instead of an individual registration ID (or array of registration IDs). The maximum
+number of members allowed for a {@code notification_key} is 10. For more discussion
+of this topic, see <a href="notifications.html">User Notifications</a>. Optional.
+</td>
+<td style="width:100px">HTTP. This feature is supported in CCS, but you use it by
+specifying a notification key in the &quot;to&quot; field.</td>
+</tr>
+  <tr>
+    <td><code>collapse_key</code></td>
+    <td>An arbitrary string (such as &quot;Updates Available&quot;) that is used
+to collapse a group of like messages
+when the device is offline, so that only the last message gets sent to the
+client. This is intended to avoid sending too many messages to the phone when it
+comes back online. Note that since there is no guarantee of the order in which
+messages get sent, the &quot;last&quot; message may not actually be the last
+message sent by the application server. Collapse keys are also called
+<a href="#s2s">send-to-sync messages</a>.
+<br>
+<strong>Note:</strong> GCM allows a maximum of 4 different collapse keys to be
+used by the GCM server
+at any given time. In other words, the GCM server can simultaneously store 4
+different send-to-sync messages per device, each with a different collapse key.
+If you exceed
+this number GCM will only keep 4 collapse keys, with no guarantees about which
+ones they will be. See <a href="adv.html#collapsible">Advanced Topics</a> for more
+discussion of this topic. Optional.</td>
+<td>CCS, HTTP</td>
+</tr>
+  <tr>
+    <td><code>data</code></td>
+    <td>A JSON object whose fields represents the key-value pairs of the message's
+payload data. If present, the payload data it will be
+included in the Intent as application data, with the key being the extra's name.
+For instance, <code>"data":{"score":"3x1"}</code> would result in an intent extra
+named <code>score</code> whose value is the string <code>3x1</code>.
+There is no limit on the number of key/value pairs, though there is a limit on
+the total size of the message (4kb). The values could be any JSON object, but we
+recommend using strings, since the values will be converted to strings in the GCM
+server anyway. If you want to include objects or other non-string data types
+(such as integers or booleans), you have to do the conversion to string yourself.
+Also note that the key cannot be a reserved word (<code>from</code> or any word
+starting with <code>google.</code>). To complicate things slightly, there are
+some reserved words (such as <code>collapse_key</code>) that are technically
+allowed in payload data. However, if the request also contains the word, the
+value in the request will overwrite the value in the payload data. Hence using
+words that are defined as field names in this table is not recommended, even in
+cases where they are technically allowed. Optional.</td>
+<td>CCS, HTTP</td>
+</tr>
+  <tr>
+    <td><code>delay_while_idle</code></td>
+    <td>If included, indicates that the message should not be sent immediately
+if the device is idle. The server will wait for the device to become active, and
+then only the last message for each <code>collapse_key</code> value will be
+sent. The default value is <code>false</code>, and must be a JSON boolean. Optional.</td>
+<td>CCS, HTTP</td>
+</tr>
+  <tr>
+    <td><code>time_to_live</code></td>
+    <td>How long (in seconds) the message should be kept on GCM storage if the
+device is offline. Optional (default time-to-live is 4 weeks, and must be set as
+a JSON number).</td>
+<td>CCS, HTTP</td>
+</tr>
+<tr>
+  <td><code>restricted_package_name</code></td>
+  <td>A string containing the package name of your application. When set, messages
+will only be sent to registration IDs that match the package name. Optional.
+  </td>
+<td>HTTP</td>
+</tr>
+<tr>
+  <td><code>dry_run</code></td>
+  <td>If included, allows developers to test their request without actually
+sending a message. Optional. The default value is <code>false</code>, and must
+be a JSON boolean.
+  </td>
+<td>HTTP</td>
+</tr>
+</table>
+
+<p>If you want to test your request (either JSON or plain text) without delivering
+the message to the devices, you can set an optional HTTP or JSON parameter called
+<code>dry_run</code> with the value <code>true</code>. The result will be almost
+identical to running the request without this parameter, except that the message
+will not be delivered to the devices. Consequently, the response will contain fake
+IDs for the message and multicast fields.</p>
+
+<h3 id="plain-text">Plain text (HTTP only)</h3>
+
+<p>If you are using plain text instead of JSON, the message fields must be set as
+HTTP parameters sent in the body, and their syntax is slightly different, as
+described below:
+<table>
+  <tr>
+    <th>Field</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td><code>registration_id</code></td>
+    <td>Must contain the registration ID of the single device receiving the message.
+Required.</td>
+  </tr>
+  <tr>
+    <td><code>collapse_key</code></td>
+    <td>Same as JSON (see previous table). Optional.</td>
+  </tr>
+  <tr>
+    <td><code>data.&lt;key&gt;</code></td>
+
+    <td>Payload data, expressed as parameters prefixed with <code>data.</code> and
+suffixed as the key. For instance, a parameter of <code>data.score=3x1</code> would
+result in an intent extra named <code>score</code> whose value is the string
+<code>3x1</code>. There is no limit on the number of key/value parameters, though
+there is a limit on the total size of the  message. Also note that the key cannot
+be a reserved word (<code>from</code> or any word starting with
+<code>google.</code>). To complicate things slightly, there are some reserved words
+(such as <code>collapse_key</code>) that are technically allowed in payload data.
+However, if the request also contains the word, the value in the request will
+overwrite the value in the payload data. Hence using words that are defined as
+field names in this table is not recommended, even in cases where they are
+technically allowed. Optional.</td>
+
+  </tr>
+  <tr>
+    <td><code>delay_while_idle</code></td>
+    <td>Should be represented as <code>1</code> or <code>true</code> for
+<code>true</code>, anything else for <code>false</code>. Optional. The default
+value is <code>false</code>.</td>
+  </tr>
+  <tr>
+    <td><code>time_to_live</code></td>
+    <td>Same as JSON (see previous table). Optional.</td>
+  </tr>
+<tr>
+  <td><code>restricted_package_name</code></td>
+  <td>Same as JSON (see previous table). Optional.
+  </td>
+</tr>
+<tr>
+  <td><code>dry_run</code></td>
+  <td>Same as JSON (see previous table). Optional.
+  </td>
+</tr>
+</table>
+
+<h2 id="receive">Receiving Messages</h2>
+
+<p>This is the sequence of events that occurs when an Android application
+installed on a mobile device receives a message:</p>
+
 <ol>
-  <li>Get the files from the <a href="http://code.google.com/p/gcm">open source site</a>, as described above.</p>
-  </li>
-  <li>In a text editor, edit <code>samples/gcm-demo-appengine/src/com/google/android/gcm/demo/server/ApiKeyInitializer.java</code> and replace the existing text with the API key obtained above.
-
-  <p class="note"><strong>Note:</strong> The API key value set in that class will be used just once to create a persistent entity on App Engine. If you deploy the application, you can use App Engine's <code>Datastore Viewer</code> to change it later.</p>
-  
-  </li>
-  <li>In a shell window, go to the <code>samples/gcm-demo-appengine</code> directory.</li>
-  <li>Start the development App Engine server by <code>ant runserver</code>, using the <code>-Dsdk.dir</code> to indicate the location of the App Engine SDK and <code>-Dserver.host</code> to set your server's hostname or IP address:</li>
-
-<pre class="prettyprint">
-$ ant -Dsdk.dir=/opt/google/appengine-java-sdk runserver -Dserver.host=192.168.1.10
-Buildfile: gcm-demo-appengine/build.xml
-
-init:
-    [mkdir] Created dir: gcm-demo-appengine/dist
-
-copyjars:
-
-compile:
-
-datanucleusenhance:
-  [enhance] DataNucleus Enhancer (version 1.1.4) : Enhancement of classes
-  [enhance] DataNucleus Enhancer completed with success for 0 classes. Timings : input=28 ms, enhance=0 ms, total=28 ms. Consult the log for full details
-  [enhance] DataNucleus Enhancer completed and no classes were enhanced. Consult the log for full details
-
-runserver:
-     [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.jetty.JettyLogger info
-     [java] INFO: Logging to JettyLogger(null) via com.google.apphosting.utils.jetty.JettyLogger
-     [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.config.AppEngineWebXmlReader readAppEngineWebXml
-     [java] INFO: Successfully processed gcm-demo-appengine/WebContent/WEB-INF/appengine-web.xml
-     [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.config.AbstractConfigXmlReader readConfigXml
-     [java] INFO: Successfully processed gcm-demo-appengine/WebContent/WEB-INF/web.xml
-     [java] Jun 15, 2012 8:46:09 PM com.google.android.gcm.demo.server.ApiKeyInitializer contextInitialized
-     [java] SEVERE: Created fake key. Please go to App Engine admin console, change its value to your API Key (the entity type is 'Settings' and its field to be changed is 'ApiKey'), then restart the server!
-     [java] Jun 15, 2012 8:46:09 PM com.google.appengine.tools.development.DevAppServerImpl start
-     [java] INFO: The server is running at http://192.168.1.10:8080/
-     [java] Jun 15, 2012 8:46:09 PM com.google.appengine.tools.development.DevAppServerImpl start
-     [java] INFO: The admin console is running at http://192.168.1.10:8080/_ah/admin
-</pre>
-
-  <li>Open the server's main page in a browser. The URL depends on the server you're using and your machine's IP address, but it will be something like <code>http://192.168.1.10:8080/home</code>, where <code>/home</code> is the path of the main servlet.</li>
-  
-  <p class="note"><strong>Note:</strong> You can get the IP by running <code>ifconfig</code> on Linux or MacOS, or <code>ipconfig</code> on Windows.</p>
-  
+  <li>The system receives the incoming message and extracts the raw key/value
+pairs from the message payload, if any.</li>
+  <li>The system passes the key/value pairs to the targeted Android application
+in a <code>com.google.android.c2dm.intent.RECEIVE</code> Intent as a set of
+extras.</li>
+  <li>The Android application extracts the raw data
+from the <code>com.google.android.c2dm.intent.RECEIVE</code><code> </code>Intent
+by key and processes the data.</li>
 </ol>
-<p> You server is now ready.</p>
 
-
+<p>See the documentation for each connection server for more detail on how it
+handles responses.</p>
diff --git a/docs/html/google/google_toc.cs b/docs/html/google/google_toc.cs
index 77042d3..2ded286 100644
--- a/docs/html/google/google_toc.cs
+++ b/docs/html/google/google_toc.cs
@@ -133,29 +133,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="<?cs var:toroot ?>google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="<?cs var:toroot?>google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="<?cs var:toroot?>google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="<?cs var:toroot?>google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="<?cs var:toroot?>google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="<?cs var:toroot?>google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="<?cs var:toroot?>google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="<?cs var:toroot?>google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="<?cs var:toroot?>google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="<?cs var:toroot?>google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="<?cs var:toroot?>google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="<?cs var:toroot?>google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="<?cs var:toroot?>google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/google/play-services/ads.jd b/docs/html/google/play-services/ads.jd
index c666ce9..7536cb0 100644
--- a/docs/html/google/play-services/ads.jd
+++ b/docs/html/google/play-services/ads.jd
@@ -1,5 +1,5 @@
 page.title=Google Mobile Ads
-page.tags="Ads","monetization", "AdMob", "Google Play services"
+page.tags=Ads,monetization,AdMob,Google Play services
 header.hide=1
 
 @jd:body
@@ -82,4 +82,4 @@
     <p class="note"><strong>Note</strong>: The SDK doesn’t currently support DFP, Ad Exchange or Search
     Ads for Mobile Apps but support is coming soon.</p>
   </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/docs/html/google/play-services/auth.jd b/docs/html/google/play-services/auth.jd
index 7acaf1c..dded599 100644
--- a/docs/html/google/play-services/auth.jd
+++ b/docs/html/google/play-services/auth.jd
@@ -1,5 +1,5 @@
 page.title=Authorization
-page.tags="AccountManager","oauth2"
+page.tags=AccountManager,oauth2
 @jd:body
 
 <div id="qv-wrapper">
@@ -236,4 +236,4 @@
     case, obtain a new token using <a
 href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthUtil.html#getToken(android.content.Context, java.lang.String, java.lang.String)"
 >{@code GoogleAuthUtil.getToken()}</a>.
-</p>
\ No newline at end of file
+</p>
diff --git a/docs/html/google/play-services/id.jd b/docs/html/google/play-services/id.jd
index 664c6e6..bd302c0 100644
--- a/docs/html/google/play-services/id.jd
+++ b/docs/html/google/play-services/id.jd
@@ -1,5 +1,5 @@
 page.title=Advertising ID
-page.tags="Ads","Advertising ID", "ID"
+page.tags=Ads,Advertising ID,ID
 header.hide=1
 
 @jd:body
@@ -195,4 +195,4 @@
   }
   final String id = adInfo.getId();
   final boolean isLAT = adInfo.isLimitAdTrackingEnabled();
-}</pre>
\ No newline at end of file
+}</pre>
diff --git a/docs/html/google/play-services/location.jd b/docs/html/google/play-services/location.jd
index 1cdd247..3fbf00e 100644
--- a/docs/html/google/play-services/location.jd
+++ b/docs/html/google/play-services/location.jd
@@ -1,5 +1,5 @@
 page.title=Location APIs
-page.tags="location","geofence", "geofencing", "gps"
+page.tags=location,geofence,geofencing,gps
 header.hide=1
 @jd:body
 
diff --git a/docs/html/google/play-services/maps.jd b/docs/html/google/play-services/maps.jd
index 965444a..246664e 100644
--- a/docs/html/google/play-services/maps.jd
+++ b/docs/html/google/play-services/maps.jd
@@ -1,5 +1,5 @@
 page.title=Google Maps Android API
-page.tags="mapview","location"
+page.tags=mapview,location
 header.hide=1
 
 @jd:body
@@ -88,4 +88,4 @@
     </p>
   </div>
 
-</div>
\ No newline at end of file
+</div>
diff --git a/docs/html/google/play-services/plus.jd b/docs/html/google/play-services/plus.jd
index e126dad..00b0488 100644
--- a/docs/html/google/play-services/plus.jd
+++ b/docs/html/google/play-services/plus.jd
@@ -1,5 +1,5 @@
 page.title=Google+ Platform for Android
-page.tags="authentication","signin","social"
+page.tags=authentication,signin,social
 header.hide=1
 
 @jd:body
@@ -87,4 +87,4 @@
     Google+ developer documents at <a class="external-link"
     href="https://developers.google.com/+/mobile/android/">developers.google.com/+</a>.</p>
   </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/docs/html/google/play-services/setup.jd b/docs/html/google/play-services/setup.jd
index 6553c18..5c8c63b 100644
--- a/docs/html/google/play-services/setup.jd
+++ b/docs/html/google/play-services/setup.jd
@@ -1,6 +1,24 @@
 page.title=Set Up Google Play Services SDK
 @jd:body
 
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+  <li><a href="#Install">Install the Google Play Services SDK</a></li>
+  <li><a href="#Setup">Set Up a Project that Uses Google Play Services</a></li>
+  <li><a href="#Proguard">Create a Proguard Exception</a></li>
+  <li><a href="#ensure">Ensure Devices Have the Google Play services APK</a></li>
+</ol>
+
+
+</div>
+</div>
+
+
     
 <p>To develop an app using the <a href="{@docRoot}reference/gms-packages.html">Google
 Play services APIs</a>, you must download the Google Play services SDK
@@ -10,7 +28,7 @@
 <p>To test your app when using the Google Play services SDK, you must use either:</p>
 <ul>
   <li>A compatible Android
-    device that runs Android 2.2 or higher and includes Google Play Store.</li>
+    device that runs Android 2.3 or higher and includes Google Play Store.</li>
   <li>The Android emulator with an <a href="{@docRoot}tools/devices/index.html">AVD</a>
   that runs the Google APIs platform based on Android 4.2.2 or higher.</li>
 </ul>
@@ -24,9 +42,12 @@
 <p>To install the Google Play services SDK for development:</p>
 
 <ol>
-  <li>Launch the SDK Manager.
+  <li>Launch the SDK Manager in one of the following ways:
    <ul>
-    <li>From Eclipse (with <a href="{@docRoot}tools/help/adt.html">ADT</a>),
+    <li>In Android Studio, click <strong>SDK Manager</strong>
+<img src="{@docRoot}images/tools/sdk-manager-studio.png" style="vertical-align:bottom;margin:0;height:19px" />
+in the toolbar.</li>
+    <li>In Eclipse (with <a href="{@docRoot}tools/help/adt.html">ADT</a>),
     select <strong>Window</strong> &gt; <strong>Android SDK Manager</strong>.</li>
     <li>On Windows, double-click the <code>SDK Manager.exe</code> file at the root of the Android
   SDK directory.</li>
@@ -36,19 +57,25 @@
   </li>
   <li>Install the Google Play services SDK.
     <p>Scroll to the bottom of the package list, expand <b>Extras</b>, select
-    <b>Google Play services</b>, and install it.</p>
+    <b>Google Play services</b>, and install it. If you're using Android Studio, also install
+    <b>Google Repository</b> (it provides the Maven repository used for Gradle builds).</p>
       <p>The Google Play services SDK is saved in your Android SDK environment at
       <code>&lt;android-sdk&gt;/extras/google/google_play_services/</code>.</p>
+
+<p class="note"><strong>Note:</strong> Google Play services 4.0.30 (released
+November 2013) and newer versions require Android 2.3 or higher. If your app supports Android 2.2,
+you can continue development with the Google Play services SDK, but must instead install
+<b>Google Play services for Froyo</b> from the SDK Manager.</p>
+
   </li>
   <li>Install a compatible version of the Google APIs platform.
     <p>If you want to test your app on the emulator, expand the directory for <b>Android 4.2.2
     (API 17)</b> or a higher version, select <b>Google APIs</b>, and install it. Then create a
     new <a href="{@docRoot}tools/devices/index.html">AVD</a> with Google APIs as
     the platform target.</p>
-    <p class="note"><strong>Note:</strong> Only Android 4.2.2 and higher versions of the
-    Google APIs platform include Google Play services.</p>
   </li>
   <li>Make a copy of the Google Play services library project.
+    <p class="note"><strong>Note:</strong> If you are using Android Studio, skip this step.</p>
     <p>Copy the library project at
   <code>&lt;android-sdk&gt;/extras/google/google_play_services/libproject/google-play-services_lib/</code>        
   to the location where you maintain your Android app projects.
@@ -60,23 +87,77 @@
 
 
 
-<h2 id="Setup">Set Up a Project with the Library</h2>
+<h2 id="Setup">Set Up a Project that Uses Google Play Services</h2>
 
-<p>To set up a project to use the Google Play services SDK:</p>
+<p><b>Using Android Studio:</b></p>
 
 <ol>
-  <li>Reference the library project in your Android project.
-      <p>See the 
-      <a href="{@docRoot}tools/projects/projects-eclipse.html#ReferencingLibraryProject">Referencing a Library Project for Eclipse</a>
-      or <a href="{@docRoot}tools/projects/projects-cmdline.html#ReferencingLibraryProject">Referencing a Library Project on the Command Line</a>
-      for more information on how to do this.</p>
-      <p class="note"><strong>Note:</strong>
-      You should be referencing a copy of the library that you copied to your development
-      workspace&mdash;you should not reference the library directly from the Android SDK directory.</p>
+  <li>Open the <code>build.gradle</code> file inside your application directory.</li>
+  <li>Add a new build rule under <code>dependencies</code> for the latest version of
+<code>play-services</code>. For example:
+<pre class="no-pretty-print">
+apply plugin: 'android'
+...
+
+dependencies {
+    compile 'com.android.support:appcompat-v7:+'
+    <strong>compile 'com.google.android.gms:play-services:4.0.30'</strong>
+}
+</pre>
+<p>Be sure you update this version number each time Google Play services is updated.</p>
   </li>
-  <li>If you are using <a href="{@docRoot}tools/help/proguard.html">ProGuard</a>, add the following
-      lines in the <code>&lt;project_directory&gt;/proguard-project.txt</code> file
-      to prevent ProGuard from stripping away required classes:
+  <li>Save the changes and click <strong>Sync Project with Gradle Files</strong>
+<img src="{@docRoot}images/tools/sync-project.png" style="vertical-align:bottom;margin:0;height:19px" />
+in the toolbar.
+  </li>
+  <li>Open your app's manifest file and add the following tag as a child of the <a
+href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application>}</a>
+element:
+<pre>
+&lt;meta-data android:name="com.google.android.gms.version"
+           android:value="&#64;integer/google_play_services_version" />
+</pre>
+  </li>
+</ol>
+
+<p>You can now begin developing features with the
+<a href="{@docRoot}reference/gms-packages.html">Google Play services APIs</a>.</p>
+
+
+<p><b>Using Eclipse or another IDE:</b></p>
+
+<p>To make the Google Play services APIs available to your app, you must reference the library
+project you created in step 4 of the <a href="#Install">installation instructions</a>.</p>
+<p>See the <a href="{@docRoot}tools/projects/projects-eclipse.html#ReferencingLibraryProject"
+>Referencing a Library Project for Eclipse</a> or <a
+href="{@docRoot}tools/projects/projects-cmdline.html#ReferencingLibraryProject">Referencing a
+Library Project on the Command Line</a> for more information on how to do this.</p>
+
+<p class="note"><strong>Note:</strong>
+You should be referencing a copy of the library that you copied to your development
+workspace&mdash;you should not reference the library directly from the Android SDK directory.</p>
+
+<p>After you've added the Google Play services library as a dependency for your app project,
+open your app's manifest file and add the following tag as a child of the <a
+href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application>}</a>
+element:
+<pre>
+&lt;meta-data android:name="com.google.android.gms.version"
+           android:value="&#64;integer/google_play_services_version" />
+</pre>
+
+
+<p>Once you've set up your project to reference the library project,
+you can begin developing features with the
+<a href="{@docRoot}reference/gms-packages.html">Google Play services APIs</a>.</p>
+
+
+
+<h2 id="Proguard">Create a Proguard Exception</h2>
+
+<p>To prevent <a href="{@docRoot}tools/help/proguard.html">ProGuard</a> from stripping away
+required classes, add the following lines in the
+<code>&lt;project_directory&gt;/proguard-project.txt</code> file:
 <pre>
 -keep class * extends java.util.ListResourceBundle {
     protected Object[][] getContents();
@@ -95,11 +176,13 @@
     public static final ** CREATOR;
 }
 </pre>
+
+<p class="note"><strong>Note:</strong> When using Android Studio, you must add Proguard
+to your <code>gradle.build</code> file's build types. For more information, see the
+<a href="http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Running-ProGuard"
+>Gradle Plugin User Guide</a>.
 </ol>
 
-<p>Once you have the Google Play services library project added to your app project,
-you can begin developing features with the
-<a href="{@docRoot}reference/gms-packages.html">Google Play services APIs</a>.</p>
 
 
 
@@ -191,4 +274,4 @@
   to display an error message to the user, which allows the user to download the APK
   from the Google Play Store or enable it in the device's system settings.
     </li>
-</ol>
\ No newline at end of file
+</ol>
diff --git a/docs/html/google/play-services/wallet.jd b/docs/html/google/play-services/wallet.jd
index b9b98d9..9467be1 100644
--- a/docs/html/google/play-services/wallet.jd
+++ b/docs/html/google/play-services/wallet.jd
@@ -1,5 +1,5 @@
 page.title=Google Wallet Instant Buy for Android
-page.tags="Wallet","payments","Instant Buy"
+page.tags=Wallet,payments,Instant Buy
 header.hide=1
 
 @jd:body
@@ -83,4 +83,4 @@
 
 
   </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/docs/html/google/play/billing/gp-purchase-status-api.jd b/docs/html/google/play/billing/gp-purchase-status-api.jd
index 25ef28b..8db7133 100644
--- a/docs/html/google/play/billing/gp-purchase-status-api.jd
+++ b/docs/html/google/play/billing/gp-purchase-status-api.jd
@@ -1,5 +1,5 @@
 page.title=Purchase Status API
-page.tags="In-app Billing", "Google Play", "inapp billing", "in app billing", "iab", "billing"
+page.tags=In-app Billing,Google Play,inapp billing,in app billing,iab,billing
 
 @jd:body
 
@@ -58,7 +58,7 @@
 
 <p>The Purchase Status API is part of the <a
 href="https://developers.google.com/android-publisher/v1_1/">Google Play Android
-Developer API v1.1</a>, available through the Google APIs console. The new version
+Developer API v1.1</a>, available through the Google Cloud Console. The new version
 of the API supersedes the v1 API, which is deprecated. If you are using the v1
 API, please migrate your operations to the v1.1 API as soon as possible.</p>
 
@@ -66,7 +66,7 @@
 <h2 id="using">Using the API</h2>
 
 <p>To use the API, you must first register a project at the <a
-href="https://code.google.com/apis/console">Google APIs Console</a> and receive
+href="https://cloud.google.com/console">Google Cloud Console</a> and receive
 a Client ID and shared secret that  your app will present when calling the
 API. All calls are authenticated with OAuth 2.0.</p>
 
@@ -93,9 +93,9 @@
 subscription-validation needs, assuming that you follow the recommendation in
 this section.</p>
 
-<p>If you need to request a higher limit for your application, please use the
-“Request more” link in the <a
-href="https://code.google.com/apis/console/#:quotas">Google APIs Console</a>.
+<p>If you need to request a higher limit for your application, see the
+instructions in the <a
+href="https://developers.google.com/console/help/new/#trafficcontrols">Google Cloud Console Help</a>.
 Also, please read the section below on design best practices for minimizing your
 use of the API.</p>
 
diff --git a/docs/html/guide/appendix/media-formats.jd b/docs/html/guide/appendix/media-formats.jd
index 7c6c145..19f510a 100644
--- a/docs/html/guide/appendix/media-formats.jd
+++ b/docs/html/guide/appendix/media-formats.jd
@@ -1,5 +1,5 @@
 page.title=Supported Media Formats
-page.tags="video","audio","mpeg","mp4","m4a","mp3","3gp","3gpp","flac","wave","wav"
+page.tags=video,audio,mpeg,mp4,m4a,mp3,3gp,3gpp,flac,wave,wav
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/components/activities.jd b/docs/html/guide/components/activities.jd
index 1cbaa79..b4617fb 100644
--- a/docs/html/guide/components/activities.jd
+++ b/docs/html/guide/components/activities.jd
@@ -1,5 +1,5 @@
 page.title=Activities
-page.tags="activity","intent"
+page.tags=activity,intent
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/components/processes-and-threads.jd b/docs/html/guide/components/processes-and-threads.jd
index 1fed712..c8c3764 100644
--- a/docs/html/guide/components/processes-and-threads.jd
+++ b/docs/html/guide/components/processes-and-threads.jd
@@ -1,5 +1,5 @@
 page.title=Processes and Threads
-page.tags="lifecycle","background"
+page.tags=lifecycle,background
 
 @jd:body
 
diff --git a/docs/html/guide/faq/security.jd b/docs/html/guide/faq/security.jd
index 96fc7f5..8ccf21f 100644
--- a/docs/html/guide/faq/security.jd
+++ b/docs/html/guide/faq/security.jd
@@ -47,8 +47,7 @@
 <a name="issue" id="issue"></a><h2>I think I found a security flaw. How do I
 report it?</h2>
 
-<p>You can reach the Android security team at <a
-href="mailto:security@android.com">security@android.com</a>. If you like, you
+<p>You can reach the Android security team at security@android.com. If you like, you
 can protect your message using our <a
 href="http://code.google.com/android/security_at_android_dot_com.txt">PGP
 key</a>.</p>
@@ -58,6 +57,15 @@
 users are at risk. In return, we will make sure to keep the researcher informed
 of our progress in issuing a fix. </p>
 
+<p>Vulnerabilities specific to Android OEMs should be reported to the relevant
+vendor. An incomplete list of Android vendor security contacts can be found below.
+To be added to this list, please contact security@android.com.</p>
+
+<ul>
+  <li><a href="http://www.htc.com/www/terms/product-security/">HTC</a></li>
+  <li><a href="http://www.motorolasolutions.com/US-EN/About/Security%20Vulnerability">Motorola</a></li>
+  <li><a href="http://developer.samsung.com/notice/How-to-Use-the-Forum">Samsung</a> - m.security@samsung.com</li>
+</ul>
 
 <a name="informed" id="informed"></a><h2>How can I stay informed about Android security?</h2>
 
@@ -91,8 +99,8 @@
 <p>Like any other platform, it will be possible for unethical developers
 to create malicious software, known as <a
 href="http://en.wikipedia.org/wiki/Malware">malware</a>, for Android. If you
-think somebody is trying to spread malware, please let us know at <a
-href="mailto:security@android.com">security@android.com</a>. Please include as
+think somebody is trying to spread malware, please let us know at
+security@android.com. Please include as
 much detail about the application as possible, with the location it is
 being distributed from and why you suspect it of being malicious software.</p>
 
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 84ffd05..8f2795a 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -490,11 +490,8 @@
     <span class="en">Web Apps</span>
     </a></div>
     <ul>
-      <li><a href="<?cs var:toroot ?>guide/webapps/overview.html">
-            <span class="en">Overview</span>
-          </a></li>
       <li><a href="<?cs var:toroot ?>guide/webapps/targeting.html">
-            <span class="en">Targeting Screens from Web Apps</span>
+            <span class="en">Supporting Different Screens in Web Apps</span>
           </a></li>
       <li><a href="<?cs var:toroot ?>guide/webapps/webview.html">
             <span class="en">Building Web Apps in WebView</span>
diff --git a/docs/html/guide/topics/admin/device-admin.jd b/docs/html/guide/topics/admin/device-admin.jd
index a474498..ee6b814 100644
--- a/docs/html/guide/topics/admin/device-admin.jd
+++ b/docs/html/guide/topics/admin/device-admin.jd
@@ -1,5 +1,5 @@
 page.title=Device Administration
-page.tags="devicepolicymanager","policy","security"
+page.tags=devicepolicymanager,policy,security
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/appwidgets/host.jd b/docs/html/guide/topics/appwidgets/host.jd
index da7408f..169e388 100644
--- a/docs/html/guide/topics/appwidgets/host.jd
+++ b/docs/html/guide/topics/appwidgets/host.jd
@@ -1,5 +1,5 @@
 page.title=App Widget Host
-page.tags="AppWidgetHost","home screen","launcher"
+page.tags=AppWidgetHost,home screen,launcher
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd
index d8ad844..a783ad1 100644
--- a/docs/html/guide/topics/appwidgets/index.jd
+++ b/docs/html/guide/topics/appwidgets/index.jd
@@ -1,5 +1,5 @@
 page.title=App Widgets
-page.tags="home","AppWidgetProvider"
+page.tags=home,AppWidgetProvider
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/connectivity/bluetooth-le.jd b/docs/html/guide/topics/connectivity/bluetooth-le.jd
index 21950c2..5c32e56 100644
--- a/docs/html/guide/topics/connectivity/bluetooth-le.jd
+++ b/docs/html/guide/topics/connectivity/bluetooth-le.jd
@@ -1,5 +1,5 @@
 page.title=Bluetooth Low Energy
-page.tags="wireless","bluetoothadapter","bluetoothdevice","BLE","BTLE"
+page.tags=wireless,bluetoothadapter,bluetoothdevice,BLE,BTLE
 @jd:body
 
 <div id="qv-wrapper">
@@ -44,6 +44,15 @@
 </div>
 </div>
 
+<a class="notice-developers-video" href="http://www.youtube.com/watch?v=vUbFB1Qypg8">
+<div>
+    <h3>Video</h3>
+    <p>DevBytes: Bluetooth Low Energy API</p>
+</div>
+</a>
+
+
+
 
 <p>
 Android 4.3 (API Level 18) introduces built-in platform support for Bluetooth Low
diff --git a/docs/html/guide/topics/connectivity/bluetooth.jd b/docs/html/guide/topics/connectivity/bluetooth.jd
index b57f3e2..96008c5 100644
--- a/docs/html/guide/topics/connectivity/bluetooth.jd
+++ b/docs/html/guide/topics/connectivity/bluetooth.jd
@@ -1,5 +1,5 @@
 page.title=Bluetooth
-page.tags="wireless","bluetoothadapter","bluetoothdevice"
+page.tags=wireless,bluetoothadapter,bluetoothdevice
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/connectivity/nfc/hce.jd b/docs/html/guide/topics/connectivity/nfc/hce.jd
index d9063f3..76f7c7c 100644
--- a/docs/html/guide/topics/connectivity/nfc/hce.jd
+++ b/docs/html/guide/topics/connectivity/nfc/hce.jd
@@ -1,5 +1,5 @@
 page.title=Host-based Card Emulation
-page.tags="host card emulation", "hce","HostApduService","OffHostApduService","tap and pay"
+page.tags=host card emulation,hce,HostApduService,OffHostApduService,tap and pay
 
 @jd:body
 
@@ -70,7 +70,7 @@
 works.</p>
 
 <img src="{@docRoot}images/nfc/host-based-card.png" />
-<p class="img-caption"><strong>Figure 2.</strong> NFC card emulation with a secure element.</p>
+<p class="img-caption"><strong>Figure 2.</strong> NFC card emulation without a secure element.</p>
 
 
 <h2 id="SupportedProtocols">Supported NFC Cards and Protocols</h2>
@@ -178,7 +178,7 @@
 
 <p>Your application can check whether a device supports HCE by checking for the 
 {@link android.content.pm.PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} feature. You should use the 
-{@code &lt;uses-feature>} tag in the manifest of your application to declare that your app 
+<a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code &lt;uses-feature>}</a> tag in the manifest of your application to declare that your app 
 uses the HCE feature, and whether it is required for the app to function or not.</p>
 
 <h3 id="ServiceImplementation">Service implementation</h3>
@@ -288,12 +288,12 @@
 
 <pre>
 &lt;service android:name=".MyHostApduService" android:exported="true"
-        android:permission="android.permission.BIND_NFC_SERVICE">
+         android:permission="android.permission.BIND_NFC_SERVICE">
     &lt;intent-filter>
         &lt;action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
     &lt;/intent-filter>
     &lt;meta-data android:name="android.nfc.cardemulation.host_apdu_service"
-        android:resource="@xml/apduservice"/>
+               android:resource="@xml/apduservice"/>
 &lt;/service>
 </pre>
 
@@ -306,7 +306,7 @@
            android:description="@string/servicedesc" 
            android:requireDeviceUnlock="false">
     &lt;aid-group android:description="@string/aiddescription" 
-                android:category="other">
+               android:category="other">
         &lt;aid-filter android:name="F0010203040506"/>
         &lt;aid-filter android:name="F0394148148100"/>
     &lt;/aid-group>
@@ -381,14 +381,14 @@
 
 <pre>
 &lt;host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
-           android:description="@string/servicedesc" 
-           android:requireDeviceUnlock="false"
-           android:apduServiceBanner="@drawable/my_banner">
-       &lt;aid-group android:description="@string/aiddescription"
-                  android:category="payment">
-           &lt;aid-filter android:name="F0010203040506"/>
-           &lt;aid-filter android:name="F0394148148100"/>
-       &lt;/aid-group>
+        android:description="@string/servicedesc" 
+        android:requireDeviceUnlock="false"
+        android:apduServiceBanner="@drawable/my_banner">
+    &lt;aid-group android:description="@string/aiddescription"
+               android:category="payment">
+        &lt;aid-filter android:name="F0010203040506"/>
+        &lt;aid-filter android:name="F0394148148100"/>
+    &lt;/aid-group>
 &lt;/host-apdu-service>
 </pre>
 
@@ -478,12 +478,12 @@
 
 <pre>
 &lt;service android:name=".MyOffHostApduService" android:exported="true"
-     android:permission="android.permission.BIND_NFC_SERVICE">
+         android:permission="android.permission.BIND_NFC_SERVICE">
     &lt;intent-filter>
         &lt;action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/>
     &lt;/intent-filter>
     &lt;meta-data android:name="android.nfc.cardemulation.off_host_apdu_ervice"
-         android:resource="@xml/apduservice"/>
+               android:resource="@xml/apduservice"/>
 &lt;/service>
 </pre>
 </li>
diff --git a/docs/html/guide/topics/connectivity/sip.jd b/docs/html/guide/topics/connectivity/sip.jd
index 526eb83..5154767 100644
--- a/docs/html/guide/topics/connectivity/sip.jd
+++ b/docs/html/guide/topics/connectivity/sip.jd
@@ -1,5 +1,5 @@
 page.title=Session Initiation Protocol
-page.tags="sipmanager","sipprofile","sipaudiocall","telephony"
+page.tags=sipmanager,sipprofile,sipaudiocall,telephony
 @jd:body
 <div id="qv-wrapper">
 <div id="qv">
diff --git a/docs/html/guide/topics/connectivity/wifip2p.jd b/docs/html/guide/topics/connectivity/wifip2p.jd
index 7cadde1..d7e1269 100644
--- a/docs/html/guide/topics/connectivity/wifip2p.jd
+++ b/docs/html/guide/topics/connectivity/wifip2p.jd
@@ -1,5 +1,5 @@
 page.title=Wi-Fi Peer-to-Peer
-page.tags="wireless","WifiP2pManager","Wi-Fi Direct","WiFi Direct","P2P","Wi-Fi P2P","WiFi P2P"
+page.tags=wireless,WifiP2pManager,Wi-Fi Direct,WiFi Direct,P2P,Wi-Fi P2P,WiFi P2P
 
 @jd:body
 
diff --git a/docs/html/guide/topics/data/data-storage.jd b/docs/html/guide/topics/data/data-storage.jd
index 385c116..6fca02f0 100644
--- a/docs/html/guide/topics/data/data-storage.jd
+++ b/docs/html/guide/topics/data/data-storage.jd
@@ -1,5 +1,5 @@
 page.title=Storage Options
-page.tags="database","sharedpreferences","sdcard"
+page.tags=database,sharedpreferences,sdcard
 @jd:body
 
 
diff --git a/docs/html/guide/topics/data/install-location.jd b/docs/html/guide/topics/data/install-location.jd
index 2ec0d5a..cc58b46 100644
--- a/docs/html/guide/topics/data/install-location.jd
+++ b/docs/html/guide/topics/data/install-location.jd
@@ -1,5 +1,5 @@
 page.title=App Install Location
-page.tags="sdcard","external"
+page.tags=sdcard,external
 @jd:body
 
 
diff --git a/docs/html/guide/topics/graphics/opengl.jd b/docs/html/guide/topics/graphics/opengl.jd
index f46113d..d194082 100644
--- a/docs/html/guide/topics/graphics/opengl.jd
+++ b/docs/html/guide/topics/graphics/opengl.jd
@@ -1,5 +1,5 @@
 page.title=OpenGL ES
-page.tags="games"
+page.tags=games
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/graphics/prop-animation.jd b/docs/html/guide/topics/graphics/prop-animation.jd
index 22bf7696..e455496 100644
--- a/docs/html/guide/topics/graphics/prop-animation.jd
+++ b/docs/html/guide/topics/graphics/prop-animation.jd
@@ -1,5 +1,5 @@
 page.title=Property Animation
-page.tags="valueanimator","objectanimator","layouttransition","ViewPropertyAnimator"
+page.tags=valueanimator,objectanimator,layouttransition,ViewPropertyAnimator
 @jd:body
 
   <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/manifest/uses-configuration-element.jd b/docs/html/guide/topics/manifest/uses-configuration-element.jd
index 810975e..e9a0ba4 100644
--- a/docs/html/guide/topics/manifest/uses-configuration-element.jd
+++ b/docs/html/guide/topics/manifest/uses-configuration-element.jd
@@ -6,18 +6,18 @@
 <!-- ##api level 3##  see comment below -->
 
 <!-- the "no___" values are nonsensical if they mean "doesn't work on devices with a
-keyboard / navigation control / touch screen."  Dianne says that that's what they mean and 
-that they therefore should be eliminated.  Suchi says that they mean "doesn't require a 
+keyboard / navigation control / touch screen."  Dianne says that that's what they mean and
+that they therefore should be eliminated.  Suchi says that they mean "doesn't require a
 keyboard / navigation control / touch screen to work."  But then what does "undefined" mean?
 Seems like some API change is in the works, either eliminating the "no___" values or
-"undefined".  Since it's unclear what the change will be, I've chosen to document the "no___" 
+"undefined".  Since it's unclear what the change will be, I've chosen to document the "no___"
 and "undefined" attributes using the same language, which is surely wrong but may make it
-easier to update the doc when the change is made. -->
+easier to update the doc when the change is made... Nov 2013, this still seems unresolved. -->
 
 <dl class="xml">
 <dt>syntax:</dt>
 <dd><pre class="stx">&lt;uses-configuration
-  android:<a href="#five">reqFiveWayNav</a>=["true" | "false"] 
+  android:<a href="#five">reqFiveWayNav</a>=["true" | "false"]
   android:<a href="#hard">reqHardKeyboard</a>=["true" | "false"]
   android:<a href="#kbd">reqKeyboardType</a>=["undefined" | "nokeys" | "qwerty" | "twelvekey"]
   android:<a href="#nav">reqNavigation</a>=["undefined" | "nonav" | "dpad" | "trackball" | "wheel"]
@@ -27,38 +27,35 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Indicates what hardware and software features the application requires.  
-For example, an application might specify that it requires a physical keyboard 
+<dd>Indicates what hardware and software features the application requires.
+For example, an application might specify that it requires a physical keyboard
 or a particular navigation device, like a trackball.  The specification is
 used to avoid installing the application on devices where it will not work.
 
-<p>
-If an application can work with different device configurations, it 
-should include separate {@code &lt;uses-configuration&gt;} declarations for 
-each one.  Each declaration must be complete.  For example, if an application 
-requires a five-way navigation control, a touch screen that can be operated 
-with a finger, and either a standard QWERTY keyboard or a numeric 12-key
-keypad like those found on most phones, it would specify these requirements
-with two {@code &lt;uses-configuration&gt;} elements as follows:
-</p>
+<p class="note"><strong>Note: Most apps should not use this manifest tag.</strong> You should
+<em>always</em> support input with a directional pad (d-pad) in order to assist sight-impaired
+users and support devices that provide d-pad input in addition to or instead of touch. For
+information about how to support d-pad input in your app, read <a href=
+"{@docRoot}guide/topics/ui/accessibility/apps.html#focus-nav">Enabling Focus Navigation</a>. If
+your app absolutely cannot function without a touchscreen, then instead use the <a href=
+"{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code &lt;uses-feature&gt;}</a> tag to
+declare the required touchscreen type, ranging from {@code "android.hardware.faketouch"} for basic
+touch-style events to more advanced touch types such as {@code
+"android.hardware.touchscreen.multitouch.jazzhand"} for distinct input from multiple fingers.</p>
 
-<pre>&lt;uses-configuration android:reqFiveWayNav="true" android:reqTouchScreen="finger"
-                    android:reqKeyboardType="qwerty" /&gt;
-&lt;uses-configuration android:reqFiveWayNav="true" android:reqTouchScreen="finger"
-                    android:reqKeyboardType="twelvekey" /&gt;</pre></dd>
 
 <dt>attributes:</dt>
 <dd><dl class="attr">
 <dt><a name="five"></a>{@code android:reqFiveWayNav}</dt>
-<dd>Whether or not the application requires a five-way navigation control 
+<dd>Whether or not the application requires a five-way navigation control
 &mdash; "{@code true}" if it does, and "{@code false}" if not.  A five-way
-control is one that can move the selection up, down, right, or left, and 
-also provides a way of invoking the current selection.  It could be a 
-D-pad (directional pad), trackball, or other device.  
+control is one that can move the selection up, down, right, or left, and
+also provides a way of invoking the current selection.  It could be a
+D-pad (directional pad), trackball, or other device.
 
 <p>
 If an application requires a directional control, but not a control of a
-particular type, it can set this attribute to "{@code true}" and ignore 
+particular type, it can set this attribute to "{@code true}" and ignore
 the <code><a href="#nav">reqNavigation</a></code> attribute.  However,
 if it requires a particular type of directional control, it can ignore
 this attribute and set {@code reqNavigation} instead.
@@ -69,10 +66,10 @@
 "{@code true}" if it does, and "{@code false}" if not.</dd>
 
 <dt><a name="kbd"></a>{@code android:reqKeyboardType}</dt>
-<dd>The type of keyboard the application requires, if any at all. 
-This attribute does not distinguish between hardware and software 
+<dd>The type of keyboard the application requires, if any at all.
+This attribute does not distinguish between hardware and software
 keyboards.  If a hardware keyboard of a certain type is required,
-specify the type here and also set the {@code reqHardKeyboard} attribute 
+specify the type here and also set the {@code reqHardKeyboard} attribute
 to "{@code true}".
 
 <p>
@@ -85,8 +82,8 @@
    <th>Description</th>
 </tr><tr>
    <td>"{@code undefined}"</td>
-   <td>The application does not require a keyboard. 
-       (A keyboard requirement is not defined.)  
+   <td>The application does not require a keyboard.
+       (A keyboard requirement is not defined.)
        This is the default value.</td>
 </tr><tr>
    <td>"{@code nokeys}"</td>
@@ -96,14 +93,14 @@
    <td>The application requires a standard QWERTY keyboard.</td>
 </tr><tr>
    <td>"{@code twelvekey}"</td>
-   <td>The application requires a twelve-key keypad, like those on most 
-       phones &mdash; with keys for the digits from {@code 0} through 
+   <td>The application requires a twelve-key keypad, like those on most
+       phones &mdash; with keys for the digits from {@code 0} through
        {@code 9} plus star ({@code *}) and pound ({@code #}) keys.</td>
 </tr>
 </table></dd>
 
 <dt><a name="nav"></a>{@code android:reqNavigation}</dt>
-<dd>The navigation device required by the application, if any.  The value 
+<dd>The navigation device required by the application, if any.  The value
 must be one of the following strings:
 
 <table>
@@ -112,8 +109,8 @@
    <th>Description</th>
 </tr><tr>
    <td>"{@code undefined}"</td>
-   <td>The application does not require any type of navigation control. 
-       (The navigation requirement is not defined.)  
+   <td>The application does not require any type of navigation control.
+       (The navigation requirement is not defined.)
        This is the default value.</td>
 </tr><tr>
    <td>"{@code nonav}"</td>
@@ -132,14 +129,14 @@
 
 <p>
 If an application requires a navigational control, but the exact type of
-control doesn't matter, it can set the 
+control doesn't matter, it can set the
 <code><a href="#five">reqFiveWayNav</a></code> attribute to "{@code true}"
 rather than set this one.
 </p></dd>
 
 <dt><a name="touch"></a>{@code android:reqTouchScreen}</dt>
 <dd>The type of touch screen the application requires, if any at all.
-The value must be one of the following strings: 
+The value must be one of the following strings:
 
 <table>
 <tr>
@@ -147,7 +144,7 @@
    <th>Description</th>
 </tr><tr>
    <td>"{@code undefined}"</td>
-   <td>The application doesn't require a touch screen.  
+   <td>The application doesn't require a touch screen.
        (The touch screen requirement is undefined.)
        This is the default value.</td>
 </tr><tr>
@@ -158,7 +155,14 @@
    <td>The application requires a touch screen that's operated with a stylus.</td>
 </tr><tr>
    <td>"{@code finger}"</td>
-   <td>The application requires a touch screen that can be operated with a finger.</td>
+   <td>The application requires a touch screen that can be operated with a finger.
+
+      <p class="note"><strong>Note:</strong> If some type of touch input is required for your app,
+      you should instead use the
+      <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code
+      &lt;uses-feature>}</a> tag to declare the required touchscreen
+      type, beginning with {@code "android.hardware.faketouch"} for basic touch-style events.</p>
+   </td>
 </tr>
 </table></dd>
 </dl></dd>
@@ -172,7 +176,7 @@
   <ul>
     <li><code><a href="{@docRoot}guide/topics/manifest/activity-element.html#config">configChanges</a></code>
 attribute of the
-<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code> 
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
 element</dd></li>
     <li>{@link android.content.pm.ConfigurationInfo}</li>
   </ul>
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index 95f62a5..445d5ce 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -1,5 +1,5 @@
 page.title=&lt;uses-feature&gt;
-page.tags="filtering","features","google play filters","permissions"
+page.tags=filtering,features,google play filters,permissions
 @jd:body
 
 <div id="qv-wrapper">
@@ -1071,4 +1071,4 @@
   <td><code>android.hardware.wifi</code></td>
 <!--  <td></td> -->
 </tr>
-</table>
\ No newline at end of file
+</table>
diff --git a/docs/html/guide/topics/manifest/uses-permission-element.jd b/docs/html/guide/topics/manifest/uses-permission-element.jd
index 8e9e795..bd7091e 100644
--- a/docs/html/guide/topics/manifest/uses-permission-element.jd
+++ b/docs/html/guide/topics/manifest/uses-permission-element.jd
@@ -35,7 +35,8 @@
 </div>
 
 <dt>syntax:</dt>
-<dd><pre class="stx">&lt;uses-permission android:<a href="#nm">name</a>="<i>string</i>" /&gt;</pre></dd>
+<dd><pre class="stx">&lt;uses-permission android:<a href="#nm">name</a>="<i>string</i>"
+        android:<a href="#maxSdk">maxSdkVersion</a>="<i>integer</i>" /&gt;</pre></dd>
 
 <dt>contained in:</dt>
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
@@ -63,6 +64,25 @@
 or "{@code android.permission.READ_CONTACTS}".  As these examples show, 
 a permission name typically includes the package name as a prefix.</dd>
 
+<dt><a name="maxSdk"></a>{@code android:maxSdkVersion}</dt>
+<dd>The highest API level at which this permission should be granted to your app.
+Setting this attribute is useful if the permission your app requires is no longer needed beginning
+at a certain API level.
+<p>For example, beginning with Android 4.4 (API level 19), it's no longer necessary for your app
+to request the {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission when your
+app wants to write to its own application-specific directories on external storage (the directories
+provided by {@link android.content.Context#getExternalFilesDir getExternalFilesDir()}). However,
+the permission <em>is required</em> for API level 18 and lower. So you can declare that this
+permission is needed only up to API level 18 with a declaration such as this:
+<pre>
+&lt;uses-permission
+     android:name="android.permission.WRITE_EXTERNAL_STORAGE"
+     android:maxSdkVersion="18" />
+</pre>
+<p>This way, beginning with API level 19, the system will no longer grant your app the
+{@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission.</p>
+</dd>
+
 </dl></dd>
 
 <!-- ##api level indication## -->
diff --git a/docs/html/guide/topics/manifest/uses-sdk-element.jd b/docs/html/guide/topics/manifest/uses-sdk-element.jd
index 9169658..dd5ea86 100644
--- a/docs/html/guide/topics/manifest/uses-sdk-element.jd
+++ b/docs/html/guide/topics/manifest/uses-sdk-element.jd
@@ -1,5 +1,5 @@
 page.title=&lt;uses-sdk&gt;
-page.tags="api levels","sdk version","minsdkversion","targetsdkversion","maxsdkversion"
+page.tags=api levels,sdk version,minsdkversion,targetsdkversion,maxsdkversion
 @jd:body
 
 
diff --git a/docs/html/guide/topics/media/audio-capture.jd b/docs/html/guide/topics/media/audio-capture.jd
index 44c618f..8e60c8f 100644
--- a/docs/html/guide/topics/media/audio-capture.jd
+++ b/docs/html/guide/topics/media/audio-capture.jd
@@ -1,5 +1,5 @@
 page.title=Audio Capture
-page.tags="mediarecorder"
+page.tags=mediarecorder
 @jd:body
 
     <div id="qv-wrapper">
@@ -249,4 +249,4 @@
         }
     }
 }
-</pre>
\ No newline at end of file
+</pre>
diff --git a/docs/html/guide/topics/media/camera.jd b/docs/html/guide/topics/media/camera.jd
index e48109a..56ef624 100644
--- a/docs/html/guide/topics/media/camera.jd
+++ b/docs/html/guide/topics/media/camera.jd
@@ -1,5 +1,5 @@
 page.title=Camera
-page.tags="photo","video","picture","mediarecorder"
+page.tags=photo,video,picture,mediarecorder
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/media/mediaplayer.jd b/docs/html/guide/topics/media/mediaplayer.jd
index fb272d2..63c04a2 100644
--- a/docs/html/guide/topics/media/mediaplayer.jd
+++ b/docs/html/guide/topics/media/mediaplayer.jd
@@ -1,5 +1,5 @@
 page.title=Media Playback
-page.tags="mediaplayer","soundpool","audiomanager"
+page.tags=mediaplayer,soundpool,audiomanager
 @jd:body
 
     <div id="qv-wrapper">
@@ -743,4 +743,4 @@
 mMediaPlayer.setDataSource(getApplicationContext(), contentUri);
 
 // ...prepare and start...
-</pre>
\ No newline at end of file
+</pre>
diff --git a/docs/html/guide/topics/providers/document-provider.jd b/docs/html/guide/topics/providers/document-provider.jd
index 9af8d5a..cd1fd1a 100644
--- a/docs/html/guide/topics/providers/document-provider.jd
+++ b/docs/html/guide/topics/providers/document-provider.jd
@@ -3,8 +3,11 @@
 <div id="qv-wrapper">
 <div id="qv">
 
-<h2>In this document</h2>
-<ol>
+<h2>In this document
+ <a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
+        <span class="more">show more</span>
+        <span class="less" style="display:none">show less</span></a></h2>
+<ol id="toc44" class="hide-nested">
     <li>
         <a href="#overview">Overview</a>
     </li>
@@ -38,8 +41,25 @@
 <ol>
     <li>{@link android.provider.DocumentsProvider}</li>
     <li>{@link android.provider.DocumentsContract}</li>
-    <li>{@link android.provider.DocumentsContract.Document}</li>
-    <li>{@link android.provider.DocumentsContract.Root}</li>
+</ol>
+
+<h2>Videos</h2>
+
+<ol>
+    <li><a href="http://www.youtube.com/watch?v=zxHVeXbK1P4">
+DevBytes: Android 4.4 Storage Access Framework: Provider</a></li>
+     <li><a href="http://www.youtube.com/watch?v=UFj9AEz0DHQ">
+DevBytes: Android 4.4 Storage Access Framework: Client</a></li>
+</ol>
+
+
+<h2>Code Samples</h2>
+
+<ol>
+    <li><a href="{@docRoot}samples/StorageProvider/index.html">
+Storage Provider</a></li>
+     <li><a href="{@docRoot}samples/StorageClient/index.html">
+StorageClient</a></li>
 </ol>
 
 <h2>See Also</h2>
@@ -50,18 +70,28 @@
         </a>
     </li>
 </ol>
+
 </div>
 </div>
-<p>Android 4.4 (API level 19) introduces the Storage Access Framework. The
-Storage Access Framework encapsulates capabilities in the Android platform that
-allow apps to request files from file storage services. The Storage Access
-Framework includes the following:</p>
+
+
+<p>Android 4.4 (API level 19) introduces the Storage Access Framework (SAF). The SAF
+ makes it simple for users to browse and open documents, images, and other files
+across all of their their preferred document storage providers. A standard, easy-to-use UI
+lets users browse files and access recents in a consistent way across apps and providers.</p>
+
+<p>Cloud or local storage services can participate in this ecosystem by implementing a new
+{@link android.provider.DocumentsProvider} that encapsulates their services. Client
+apps that need access to a provider's documents can integrate with the SAF with just a few
+lines of code.</p>
+
+<p>The SAF includes the following:</p>
 
 <ul>
 <li><strong>Document provider</strong>&mdash;A content provider that allows a
-storage service (such as Google Drive) to reveal the files it manages. This is
+storage service (such as Google Drive) to reveal the files it manages. A document provider is
 implemented as a subclass of the {@link android.provider.DocumentsProvider} class.
-The document provider schema is based on a traditional file hierarchy,
+The document-provider schema is based on a traditional file hierarchy,
 though how your document provider physically stores data is up to you.
 The Android platform includes several built-in document providers, such as
 Downloads, Images, and Videos.</li>
@@ -75,7 +105,7 @@
 document providers that satisfy the client app's search criteria.</li>
 </ul>
 
-<p>Some of the features offered by the Storage Access Framework are as follows:</p>
+<p>Some of the features offered by the SAF are as follows:</p>
 <ul>
 <li>Lets users browse content from all document providers, not just a single app.</li>
 <li>Makes it possible for your app to have long term, persistent access to
@@ -87,7 +117,7 @@
 
 <h2 id ="overview">Overview</h2>
 
-<p>The Storage Access Framework centers around a content provider that is a
+<p>The SAF centers around a content provider that is a
 subclass of the {@link android.provider.DocumentsProvider} class. Within a <em>document provider</em>, data is
 structured as a traditional file hierarchy:</p>
 <p><img src="{@docRoot}images/providers/storage_datamodel.png" alt="data model" /></p>
@@ -134,7 +164,7 @@
 long as it can be accessed through the {@link android.provider.DocumentsProvider} API. For example, you
 could use tag-based cloud storage for your data.</p>
 
-<p>Figure 2 shows an example of how a photo app might use the Storage Access Framework
+<p>Figure 2 shows an example of how a photo app might use the SAF
 to access  stored data:</p>
 <p><img src="{@docRoot}images/providers/storage_dataflow.png" alt="app" /></p>
 
@@ -143,7 +173,7 @@
 <p>Note the following:</p>
 <ul>
 
-<li>In the Storage Access Framework, providers and clients don't interact
+<li>In the SAF, providers and clients don't interact
 directly. A client requests permission to interact
 with files (that is, to read, edit, create, or delete files).</li>
 
@@ -430,7 +460,7 @@
 
 <h3 id="edit">Edit a document</h3>
 
-<p>You can use the Storage Access Framework to edit a text document in place.
+<p>You can use the SAF to edit a text document in place.
 This snippet fires
 the {@link android.content.Intent#ACTION_OPEN_DOCUMENT} intent and uses the
 category {@link android.content.Intent#CATEGORY_OPENABLE} to to display only
@@ -513,8 +543,8 @@
 
 <p>
 If you're developing an app that provides storage services for files (such as
-a cloud save service), you can make your files available through the Storage
-Access Framework by writing a custom document provider.  This section describes
+a cloud save service), you can make your files available through the
+SAF by writing a custom document provider.  This section describes
 how to do this.</p>
 
 
@@ -540,13 +570,25 @@
 You must export your provider so that other apps can see it.</li>
 
 <li>The attribute <code>android:grantUriPermissions</code> set to
-<code>&quot;true&quot;</code>. This allows the system to grant other apps access
+<code>&quot;true&quot;</code>. This setting allows the system to grant other apps access
 to content in your provider. For a discussion of how to persist a grant for
 a particular document, see <a href="#permissions">Persist permissions</a>.</li>
 
 <li>The {@code MANAGE_DOCUMENTS} permission. By default a provider is available
-to everyone. Adding this permission restricts your provider to the system,
-which is important for security. </li>
+to everyone. Adding this permission restricts your provider to the system.
+This restriction is important for security.</li>
+
+<li>The {@code android:enabled} attribute set to a boolean value defined in a resource
+file. The purpose of this attribute is to disable the provider on devices running Android 4.3 or lower.
+For example, {@code android:enabled=&quot;&#64;bool/atLeastKitKat&quot;}. In
+addition to including this attribute in the manifest, you need to do the following:
+<ul>
+<li>In your {@code bool.xml} resources file under {@code res/values/}, add
+this line: <pre>&lt;bool name=&quot;atLeastKitKat&quot;&gt;false&lt;/bool&gt;</pre></li>
+
+<li>In your {@code bool.xml} resources file under {@code res/values-v19/}, add
+this line: <pre>&lt;bool name=&quot;atLeastKitKat&quot;&gt;true&lt;/bool&gt;</pre></li>
+</ul></li>
 
 <li>An intent filter that includes the
 {@code android.content.action.DOCUMENTS_PROVIDER} action, so that your provider
@@ -566,7 +608,8 @@
             android:authorities=&quot;com.example.android.storageprovider.documents&quot;
             android:grantUriPermissions=&quot;true&quot;
             android:exported=&quot;true&quot;
-            android:permission=&quot;android.permission.MANAGE_DOCUMENTS&quot;&gt;
+            android:permission=&quot;android.permission.MANAGE_DOCUMENTS&quot;
+            android:enabled=&quot;&#64;bool/atLeastKitKat&quot;&gt;
             &lt;intent-filter&gt;
                 &lt;action android:name=&quot;android.content.action.DOCUMENTS_PROVIDER&quot; /&gt;
             &lt;/intent-filter&gt;
@@ -575,7 +618,7 @@
 
 &lt;/manifest&gt;</pre>
 
-<h4>Supporting devices running Android 4.3 and lower</h4>
+<h4 id="43">Supporting devices running Android 4.3 and lower</h4>
 
 <p>The
 {@link android.content.Intent#ACTION_OPEN_DOCUMENT} intent is only available
@@ -583,7 +626,7 @@
 If you want your application to support {@link android.content.Intent#ACTION_GET_CONTENT}
 to accommodate devices that are running Android 4.3 and lower, you should
 disable the {@link android.content.Intent#ACTION_GET_CONTENT} intent filter in
-your manifest if a device is running Android 4.4 or higher. A
+your manifest for devices running Android 4.4 or higher. A
 document provider and {@link android.content.Intent#ACTION_GET_CONTENT} should be considered
  mutually exclusive. If you support both of them simultaneously, your app will
 appear twice in the system picker UI, offering two different ways of accessing
@@ -630,7 +673,7 @@
 <a href="{@docRoot}guide/topics/providers/content-provider-creating.html#ContractClass">
 Content Providers</a> developers guide. A contract class is a {@code public final} class
 that contains constant definitions for the URIs, column names, MIME types, and
-other metadata that pertain to the provider. The Storage Access Framework
+other metadata that pertain to the provider. The SAF
 provides these contract classes for you, so you don't need to write your
 own:</p>
 
@@ -872,4 +915,4 @@
     getContentResolver().notifyChange(DocumentsContract
             .buildRootsUri(AUTHORITY), null);
 }
-</pre>
+</pre>
\ No newline at end of file
diff --git a/docs/html/guide/topics/resources/localization.jd b/docs/html/guide/topics/resources/localization.jd
index 55c8dc42..3bb9ab5 100644
--- a/docs/html/guide/topics/resources/localization.jd
+++ b/docs/html/guide/topics/resources/localization.jd
@@ -1,483 +1,485 @@
-page.title=Localizing with Resources

-parent.title=Application Resources

-page.tags="localizing","localization","resources", "formats", "l10n"

-parent.link=index.html

-@jd:body

-

-<div id="qv-wrapper">

-    <div id="qv">

-

-<h2>Quickview</h2>

-

-<ul>

-  <li>Use resource sets to create a localized app.</li>

-  <li>Android loads the correct resource set for the user's language and locale.</li>

-  <li>If localized resources are not available, Android loads your default resources.</li>

-</ul>

-

-<h2>In this document</h2>

-<ol>

-  <li><a href="#resource-switching">Overview: Resource-Switching in Android</a></li>

-<li><a href="#using-framework">Using Resources for Localization</a></li>

-<li><a href="#strategies">Localization Strategies</a></li>

-<li><a href="#testing">Testing Localized Applications</a></li>

-</ol>

-

-<h2>See also</h2>

-  <ol>

-    <li><a href="{@docRoot}distribute/googleplay/publish/localizing.html">Localization Checklist</a></li>

-    <li><a href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a></li>

-    <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">Layouts</a></li>

-    <li><a href="{@docRoot}reference/android/app/Activity.html#ActivityLifecycle">Activity Lifecycle</a></li>

-</ol>

-</div>

-</div>

-

-<p>Android will run on many  devices in many  regions. To reach the most users,

-your application should handle text, audio files, numbers, currency, and

-graphics in ways appropriate to the locales where your application will be used.

-</p>

-

-<p>This document describes best practices for localizing Android

-applications. The principles apply whether you are developing your application  

-using ADT with Eclipse, Ant-based tools, or any other IDE. </p>

-

-<p>You should already have a working knowledge of Java and be  familiar with

-Android resource loading, the declaration of user interface elements in XML,

-development considerations such as Activity lifecycle, and general principles of

-internationalization and localization. </p>

-

-<p>It is good practice to use the Android resource framework to separate the

-localized aspects of your application as much as possible from the core Java

-functionality:</p>

-

-<ul>

-  <li>You can put most or all of the <em>contents</em> of your application's

-user interface into resource files, as described in this document and in <a

-href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a>.</li>

-  <li>The <em>behavior</em> of the user interface, on the other hand, is driven

-by your Java code. 

-    For example, if users input data that needs to be formatted or sorted

-differently depending on locale, then you would use Java to handle the data

-programmatically. This document does not cover how to  localize your Java code.

-</li>

-</ul>

-

-<p>For a short guide to localizing strings in your app, see the training lesson, <a

-href="{@docRoot}training/basics/supporting-devices/languages.html">Supporting Different Languages</a>. </p>

-

-

-<h2 id="resource-switching">Overview: Resource-Switching in Android</h2>

-

-<p>Resources are text strings, layouts, sounds, graphics, and any other static

-data that your  Android application  needs. An application can include multiple

-sets of resources, each customized for a different device configuration. When a

-user runs the application,  Android    automatically selects and loads the 

-resources that best match the device.</p>

-

-<p>(This document focuses on localization and locale. For a complete description

-of resource-switching and all the types of configurations that you can

-specify &#8212; screen orientation, touchscreen type, and so on &#8212; see <a

-href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">Providing

-Alternative Resources</a>.)</p>

-

-<table border="0" cellspacing="0" cellpadding="0">

-  <tr border="0">

-    <td width="180" style="border: 0pt none ;"><p class="special-note">

-    <strong>When you write your application:</strong>

-    <br><br>

-    You create a set of default resources, plus alternatives to be used in

-    different locales.</p></td>

-    <td style="border: 0pt none; padding:0">

-    <p style="border:0; padding:0"><img src="../../../images/resources/right-arrow.png" alt="right-arrow" 

-    width="51" height="17"></p></td>

-    <td width="180" style="border: 0pt none ;"><p class="special-note">

-    <strong>When a user runs your application:</strong>

-    <br><br>The Android system selects which resources to load, based on the

-    device's locale.</p></td>

-  </tr>

-</table>

-

-<p>When you write your application, you create default and alternative resources

-for your application to use. To create  resources, you place files within

-specially named subdirectories of the project's <code>res/</code> directory.

-</p>

-

-

-

-<h3 id="defaults-r-important">Why Default Resources Are Important</h3>

-

-<p>Whenever the application runs in a locale for which you have not provided

-locale-specific text,  Android will load the default strings from

-<code>res/values/strings.xml</code>. If this default  file is absent, or if it 

-is missing a string that your application needs, then your application will not run 

-and will show an error. 

-The example below illustrates what can happen when the default text file is incomplete. </p>

-

-<p><em>Example:</em>

-<p>An application's Java code refers to just two strings, <code>text_a</code> and 

-	<code>text_b</code>. This application includes a localized resource file 

-	(<code>res/values-en/strings.xml</code>) that defines <code>text_a</code> and 

-	<code>text_b</code> in English. This application also includes a default 

-	resource file (<code>res/values/strings.xml</code>) that includes a

-definition for <code>text_a</code>, but not for <code>text_b</code>:

-<ul>

-  <li>This application might compile without a problem. An IDE such as Eclipse 

-  	will not highlight any errors if a resource is missing.</li>

-  <li>When this application is launched on a device with locale set to English, 

-  	the application  might run without a problem, because 

-  	<code>res/values-en/strings.xml</code> contains both of the needed text 

-  	strings.</li>

-  <li>However, <strong>the user  will see an error message and a Force Close 

-  	button</strong> when this application is launched on a device set to a 

-  	language other than English. The application will not load.</li>

-</ul>

-

-

-<p>To prevent this situation, make sure that a <code>res/values/strings.xml</code> 

-	file exists and that it defines every needed string. The situation applies to 

-	all types of resources, not just strings: You 

-	need to create a  set of default resource files containing all 

-	the resources that your application calls upon &#8212; layouts, drawables, 

-	animations, etc. For information about testing, see <a href="#test-for-default">

-	Testing for Default Resources</a>.</p>

-

-<h2 id="using-framework">Using Resources for Localization</h2>

-

-<h3 id="creating-defaults">How to Create Default Resources</h3>

-

-<p>Put the application's default text in

-a file with the following location and name:</p>

-<p><code>&nbsp;&nbsp;&nbsp;&nbsp;res/values/strings.xml</code> (required directory)</p>

-

-<p>The text strings in <code>res/values/strings.xml</code> should  use the

-default language, which is the language that you expect most of your application's users to

-speak.  </p>

-

-<p>The default resource set must also include any default drawables and layouts, 

-	and can include other types of resources such as animations. 

-<br>

-  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/drawable/</code>(required directory holding at least

-  one graphic file, for the application's icon on Google Play)<br>

-  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/layout/</code> (required directory holding an XML

-  file that defines the default layout)<br>

-  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/anim/</code> (required if you have any 

-  <code>res/anim-<em>&lt;qualifiers&gt;</em></code> folders)<br>

-  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/xml/</code> (required if you have any 

-  <code>res/xml-<em>&lt;qualifiers&gt;</em></code> folders)<br>

-  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/raw/</code> (required if you have any 

-  <code>res/raw-<em>&lt;qualifiers&gt;</em></code> folders)

-</p>

-

-<p class="note"><strong>Tip:</strong> In your code, examine each reference to 

-	an Android resource. Make sure that a default resource is defined for each

-	one. Also make sure that the default string file is complete: A <em>

-	localized</em> string file can contain a subset of the strings, but the 

-	<em>default</em> string file must contain them all. 

-</p>

-

-<h3 id="creating-alternatives">How to Create Alternative Resources</h3>

-

-<p>A large part of localizing an application is providing alternative text for

-different languages. In some cases you will also provide alternative graphics,

-sounds, layouts, and other locale-specific resources. </p>

-

-<p>An application can specify many <code>res/<em>&lt;qualifiers&gt;</em>/</code>

-directories, each with different qualifiers. To create an alternative resource for

-a different locale, you use a qualifier that specifies a language or a 

-language-region combination. (The name of a resource directory must conform 

-to the naming scheme described in 

-<a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">Providing

-Alternative Resources</a>,

-or else it will not compile.)</p>

-

-<p><em>Example:</em></p>

-

-<p>Suppose that your application's default language is English. Suppose also

-that you want to localize all the text in your application to French, and most

-of the text in your application (everything except the application's title) to

-Japanese. In this case, you could create three alternative <code>strings.xml</code>

-files, each stored in a locale-specific resource directory:</p>

-

-<ol>

-  <li><code>res/values/strings.xml</code><br>

-    Contains  English text for all  the strings that the application uses,

-including text for a string named <code>title</code>.</li>

-  <li><code>res/values-fr/strings.xml</code><br>

-    Contain French text for all  the strings, including <code>title</code>.</li>

-  <li><code>res/values-ja/strings.xml</code><br>

-    Contain Japanese text for all  the strings <em>except</em>

-<code>title</code>.<br>

-  <code></code></li>

-</ol>

-

-<p>If your Java code refers to <code>R.string.title</code>,  here is what will

-happen at runtime:</p>

-

-<ul>

-  <li>If the device is set to any language other than French, Android will load

-<code>title</code> from the <code>res/values/strings.xml</code> file.</li>

-  <li>If the device is set to French, Android will load <code>title</code> from

-the <code>res/values-fr/strings.xml</code> file.</li>

-</ul>

-

-<p>Notice that if the device is set to Japanese, Android will look for

-<code>title</code> in the <code>res/values-ja/strings.xml</code> file. But

-because no such string is included in that file, Android will fall back to the

-default, and will load  <code>title</code> in English from the

-<code>res/values/strings.xml</code> file.  </p>

-

-<h3 id="resource-precedence">Which Resources Take Precedence?</h3>

-

-<p> If multiple resource files match a device's configuration, Android follows a

-set of rules in deciding which file to use. Among the qualifiers that can be

-specified in a resource directory name, <strong>locale almost always takes

-precedence</strong>. </p>

-<p><em>Example:</em></p>

-

-<p>Assume that an application  includes a default set of graphics and two other

-sets of graphics, each optimized for a different device setup:</p>

-

-<ul>

-  <li><code>res/drawable/</code><br>

-    Contains

-  default graphics.</li>

-  <li><code>res/drawable-small-land-stylus/</code><br>

-  Contains  graphics optimized for use with a device that expects input from a 

-  stylus and has a QVGA low-density screen in landscape orientation.</li>

-  <li><code>res/drawable-ja/</code> <br>

-  Contains  graphics optimized for use with Japanese.</li>

-</ul>

-

-<p>If the application runs on a device that is configured to use Japanese,

-Android will load graphics from  <code>res/drawable-ja/</code>, even if the

-device happens to be one that expects input from a stylus and has a QVGA 

-low-density screen in landscape orientation.</p>

-

-<p class="note"><strong>Exception:</strong> The only qualifiers that take

-precedence over locale in the selection process are MCC and MNC (mobile country

-code and mobile network code). </p>

-

-<p><em>Example:</em></p>

-

-<p>Assume that you have the following situation:</p>

-

-<ul>

-  <li>The application code calls for <code>R.string.text_a</code></li>

-  <li>Two relevant resource files are available:

-    <ul>

-      <li><code>res/values-mcc404/strings.xml</code>, which includes

-<code>text_a</code> in the application's default language, in this case

-English.</li>

-      <li><code>res/values-hi/strings.xml</code>, which includes

-<code>text_a</code> in Hindi.</li>

-    </ul>

-  </li>

-  <li>The application is running on a device that has the following

-configuration:

-    <ul>

-      <li>The SIM card is connected to a mobile network in India (MCC 404).</li>

-      <li>The language is set to Hindi (<code>hi</code>).</li>

-    </ul>

-  </li>

-</ul>

-

-<p>Android will load <code>text_a</code> from

-<code>res/values-mcc404/strings.xml</code> (in English), even if the device is

-configured for Hindi. That is because in the resource-selection process, Android

-will prefer an MCC match over a language match. </p>

-

-<p>The selection process is not always as straightforward as these examples

-suggest. Please read  <a

-href="{@docRoot}guide/topics/resources/providing-resources.html#BestMatch">How Android Finds

-the Best-matching Resource</a> for a more nuanced description of the

-process. All the qualifiers are described and listed in order of

-precedence in <a

-href="{@docRoot}guide/topics/resources/providing-resources.html#table2">Table 2 of Providing

-Alternative Resources</a>.</p>

-

-<h3 id="referring-to-resources">Referring to Resources in Java</h3>

-

-<p>In your application's Java code, you refer to  resources using the syntax

-<code>R.<em>resource_type</em>.<em>resource_name</em></code> or

-<code>android.R.<em>resource_type</em>.<em>resource_name</em></code><em>.</em>

-For more about this, see <a

-href="{@docRoot}guide/topics/resources/accessing-resources.html">Accessing Resources</a>.</p>

-

-<h2 id="strategies">Localization Strategies</h2>

-

-<h4 id="failing2">Design your application  to work in any locale</h4>

-

-<p>You cannot assume anything about the device on which a user will

-run your application. The device might have hardware that you were not

-anticipating, or it might be set to a locale that you did not plan for or that 

-you cannot test. Design your application so that it will function normally or fail gracefully no 

-matter what device it runs on.</p>

-

-<p class="note"><strong>Important:</strong> Make sure that your application

-includes a full set of default resources.</p> <p>Make sure to include

-<code>res/drawable/</code> and a <code>res/values/</code> folders (without any

-additional modifiers in the folder names) that contain all the images and text

-that your application will need. </p>

-

-<p>If an application is missing even one default resource, it will not run on a 

-	device that is set to an unsupported locale. For example, the 

-	<code>res/values/strings.xml</code> default file might lack one string that 

-	the application needs: When the application runs in an unsupported locale and 

-	attempts to load <code>res/values/strings.xml</code>, the user will see an 

-	error message and a Force Close button. An IDE such as Eclipse will not 

-	highlight this kind of error, and you will not see the problem when you 

-	test the application on a device or emulator that is set to a supported locale.</p>

-

-<p>For more information, see <a href="#test-for-default">Testing for Default Resources</a>.</p>

-

-<h4>Design a flexible layout</h4>

-

-<p> If you need to rearrange your layout to fit a certain language (for example

-German with its long words), you can create an alternative layout for that

-language (for example <code>res/layout-de/main.xml</code>). However, doing this

-can make your application harder to maintain.  It is better to create a single

-layout that is more flexible.</p>

-

-<p>Another typical situation is a language that requires something different in

-its layout. For example, you might have a contact form that should include  two

-name fields when the application runs in Japanese, but three name fields when

-the application  runs in some other language. You could handle this in either of

-two ways:</p>

-

-<ul>

-  <li>Create  one  layout with a field that you can programmatically enable or

-disable, based on the language, or</li>

-  <li>Have the main layout include another layout that  includes the changeable

-field. The second layout can have different configurations for different

-languages.</li>

-</ul>

-

-<h4>Avoid creating more resource files and text strings than you need</h4>

-

-<p>You probably do not need to create a locale-specific

-alternative for every resource in your application. For example, the layout

-defined in the <code>res/layout/main.xml</code> file might work in any locale,

-in which case there would be no need to create any alternative layout files.

-</p>

-

-<p>Also, you might not need to create alternative text for every

-string. For example, assume the following:</p>

-

-<ul>

-  <li>Your application's default language is American

-English. Every string that the application uses is defined, using American

-English spellings, in <code>res/values/strings.xml</code>. </li>

-

-  <li>For  a few important phrases, you want to provide

-British English spelling. You want these alternative strings to be used when your

-application runs on a device in the United Kingdom. </li>

-</ul>

-

-<p>To do this, you could create a small file called

-<code>res/values-en-rGB/strings.xml</code> that includes only the strings that

-should be different when the application  runs in the U.K. For all the rest of

-the strings, the application will fall back to the defaults and use what is

-defined in <code>res/values/strings.xml</code>.</p>

-

-<h4>Use the Android Context object for manual locale lookup</h4>

-

-<p>You can look up the locale using the {@link android.content.Context} object

-that Android makes available:</p>

-

-<pre>String locale = context.getResources().getConfiguration().locale.getDisplayName();</pre>

-

-<h2 id="testing">Testing Localized Applications</h2>

-

-<h3 id="device">Testing on a Device</h3>

-<p>Keep in mind that the device you are testing may be significantly different from 

-	the devices available to consumers in other geographies. The locales available 

-	on your device may differ from those available on other devices. Also, the 

-	resolution and density of the device screen may differ, which could affect 

-	the display of strings and drawables in your UI.</p>

-

-<p>To change the locale on a device, use  the Settings application  (Home &gt;

-Menu &gt; Settings &gt; Locale &amp; text &gt; Select locale). </p>

-

-<h3 id="emulator">Testing on an Emulator</h3>

-

-<p>For details about using the emulator, see See <a

-href="{@docRoot}tools/help/emulator.html">Android Emulator</a>.</p>

-<h4>Creating and using a custom locale</h4>

-

-<p>A &quot;custom&quot; locale is a language/region combination that the Android

-system image does not explicitly support. (For a list of supported locales in

-Android platforms see the Version Notes in the <a

-href="{@docRoot}sdk/index.html">SDK</a> tab). You can test

-how your application will run in a custom locale by creating a custom locale in

-the emulator. There are two ways to do this:</p>

-

-<ul>

-  <li>Use the Custom Locale application, which is accessible from the

-Application tab. (After you create a custom locale, switch to it by 

-pressing and holding the locale name.)</li>

-  <li>Change to a custom locale from the adb shell, as described below.</li>

-</ul>

-

-<p>When you set the emulator to a locale that is not available in the Android

-system image, the system itself will display in its default language. Your

-application, however, should localize properly.</p>

-

-<h4>Changing the emulator locale from the adb shell</h4>

-

-<p>To change the locale in the emulator by using the adb shell. </p>

-

-<ol>

-  <li>Pick the locale you want to test and determine its language and region codes, for

-example <code>fr</code> for French and <code>CA</code> for Canada.<br>

-  </li>

-  <li>Launch an emulator.</li>

-  <li>From a command-line shell on the host computer, run the following

-command:<br>

-    <code>adb shell</code><br>

-  or if you have a device attached, specify that you want the emulator by adding

-the <code>-e</code> option:<br>

-  <code>adb -e shell</code></li>

-  <li>At  the  adb shell prompt (<code>#</code>), run this command: <br>

-    <code>setprop persist.sys.language  [<em>language code</em>];setprop

-persist.sys.country [<em>country  code</em>];stop;sleep 5;start <br>

-    </code>Replace bracketed sections with the  appropriate codes from Step

-1.</li>

-</ol>

-

-<p>For instance, to test in Canadian French:</p>

-

-<p><code>setprop persist.sys.language  fr;setprop persist.sys.country

-CA;stop;sleep 5;start </code></p>

-

-<p>This will cause the emulator  to restart. (It will look like a full reboot,

-but it is not.) Once the Home screen appears again, re-launch your application (for

-example, click the Run icon in Eclipse), and the application will launch with

-the new locale. </p>

-

-<h3 id="test-for-default">Testing for Default Resources</h3>

-<p>Here's how to test whether an application includes every string resource that it needs:  </p>

-<ol><li>Set the emulator or device to a language that your application does not 

-	support. For example, if the application has French strings in 

-	<code>res/values-fr/</code> but does not have any Spanish strings in 

-	<code>res/values-es/</code>, then set the emulator's locale to Spanish. 

-	(You can use the Custom Locale application to set the emulator to an 

-	unsupported locale.)</li>

-	<li>Run the application.</li>  

-<li>If the application shows an error message and a Force Close button, it might 

-	be looking for a string that is not available. Make sure that your 

-	<code>res/values/strings.xml</code> file includes a definition for 

-	every string that the application uses.</li>

-</ol> 

-</p> 

-

-<p>If the test is successful, repeat it for other types of 

-	configurations. For example, if the application has a layout file called 

-	<code>res/layout-land/main.xml</code> but does not contain a file called 

-	<code>res/layout-port/main.xml</code>, then set the emulator or device to 

-	portrait orientation and see if the application will run. 

-

-

-<h2 id="checklist">Localization Checklist</h2>

-

-<p>For an overview of the process of localizing an Android application, see the <a href="{@docRoot}distribute/googleplay/publish/localizing.html">Localization Checklist</a>.</p>

+page.title=Localizing with Resources
+parent.title=Application Resources
+page.tags=localizing,localization,resources,formats,l10n
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+    <div id="qv">
+
+<h2>Quickview</h2>
+
+<ul>
+  <li>Use resource sets to create a localized app.</li>
+  <li>Android loads the correct resource set for the user's language and locale.</li>
+  <li>If localized resources are not available, Android loads your default resources.</li>
+</ul>
+
+<h2>In this document</h2>
+<ol>
+  <li><a href="#resource-switching">Overview: Resource-Switching in Android</a></li>
+<li><a href="#using-framework">Using Resources for Localization</a></li>
+<li><a href="#strategies">Localization Tips</a></li>
+<li><a href="#testing">Testing Localized Applications</a></li>
+</ol>
+
+<h2>See also</h2>
+  <ol>
+    <li><a href="{@docRoot}distribute/googleplay/publish/localizing.html">Localization Checklist</a></li>
+    <li><a href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a></li>
+    <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">Layouts</a></li>
+    <li><a href="{@docRoot}reference/android/app/Activity.html#ActivityLifecycle">Activity Lifecycle</a></li>
+</ol>
+</div>
+</div>
+
+<p>Android will run on many  devices in many  regions. To reach the most users,
+your application should handle text, audio files, numbers, currency, and
+graphics in ways appropriate to the locales where your application will be used.
+</p>
+
+<p>This document describes best practices for localizing Android
+applications. The principles apply whether you are developing your application
+using ADT with Eclipse, Ant-based tools, or any other IDE. </p>
+
+<p>You should already have a working knowledge of Java and be  familiar with
+Android resource loading, the declaration of user interface elements in XML,
+development considerations such as Activity lifecycle, and general principles of
+internationalization and localization. </p>
+
+<p>It is good practice to use the Android resource framework to separate the
+localized aspects of your application as much as possible from the core Java
+functionality:</p>
+
+<ul>
+  <li>You can put most or all of the <em>contents</em> of your application's
+user interface into resource files, as described in this document and in <a
+href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a>.</li>
+  <li>The <em>behavior</em> of the user interface, on the other hand, is driven
+by your Java code.
+    For example, if users input data that needs to be formatted or sorted
+differently depending on locale, then you would use Java to handle the data
+programmatically. This document does not cover how to  localize your Java code.
+</li>
+</ul>
+
+<p>For a short guide to localizing strings in your app, see the training lesson, <a
+href="{@docRoot}training/basics/supporting-devices/languages.html">Supporting Different Languages</a>. </p>
+
+
+<h2 id="resource-switching">Overview: Resource-Switching in Android</h2>
+
+<p>Resources are text strings, layouts, sounds, graphics, and any other static
+data that your  Android application  needs. An application can include multiple
+sets of resources, each customized for a different device configuration. When a
+user runs the application,  Android    automatically selects and loads the
+resources that best match the device.</p>
+
+<p>(This document focuses on localization and locale. For a complete description
+of resource-switching and all the types of configurations that you can
+specify &#8212; screen orientation, touchscreen type, and so on &#8212; see <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">Providing
+Alternative Resources</a>.)</p>
+
+<table border="0" cellspacing="0" cellpadding="0">
+  <tr border="0">
+    <td width="180" style="border: 0pt none ;"><p class="special-note">
+    <strong>When you write your application:</strong>
+    <br><br>
+    You create a set of default resources, plus alternatives to be used in
+    different locales.</p></td>
+    <td style="border: 0pt none; padding:0">
+    <p style="border:0; padding:0"><img src="../../../images/resources/right-arrow.png" alt="right-arrow"
+    width="51" height="17"></p></td>
+    <td width="180" style="border: 0pt none ;"><p class="special-note">
+    <strong>When a user runs your application:</strong>
+    <br><br>The Android system selects which resources to load, based on the
+    device's locale.</p></td>
+  </tr>
+</table>
+
+<p>When you write your application, you create default and alternative resources
+for your application to use. To create  resources, you place files within
+specially named subdirectories of the project's <code>res/</code> directory.
+</p>
+
+
+
+<h3 id="defaults-r-important">Why Default Resources Are Important</h3>
+
+<p>Whenever the application runs in a locale for which you have not provided
+locale-specific text,  Android will load the default strings from
+<code>res/values/strings.xml</code>. If this default  file is absent, or if it
+is missing a string that your application needs, then your application will not run
+and will show an error.
+The example below illustrates what can happen when the default text file is incomplete. </p>
+
+<p><em>Example:</em>
+<p>An application's Java code refers to just two strings, <code>text_a</code> and
+  <code>text_b</code>. This application includes a localized resource file
+  (<code>res/values-en/strings.xml</code>) that defines <code>text_a</code> and
+  <code>text_b</code> in English. This application also includes a default
+  resource file (<code>res/values/strings.xml</code>) that includes a
+definition for <code>text_a</code>, but not for <code>text_b</code>:
+<ul>
+  <li>This application might compile without a problem. An IDE such as Eclipse
+    will not highlight any errors if a resource is missing.</li>
+  <li>When this application is launched on a device with locale set to English,
+    the application  might run without a problem, because
+    <code>res/values-en/strings.xml</code> contains both of the needed text
+    strings.</li>
+  <li>However, <strong>the user  will see an error message and a Force Close
+    button</strong> when this application is launched on a device set to a
+    language other than English. The application will not load.</li>
+</ul>
+
+
+<p>To prevent this situation, make sure that a <code>res/values/strings.xml</code>
+  file exists and that it defines every needed string. The situation applies to
+  all types of resources, not just strings: You
+  need to create a  set of default resource files containing all
+  the resources that your application calls upon &#8212; layouts, drawables,
+  animations, etc. For information about testing, see <a href="#test-for-default">
+  Testing for Default Resources</a>.</p>
+
+<h2 id="using-framework">Using Resources for Localization</h2>
+
+<h3 id="creating-defaults">How to Create Default Resources</h3>
+
+<p>Put the application's default text in
+a file with the following location and name:</p>
+<p><code>&nbsp;&nbsp;&nbsp;&nbsp;res/values/strings.xml</code> (required directory)</p>
+
+<p>The text strings in <code>res/values/strings.xml</code> should  use the
+default language, which is the language that you expect most of your application's users to
+speak.  </p>
+
+<p>The default resource set must also include any default drawables and layouts,
+  and can include other types of resources such as animations.
+<br>
+  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/drawable/</code>(required directory holding at least
+  one graphic file, for the application's icon on Google Play)<br>
+  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/layout/</code> (required directory holding an XML
+  file that defines the default layout)<br>
+  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/anim/</code> (required if you have any
+  <code>res/anim-<em>&lt;qualifiers&gt;</em></code> folders)<br>
+  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/xml/</code> (required if you have any
+  <code>res/xml-<em>&lt;qualifiers&gt;</em></code> folders)<br>
+  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/raw/</code> (required if you have any
+  <code>res/raw-<em>&lt;qualifiers&gt;</em></code> folders)
+</p>
+
+<p class="note"><strong>Tip:</strong> In your code, examine each reference to
+  an Android resource. Make sure that a default resource is defined for each
+  one. Also make sure that the default string file is complete: A <em>
+  localized</em> string file can contain a subset of the strings, but the
+  <em>default</em> string file must contain them all.
+</p>
+
+<h3 id="creating-alternatives">How to Create Alternative Resources</h3>
+
+<p>A large part of localizing an application is providing alternative text for
+different languages. In some cases you will also provide alternative graphics,
+sounds, layouts, and other locale-specific resources. </p>
+
+<p>An application can specify many <code>res/<em>&lt;qualifiers&gt;</em>/</code>
+directories, each with different qualifiers. To create an alternative resource for
+a different locale, you use a qualifier that specifies a language or a
+language-region combination. (The name of a resource directory must conform
+to the naming scheme described in
+<a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">Providing
+Alternative Resources</a>,
+or else it will not compile.)</p>
+
+<p><em>Example:</em></p>
+
+<p>Suppose that your application's default language is English. Suppose also
+that you want to localize all the text in your application to French, and most
+of the text in your application (everything except the application's title) to
+Japanese. In this case, you could create three alternative <code>strings.xml</code>
+files, each stored in a locale-specific resource directory:</p>
+
+<ol>
+  <li><code>res/values/strings.xml</code><br>
+    Contains  English text for all  the strings that the application uses,
+including text for a string named <code>title</code>.</li>
+  <li><code>res/values-fr/strings.xml</code><br>
+    Contain French text for all  the strings, including <code>title</code>.</li>
+  <li><code>res/values-ja/strings.xml</code><br>
+    Contain Japanese text for all  the strings <em>except</em>
+<code>title</code>.<br>
+  <code></code></li>
+</ol>
+
+<p>If your Java code refers to <code>R.string.title</code>,  here is what will
+happen at runtime:</p>
+
+<ul>
+  <li>If the device is set to any language other than French, Android will load
+<code>title</code> from the <code>res/values/strings.xml</code> file.</li>
+  <li>If the device is set to French, Android will load <code>title</code> from
+the <code>res/values-fr/strings.xml</code> file.</li>
+</ul>
+
+<p>Notice that if the device is set to Japanese, Android will look for
+<code>title</code> in the <code>res/values-ja/strings.xml</code> file. But
+because no such string is included in that file, Android will fall back to the
+default, and will load  <code>title</code> in English from the
+<code>res/values/strings.xml</code> file.  </p>
+
+<h3 id="resource-precedence">Which Resources Take Precedence?</h3>
+
+<p> If multiple resource files match a device's configuration, Android follows a
+set of rules in deciding which file to use. Among the qualifiers that can be
+specified in a resource directory name, <strong>locale almost always takes
+precedence</strong>. </p>
+<p><em>Example:</em></p>
+
+<p>Assume that an application  includes a default set of graphics and two other
+sets of graphics, each optimized for a different device setup:</p>
+
+<ul>
+  <li><code>res/drawable/</code><br>
+    Contains
+  default graphics.</li>
+  <li><code>res/drawable-small-land-stylus/</code><br>
+  Contains  graphics optimized for use with a device that expects input from a
+  stylus and has a QVGA low-density screen in landscape orientation.</li>
+  <li><code>res/drawable-ja/</code> <br>
+  Contains  graphics optimized for use with Japanese.</li>
+</ul>
+
+<p>If the application runs on a device that is configured to use Japanese,
+Android will load graphics from  <code>res/drawable-ja/</code>, even if the
+device happens to be one that expects input from a stylus and has a QVGA
+low-density screen in landscape orientation.</p>
+
+<p class="note"><strong>Exception:</strong> The only qualifiers that take
+precedence over locale in the selection process are MCC and MNC (mobile country
+code and mobile network code). </p>
+
+<p><em>Example:</em></p>
+
+<p>Assume that you have the following situation:</p>
+
+<ul>
+  <li>The application code calls for <code>R.string.text_a</code></li>
+  <li>Two relevant resource files are available:
+    <ul>
+      <li><code>res/values-mcc404/strings.xml</code>, which includes
+<code>text_a</code> in the application's default language, in this case
+English.</li>
+      <li><code>res/values-hi/strings.xml</code>, which includes
+<code>text_a</code> in Hindi.</li>
+    </ul>
+  </li>
+  <li>The application is running on a device that has the following
+configuration:
+    <ul>
+      <li>The SIM card is connected to a mobile network in India (MCC 404).</li>
+      <li>The language is set to Hindi (<code>hi</code>).</li>
+    </ul>
+  </li>
+</ul>
+
+<p>Android will load <code>text_a</code> from
+<code>res/values-mcc404/strings.xml</code> (in English), even if the device is
+configured for Hindi. That is because in the resource-selection process, Android
+will prefer an MCC match over a language match. </p>
+
+<p>The selection process is not always as straightforward as these examples
+suggest. Please read  <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#BestMatch">How Android Finds
+the Best-matching Resource</a> for a more nuanced description of the
+process. All the qualifiers are described and listed in order of
+precedence in <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#table2">Table 2 of Providing
+Alternative Resources</a>.</p>
+
+<h3 id="referring-to-resources">Referring to Resources in Java</h3>
+
+<p>In your application's Java code, you refer to  resources using the syntax
+<code>R.<em>resource_type</em>.<em>resource_name</em></code> or
+<code>android.R.<em>resource_type</em>.<em>resource_name</em></code><em>.</em>
+For more about this, see <a
+href="{@docRoot}guide/topics/resources/accessing-resources.html">Accessing Resources</a>.</p>
+
+<h2 id="checklist">Localization Checklist</h2>
+
+<p>For a complete overview of the process of localizing and distributing an Android application,
+see the <a href="{@docRoot}distribute/googleplay/publish/localizing.html">Localization
+Checklist</a> document.</p>
+
+<h2 id="strategies">Localization Tips</h2>
+
+<h4 id="failing2">Design your application  to work in any locale</h4>
+
+<p>You cannot assume anything about the device on which a user will
+run your application. The device might have hardware that you were not
+anticipating, or it might be set to a locale that you did not plan for or that
+you cannot test. Design your application so that it will function normally or fail gracefully no
+matter what device it runs on.</p>
+
+<p class="note"><strong>Important:</strong> Make sure that your application
+includes a full set of default resources.</p> <p>Make sure to include
+<code>res/drawable/</code> and a <code>res/values/</code> folders (without any
+additional modifiers in the folder names) that contain all the images and text
+that your application will need. </p>
+
+<p>If an application is missing even one default resource, it will not run on a
+  device that is set to an unsupported locale. For example, the
+  <code>res/values/strings.xml</code> default file might lack one string that
+  the application needs: When the application runs in an unsupported locale and
+  attempts to load <code>res/values/strings.xml</code>, the user will see an
+  error message and a Force Close button. An IDE such as Eclipse will not
+  highlight this kind of error, and you will not see the problem when you
+  test the application on a device or emulator that is set to a supported locale.</p>
+
+<p>For more information, see <a href="#test-for-default">Testing for Default Resources</a>.</p>
+
+<h4>Design a flexible layout</h4>
+
+<p> If you need to rearrange your layout to fit a certain language (for example
+German with its long words), you can create an alternative layout for that
+language (for example <code>res/layout-de/main.xml</code>). However, doing this
+can make your application harder to maintain.  It is better to create a single
+layout that is more flexible.</p>
+
+<p>Another typical situation is a language that requires something different in
+its layout. For example, you might have a contact form that should include  two
+name fields when the application runs in Japanese, but three name fields when
+the application  runs in some other language. You could handle this in either of
+two ways:</p>
+
+<ul>
+  <li>Create  one  layout with a field that you can programmatically enable or
+disable, based on the language, or</li>
+  <li>Have the main layout include another layout that  includes the changeable
+field. The second layout can have different configurations for different
+languages.</li>
+</ul>
+
+<h4>Avoid creating more resource files and text strings than you need</h4>
+
+<p>You probably do not need to create a locale-specific
+alternative for every resource in your application. For example, the layout
+defined in the <code>res/layout/main.xml</code> file might work in any locale,
+in which case there would be no need to create any alternative layout files.
+</p>
+
+<p>Also, you might not need to create alternative text for every
+string. For example, assume the following:</p>
+
+<ul>
+  <li>Your application's default language is American
+English. Every string that the application uses is defined, using American
+English spellings, in <code>res/values/strings.xml</code>. </li>
+
+  <li>For  a few important phrases, you want to provide
+British English spelling. You want these alternative strings to be used when your
+application runs on a device in the United Kingdom. </li>
+</ul>
+
+<p>To do this, you could create a small file called
+<code>res/values-en-rGB/strings.xml</code> that includes only the strings that
+should be different when the application  runs in the U.K. For all the rest of
+the strings, the application will fall back to the defaults and use what is
+defined in <code>res/values/strings.xml</code>.</p>
+
+<h4>Use the Android Context object for manual locale lookup</h4>
+
+<p>You can look up the locale using the {@link android.content.Context} object
+that Android makes available:</p>
+
+<pre>String locale = context.getResources().getConfiguration().locale.getDisplayName();</pre>
+
+<h2 id="testing">Testing Localized Applications</h2>
+
+<h3 id="device">Testing on a Device</h3>
+<p>Keep in mind that the device you are testing may be significantly different from
+  the devices available to consumers in other geographies. The locales available
+  on your device may differ from those available on other devices. Also, the
+  resolution and density of the device screen may differ, which could affect
+  the display of strings and drawables in your UI.</p>
+
+<p>To change the locale on a device, use  the Settings application  (Home &gt;
+Menu &gt; Settings &gt; Locale &amp; text &gt; Select locale). </p>
+
+<h3 id="emulator">Testing on an Emulator</h3>
+
+<p>For details about using the emulator, see See <a
+href="{@docRoot}tools/help/emulator.html">Android Emulator</a>.</p>
+<h4>Creating and using a custom locale</h4>
+
+<p>A &quot;custom&quot; locale is a language/region combination that the Android
+system image does not explicitly support. (For a list of supported locales in
+Android platforms see the Version Notes in the <a
+href="{@docRoot}sdk/index.html">SDK</a> tab). You can test
+how your application will run in a custom locale by creating a custom locale in
+the emulator. There are two ways to do this:</p>
+
+<ul>
+  <li>Use the Custom Locale application, which is accessible from the
+Application tab. (After you create a custom locale, switch to it by
+pressing and holding the locale name.)</li>
+  <li>Change to a custom locale from the adb shell, as described below.</li>
+</ul>
+
+<p>When you set the emulator to a locale that is not available in the Android
+system image, the system itself will display in its default language. Your
+application, however, should localize properly.</p>
+
+<h4>Changing the emulator locale from the adb shell</h4>
+
+<p>To change the locale in the emulator by using the adb shell. </p>
+
+<ol>
+  <li>Pick the locale you want to test and determine its language and region codes, for
+example <code>fr</code> for French and <code>CA</code> for Canada.<br>
+  </li>
+  <li>Launch an emulator.</li>
+  <li>From a command-line shell on the host computer, run the following
+command:<br>
+    <code>adb shell</code><br>
+  or if you have a device attached, specify that you want the emulator by adding
+the <code>-e</code> option:<br>
+  <code>adb -e shell</code></li>
+  <li>At  the  adb shell prompt (<code>#</code>), run this command: <br>
+    <code>setprop persist.sys.language  [<em>language code</em>];setprop
+persist.sys.country [<em>country  code</em>];stop;sleep 5;start <br>
+    </code>Replace bracketed sections with the  appropriate codes from Step
+1.</li>
+</ol>
+
+<p>For instance, to test in Canadian French:</p>
+
+<p><code>setprop persist.sys.language  fr;setprop persist.sys.country
+CA;stop;sleep 5;start </code></p>
+
+<p>This will cause the emulator  to restart. (It will look like a full reboot,
+but it is not.) Once the Home screen appears again, re-launch your application (for
+example, click the Run icon in Eclipse), and the application will launch with
+the new locale. </p>
+
+<h3 id="test-for-default">Testing for Default Resources</h3>
+<p>Here's how to test whether an application includes every string resource that it needs:  </p>
+<ol><li>Set the emulator or device to a language that your application does not
+  support. For example, if the application has French strings in
+  <code>res/values-fr/</code> but does not have any Spanish strings in
+  <code>res/values-es/</code>, then set the emulator's locale to Spanish.
+  (You can use the Custom Locale application to set the emulator to an
+  unsupported locale.)</li>
+  <li>Run the application.</li>
+<li>If the application shows an error message and a Force Close button, it might
+  be looking for a string that is not available. Make sure that your
+  <code>res/values/strings.xml</code> file includes a definition for
+  every string that the application uses.</li>
+</ol>
+</p>
+
+<p>If the test is successful, repeat it for other types of
+  configurations. For example, if the application has a layout file called
+  <code>res/layout-land/main.xml</code> but does not contain a file called
+  <code>res/layout-port/main.xml</code>, then set the emulator or device to
+  portrait orientation and see if the application will run.
+
diff --git a/docs/html/guide/topics/resources/runtime-changes.jd b/docs/html/guide/topics/resources/runtime-changes.jd
index 45a548a..695647b 100644
--- a/docs/html/guide/topics/resources/runtime-changes.jd
+++ b/docs/html/guide/topics/resources/runtime-changes.jd
@@ -1,5 +1,5 @@
 page.title=Handling Runtime Changes
-page.tags="activity","lifecycle"
+page.tags=activity,lifecycle
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/search/adding-custom-suggestions.jd b/docs/html/guide/topics/search/adding-custom-suggestions.jd
index 47ad2fe..6ebef08 100644
--- a/docs/html/guide/topics/search/adding-custom-suggestions.jd
+++ b/docs/html/guide/topics/search/adding-custom-suggestions.jd
@@ -1,5 +1,5 @@
 page.title=Adding Custom Suggestions
-page.tags="SearchRecentSuggestionsProvider",
+page.tags=SearchRecentSuggestionsProvider,
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/search/adding-recent-query-suggestions.jd b/docs/html/guide/topics/search/adding-recent-query-suggestions.jd
index c1d59d4..e1020dd 100644
--- a/docs/html/guide/topics/search/adding-recent-query-suggestions.jd
+++ b/docs/html/guide/topics/search/adding-recent-query-suggestions.jd
@@ -1,5 +1,5 @@
 page.title=Adding Recent Query Suggestions
-page.tags="SearchRecentSuggestions","SearchRecentSuggestionsProvider"
+page.tags=SearchRecentSuggestions,SearchRecentSuggestionsProvider
 
 @jd:body
 
diff --git a/docs/html/guide/topics/search/search-dialog.jd b/docs/html/guide/topics/search/search-dialog.jd
index fc722b2..fcaaed36 100644
--- a/docs/html/guide/topics/search/search-dialog.jd
+++ b/docs/html/guide/topics/search/search-dialog.jd
@@ -1,5 +1,5 @@
 page.title=Creating a Search Interface
-page.tags="searchview"
+page.tags=searchview
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/sensors/index.jd b/docs/html/guide/topics/sensors/index.jd
index 65560e6..09d27e7 100644
--- a/docs/html/guide/topics/sensors/index.jd
+++ b/docs/html/guide/topics/sensors/index.jd
@@ -1,6 +1,6 @@
 page.title=Location and Sensors APIs
 page.landing=true
-page.tags="location","sensors"
+page.tags=location,sensors
 page.landing.intro=Use sensors on the device to add rich location and motion capabilities to your app, from GPS or network location to accelerometer, gyroscope, temperature, barometer, and more. 
 page.landing.image=
 
@@ -38,4 +38,4 @@
     </a>
   </div>
 
-</div>
\ No newline at end of file
+</div>
diff --git a/docs/html/guide/topics/sensors/sensors_motion.jd b/docs/html/guide/topics/sensors/sensors_motion.jd
index 289c639..99b689f 100644
--- a/docs/html/guide/topics/sensors/sensors_motion.jd
+++ b/docs/html/guide/topics/sensors/sensors_motion.jd
@@ -1,5 +1,5 @@
 page.title=Motion Sensors
-page.tags="sensorevent","accelerometer","gyroscope","gravity","rotation"
+page.tags=sensorevent,accelerometer,gyroscope,gravity,rotation
 @jd:body
 
 <div id="qv-wrapper">
@@ -450,4 +450,4 @@
 <p>The Android SDK provides a sample application that shows how to use the rotation vector sensor.
 The sample application is located in the API Demos code (<a
 href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/os/RotationVectorDemo.html">
-OS - RotationVectorDemo</a>).</p>
\ No newline at end of file
+OS - RotationVectorDemo</a>).</p>
diff --git a/docs/html/guide/topics/sensors/sensors_position.jd b/docs/html/guide/topics/sensors/sensors_position.jd
index 55b282b..65b9350 100644
--- a/docs/html/guide/topics/sensors/sensors_position.jd
+++ b/docs/html/guide/topics/sensors/sensors_position.jd
@@ -1,5 +1,5 @@
 page.title=Position Sensors
-page.tags="sensorevent","orientation","proximity"
+page.tags=sensorevent,orientation,proximity
 @jd:body
 
 <div id="qv-wrapper">
@@ -313,4 +313,4 @@
 "near" or "far." In this case, the sensor usually reports its maximum range value in the far state
 and a lesser value in the near state. Typically, the far value is a value > 5 cm, but this can vary
 from sensor to sensor. You can determine a sensor's maximum range by using the {@link
-android.hardware.Sensor#getMaximumRange} method.</p>
\ No newline at end of file
+android.hardware.Sensor#getMaximumRange} method.</p>
diff --git a/docs/html/guide/topics/text/copy-paste.jd b/docs/html/guide/topics/text/copy-paste.jd
index b34f0fa..8f898e4 100644
--- a/docs/html/guide/topics/text/copy-paste.jd
+++ b/docs/html/guide/topics/text/copy-paste.jd
@@ -1,5 +1,5 @@
 page.title=Copy and Paste
-page.tags="clipboardmanager","clipdata","input"
+page.tags=clipboardmanager,clipdata,input
 @jd:body
 <div id="qv-wrapper">
     <div id="qv">
diff --git a/docs/html/guide/topics/text/creating-input-method.jd b/docs/html/guide/topics/text/creating-input-method.jd
index 7254594..205fd96 100644
--- a/docs/html/guide/topics/text/creating-input-method.jd
+++ b/docs/html/guide/topics/text/creating-input-method.jd
@@ -1,5 +1,5 @@
 page.title=Creating an Input Method
-page.tags="ime","keyboard","inputmethodservice"
+page.tags=ime,keyboard,inputmethodservice
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/text/spell-checker-framework.jd b/docs/html/guide/topics/text/spell-checker-framework.jd
index 366f9cc..a5d9932 100644
--- a/docs/html/guide/topics/text/spell-checker-framework.jd
+++ b/docs/html/guide/topics/text/spell-checker-framework.jd
@@ -1,5 +1,5 @@
 page.title=Spelling Checker Framework
-page.tags="input","spellcheckerservice"
+page.tags=input,spellcheckerservice
 @jd:body
 <div id="qv-wrapper">
 <div id="qv">
diff --git a/docs/html/guide/topics/ui/accessibility/services.jd b/docs/html/guide/topics/ui/accessibility/services.jd
index 4bd752f..c868080 100644
--- a/docs/html/guide/topics/ui/accessibility/services.jd
+++ b/docs/html/guide/topics/ui/accessibility/services.jd
@@ -81,7 +81,8 @@
 <pre>
 &lt;application&gt;
   &lt;service android:name=&quot;.MyAccessibilityService&quot;
-      android:label=&quot;@string/accessibility_service_label&quot;&gt;
+      android:label=&quot;@string/accessibility_service_label&quot;
+      android:permission=&quot;android.permission.BIND_ACCESSIBILITY_SERVICE&quot&gt;
     &lt;intent-filter&gt;
       &lt;action android:name=&quot;android.accessibilityservice.AccessibilityService&quot; /&gt;
     &lt;/intent-filter&gt;
diff --git a/docs/html/guide/topics/ui/actionbar.jd b/docs/html/guide/topics/ui/actionbar.jd
index 3173ff1..a122443 100644
--- a/docs/html/guide/topics/ui/actionbar.jd
+++ b/docs/html/guide/topics/ui/actionbar.jd
@@ -1,5 +1,5 @@
 page.title=Action Bar
-page.tags="actionbar","menu","tabs"
+page.tags=actionbar,menu,tabs
 
 @jd:body
 
diff --git a/docs/html/guide/topics/ui/controls/button.jd b/docs/html/guide/topics/ui/controls/button.jd
index 41b67b7f..02597c8 100644
--- a/docs/html/guide/topics/ui/controls/button.jd
+++ b/docs/html/guide/topics/ui/controls/button.jd
@@ -1,5 +1,5 @@
 page.title=Buttons
-page.tags="button","imagebutton"
+page.tags=button,imagebutton
 @jd:body
 
 <div id="qv-wrapper">
@@ -241,4 +241,4 @@
   <p>For more information about this XML syntax, including how to define a disabled, hovered, or
 other button states, read about <a
 href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">State List
-Drawable</a>.</p>
\ No newline at end of file
+Drawable</a>.</p>
diff --git a/docs/html/guide/topics/ui/controls/pickers.jd b/docs/html/guide/topics/ui/controls/pickers.jd
index 4c55840..31e4d3f5 100644
--- a/docs/html/guide/topics/ui/controls/pickers.jd
+++ b/docs/html/guide/topics/ui/controls/pickers.jd
@@ -1,5 +1,5 @@
 page.title=Pickers
-page.tags="datepicker","timepicker"
+page.tags=datepicker,timepicker
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/controls/radiobutton.jd b/docs/html/guide/topics/ui/controls/radiobutton.jd
index d0c48ed..b2556e19 100644
--- a/docs/html/guide/topics/ui/controls/radiobutton.jd
+++ b/docs/html/guide/topics/ui/controls/radiobutton.jd
@@ -1,5 +1,5 @@
 page.title=Radio Buttons
-page.tags="radiobutton","radiogroup"
+page.tags=radiobutton,radiogroup
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/controls/spinner.jd b/docs/html/guide/topics/ui/controls/spinner.jd
index 85714b6..d2db7a4 100644
--- a/docs/html/guide/topics/ui/controls/spinner.jd
+++ b/docs/html/guide/topics/ui/controls/spinner.jd
@@ -1,5 +1,5 @@
 page.title=Spinners
-page.tags="adapterview","spinneradapter"
+page.tags=adapterview,spinneradapter
 @jd:body
 
 <div id="qv-wrapper">
@@ -143,4 +143,4 @@
 <p>If you implement the {@link
 android.widget.AdapterView.OnItemSelectedListener} interface with your {@link
 android.app.Activity} or {@link android.app.Fragment} (such as in the example above), you can pass
-<code>this</code> as the interface instance.</p>
\ No newline at end of file
+<code>this</code> as the interface instance.</p>
diff --git a/docs/html/guide/topics/ui/controls/text.jd b/docs/html/guide/topics/ui/controls/text.jd
index c0b9873..9474dee 100644
--- a/docs/html/guide/topics/ui/controls/text.jd
+++ b/docs/html/guide/topics/ui/controls/text.jd
@@ -1,5 +1,5 @@
 page.title=Text Fields
-page.tags="edittext","autocompletetextview"
+page.tags=edittext,autocompletetextview
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/controls/togglebutton.jd b/docs/html/guide/topics/ui/controls/togglebutton.jd
index 3119cd9..c57b510 100644
--- a/docs/html/guide/topics/ui/controls/togglebutton.jd
+++ b/docs/html/guide/topics/ui/controls/togglebutton.jd
@@ -1,5 +1,5 @@
 page.title=Toggle Buttons
-page.tags="switch","togglebutton"
+page.tags=switch,togglebutton
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/custom-components.jd b/docs/html/guide/topics/ui/custom-components.jd
index 703a5ce..b146098 100644
--- a/docs/html/guide/topics/ui/custom-components.jd
+++ b/docs/html/guide/topics/ui/custom-components.jd
@@ -1,5 +1,5 @@
 page.title=Custom Components
-page.tags="view","widget"
+page.tags=view,widget
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/declaring-layout.jd b/docs/html/guide/topics/ui/declaring-layout.jd
index 6586c2f..616949b 100644
--- a/docs/html/guide/topics/ui/declaring-layout.jd
+++ b/docs/html/guide/topics/ui/declaring-layout.jd
@@ -1,5 +1,5 @@
 page.title=Layouts
-page.tags="view","viewgroup"
+page.tags=view,viewgroup
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/dialogs.jd b/docs/html/guide/topics/ui/dialogs.jd
index d934c4b..4754d11 100644
--- a/docs/html/guide/topics/ui/dialogs.jd
+++ b/docs/html/guide/topics/ui/dialogs.jd
@@ -1,5 +1,5 @@
 page.title=Dialogs
-page.tags="alertdialog","dialogfragment"
+page.tags=alertdialog,dialogfragment
 
 @jd:body
 
diff --git a/docs/html/guide/topics/ui/drag-drop.jd b/docs/html/guide/topics/ui/drag-drop.jd
index e989374..9d8aa9b 100644
--- a/docs/html/guide/topics/ui/drag-drop.jd
+++ b/docs/html/guide/topics/ui/drag-drop.jd
@@ -1,5 +1,5 @@
 page.title=Drag and Drop
-page.tags="clipdata","dragevent","onlongclicklistener"
+page.tags=clipdata,dragevent,onlongclicklistener
 @jd:body
 
 <div id="qv-wrapper">
@@ -873,7 +873,7 @@
 
 ...
 
-protected class myDragEventListener implements View.OnDragEventListener {
+protected class myDragEventListener implements View.OnDragListener {
 
     // This is the method that the system calls when it dispatches a drag event to the
     // listener.
@@ -899,18 +899,15 @@
                     v.invalidate();
 
                     // returns true to indicate that the View can accept the dragged data.
-                    return(true);
+                    return true;
 
-                    } else {
+                }
 
-                    // Returns false. During the current drag and drop operation, this View will
-                    // not receive events again until ACTION_DRAG_ENDED is sent.
-                    return(false);
+                // Returns false. During the current drag and drop operation, this View will
+                // not receive events again until ACTION_DRAG_ENDED is sent.
+                return false;
 
-                    }
-                break;
-
-            case DragEvent.ACTION_DRAG_ENTERED: {
+            case DragEvent.ACTION_DRAG_ENTERED:
 
                 // Applies a green tint to the View. Return true; the return value is ignored.
 
@@ -919,79 +916,70 @@
                 // Invalidate the view to force a redraw in the new tint
                 v.invalidate();
 
-                return(true);
+                return true;
 
-                break;
-
-                case DragEvent.ACTION_DRAG_LOCATION:
+            case DragEvent.ACTION_DRAG_LOCATION:
 
                 // Ignore the event
-                    return(true);
+                return true;
 
+            case DragEvent.ACTION_DRAG_EXITED:
+
+                // Re-sets the color tint to blue. Returns true; the return value is ignored.
+                v.setColorFilter(Color.BLUE);
+
+                // Invalidate the view to force a redraw in the new tint
+                v.invalidate();
+
+                return true;
+
+            case DragEvent.ACTION_DROP:
+
+                // Gets the item containing the dragged data
+                ClipData.Item item = event.getClipData().getItemAt(0);
+
+                // Gets the text data from the item.
+                dragData = item.getText();
+
+                // Displays a message containing the dragged data.
+                Toast.makeText(this, "Dragged data is " + dragData, Toast.LENGTH_LONG);
+
+                // Turns off any color tints
+                v.clearColorFilter();
+
+                // Invalidates the view to force a redraw
+                v.invalidate();
+
+                // Returns true. DragEvent.getResult() will return true.
+                return true;
+
+            case DragEvent.ACTION_DRAG_ENDED:
+
+                // Turns off any color tinting
+                v.clearColorFilter();
+
+                // Invalidates the view to force a redraw
+                v.invalidate();
+
+                // Does a getResult(), and displays what happened.
+                if (event.getResult()) {
+                    Toast.makeText(this, "The drop was handled.", Toast.LENGTH_LONG);
+
+                } else {
+                    Toast.makeText(this, "The drop didn't work.", Toast.LENGTH_LONG);
+
+                }
+
+                // returns true; the value is ignored.
+                return true;
+
+            // An unknown action type was received.
+            default:
+                Log.e("DragDrop Example","Unknown action type received by OnDragListener.");
                 break;
-
-                case DragEvent.ACTION_DRAG_EXITED:
-
-                    // Re-sets the color tint to blue. Returns true; the return value is ignored.
-                    v.setColorFilter(Color.BLUE);
-
-                    // Invalidate the view to force a redraw in the new tint
-                    v.invalidate();
-
-                    return(true);
-
-                break;
-
-                case DragEvent.ACTION_DROP:
-
-                    // Gets the item containing the dragged data
-                    ClipData.Item item = event.getClipData().getItemAt(0);
-
-                    // Gets the text data from the item.
-                    dragData = item.getText();
-
-                    // Displays a message containing the dragged data.
-                    Toast.makeText(this, "Dragged data is " + dragData, Toast.LENGTH_LONG);
-
-                    // Turns off any color tints
-                    v.clearColorFilter();
-
-                    // Invalidates the view to force a redraw
-                    v.invalidate();
-
-                    // Returns true. DragEvent.getResult() will return true.
-                    return(true);
-
-                break;
-
-                case DragEvent.ACTION_DRAG_ENDED:
-
-                    // Turns off any color tinting
-                    v.clearColorFilter();
-
-                    // Invalidates the view to force a redraw
-                    v.invalidate();
-
-                    // Does a getResult(), and displays what happened.
-                    if (event.getResult()) {
-                        Toast.makeText(this, "The drop was handled.", Toast.LENGTH_LONG);
-
-                    } else {
-                        Toast.makeText(this, "The drop didn't work.", Toast.LENGTH_LONG);
-
-                    };
-
-                    // returns true; the value is ignored.
-                    return(true);
-
-                break;
-
-                // An unknown action type was received.
-                default:
-                    Log.e("DragDrop Example","Unknown action type received by OnDragListener.");
-
-                break;
-        };
-    };
+        }
+        
+        return false;
+    }
 };
 </pre>
diff --git a/docs/html/guide/topics/ui/layout/gridview.jd b/docs/html/guide/topics/ui/layout/gridview.jd
index bc189c4..b8d24b60 100644
--- a/docs/html/guide/topics/ui/layout/gridview.jd
+++ b/docs/html/guide/topics/ui/layout/gridview.jd
@@ -1,5 +1,5 @@
 page.title=Grid View
-page.tags="gridview"
+page.tags=gridview
 @jd:body
 <div id="qv-wrapper">
 <div id="qv">
diff --git a/docs/html/guide/topics/ui/layout/linear.jd b/docs/html/guide/topics/ui/layout/linear.jd
index 444dc71..902f22f 100644
--- a/docs/html/guide/topics/ui/layout/linear.jd
+++ b/docs/html/guide/topics/ui/layout/linear.jd
@@ -1,5 +1,5 @@
 page.title=Linear Layout
-page.tags="linearlayout"
+page.tags=linearlayout
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/layout/listview.jd b/docs/html/guide/topics/ui/layout/listview.jd
index f8315c5..3c6e32c 100644
--- a/docs/html/guide/topics/ui/layout/listview.jd
+++ b/docs/html/guide/topics/ui/layout/listview.jd
@@ -1,5 +1,5 @@
 page.title=List View
-page.tags="listview"
+page.tags=listview
 @jd:body
 <div id="qv-wrapper">
 <div id="qv">
diff --git a/docs/html/guide/topics/ui/layout/relative.jd b/docs/html/guide/topics/ui/layout/relative.jd
index 65c5617..69f5c0a 100644
--- a/docs/html/guide/topics/ui/layout/relative.jd
+++ b/docs/html/guide/topics/ui/layout/relative.jd
@@ -1,5 +1,5 @@
 page.title=Relative Layout
-page.tags="relativelayout"
+page.tags=relativelayout
 @jd:body
 
 <div id="qv-wrapper">
@@ -114,4 +114,4 @@
 </pre>
 
 <p>For details about all the layout attributes available to each child view of a {@link
-android.widget.RelativeLayout}, see {@link android.widget.RelativeLayout.LayoutParams}.</p>
\ No newline at end of file
+android.widget.RelativeLayout}, see {@link android.widget.RelativeLayout.LayoutParams}.</p>
diff --git a/docs/html/guide/topics/ui/settings.jd b/docs/html/guide/topics/ui/settings.jd
index d96447d..1d36430 100644
--- a/docs/html/guide/topics/ui/settings.jd
+++ b/docs/html/guide/topics/ui/settings.jd
@@ -1,5 +1,5 @@
 page.title=Settings
-page.tags="preference","preferenceactivity","preferencefragment"
+page.tags=preference,preferenceactivity,preferencefragment
 
 @jd:body
 
diff --git a/docs/html/guide/webapps/best-practices.jd b/docs/html/guide/webapps/best-practices.jd
index 1362990..a13c69da 100644
--- a/docs/html/guide/webapps/best-practices.jd
+++ b/docs/html/guide/webapps/best-practices.jd
@@ -1,6 +1,24 @@
 page.title=Best Practices for Web Apps
 @jd:body
 
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>See also</h2>
+<ul>
+  <li><a href="https://developers.google.com/chrome/mobile/docs/webview/pixelperfect"
+  >Pixel-Perfect UI in the WebView</a></li>
+  <li><a href="http://www.html5rocks.com/en/mobile/responsivedesign/" class="external-link">Creating
+  a Mobile-First Responsive Web Design</a></li>
+  <li><a href="http://www.html5rocks.com/en/mobile/high-dpi/" class="external-link">High
+  DPI Images for Variable Pixel Densities</a></li>
+</ul>
+
+</div>
+</div>
+
+
+
 <style>
 .bold li {
   font-weight:bold;
diff --git a/docs/html/guide/webapps/debugging.jd b/docs/html/guide/webapps/debugging.jd
index 1eef1ae..3c95fc2 100644
--- a/docs/html/guide/webapps/debugging.jd
+++ b/docs/html/guide/webapps/debugging.jd
@@ -18,19 +18,29 @@
 
 <h2>See also</h2>
 <ol>
+  <li><a class="external-link"
+href="https://developers.google.com/chrome-developer-tools/docs/remote-debugging">Remote
+Debugging on Android</a></li>
   <li><a href="{@docRoot}tools/debugging/index.html">Debugging</a></li>
 </ol>
 
 </div>
 </div>
 
-<p>If you're developing a web application for Android, you can debug your JavaScript
-using the {@code console} JavaScript APIs, which output messages to logcat. If you're familiar with
+<p>If you are testing your web app with a device running Android 4.4 or higher,
+you can remotely debug your web pages in {@link android.webkit.WebView} with
+Chrome Developer Tools, while continuing to support older versions of Android.
+For more information, see <a class="external-link"
+href="https://developers.google.com/chrome-developer-tools/docs/remote-debugging">Remote
+Debugging on Android</a>.</p>
+
+<p>If you don't have a device running Android 4.4 or higher, you can debug your JavaScript using the
+{@code console} JavaScript APIs and view the output messages to logcat. If you're familiar with
 debugging web pages with Firebug or Web Inspector, then you're probably familiar
 with using {@code console} (such as {@code console.log()}). Android's WebKit framework supports most
 of the same APIs, so you can receive logs from your web page when debugging in Android's Browser
-or in your own {@link android.webkit.WebView}.</p>
-
+or in your own {@link android.webkit.WebView}. This document describes how to use the
+console APIs for debugging.</p>
 
 
 <h2 id="Browser">Using Console APIs in the Android Browser</h2>
@@ -83,28 +93,17 @@
 
 <h2 id="WebView">Using Console APIs in WebView</h2>
 
-<p>If you've implemented a custom {@link android.webkit.WebView} in your application, all the
-same console APIs are supported when debugging your web page in WebView. On Android
-1.6 and lower, console messages are automatically sent to logcat with the
-"WebCore" logging tag. If you're targeting Android 2.1 (API Level 7) or higher, then you must
+<p>All the console APIs shown above are also
+supported when debugging in {@link android.webkit.WebView}. 
+If you're targeting Android 2.1 (API level 7) and higher, you must
 provide a {@link android.webkit.WebChromeClient}
 that implements the {@link android.webkit.WebChromeClient#onConsoleMessage(String,int,String)
-onConsoleMessage()} callback method, in order for console messages to appear in logcat.</p>
-
-<p>Additionally, the {@link
-android.webkit.WebChromeClient#onConsoleMessage(String,int,String)} method introduced in API
-Level 7 has been deprecated in favor of {@link
-android.webkit.WebChromeClient#onConsoleMessage(ConsoleMessage)} in API Level 8.</p>
-
-<p>Whether you're developing for Android 2.1 (API Level 7) or Android 2.2 (API Level 8 or
-greater), you must implement {@link android.webkit.WebChromeClient} and override the appropriate
-{@link
-android.webkit.WebChromeClient#onConsoleMessage(String,int,String) onConsoleMessage()} callback
-method. Then, apply the {@link android.webkit.WebChromeClient} to your {@link
+onConsoleMessage()} method in order for console messages to appear in logcat.
+Then, apply the {@link android.webkit.WebChromeClient} to your {@link
 android.webkit.WebView} with {@link android.webkit.WebView#setWebChromeClient(WebChromeClient)
 setWebChromeClient()}.
 
-<p>Using API Level 7, this is how your code for {@link
+<p>For example, to support API level 7, this is how your code for {@link
 android.webkit.WebChromeClient#onConsoleMessage(String,int,String)} might look:</p>
 
 <pre>
@@ -118,8 +117,8 @@
 });
 </pre>
 
-<p>With API Level 8 or greater, your code for {@link
-android.webkit.WebChromeClient#onConsoleMessage(ConsoleMessage)} might look like this:</p>
+<p>However, if your lowest supported version is API level 8 or higher, you should instead
+implement {@link android.webkit.WebChromeClient#onConsoleMessage(ConsoleMessage)}. For example:</p>
 
 <pre>
 WebView myWebView = (WebView) findViewById(R.id.webview);
@@ -134,8 +133,8 @@
 </pre>
 
 <p>The {@link android.webkit.ConsoleMessage} also includes a {@link
-android.webkit.ConsoleMessage.MessageLevel MessageLevel} to indicate the type of console message
-being delivered. You can query the message level with {@link
+android.webkit.ConsoleMessage.MessageLevel MessageLevel} object to indicate the type of console
+message being delivered. You can query the message level with {@link
 android.webkit.ConsoleMessage#messageLevel()} to determine the severity of the message, then
 use the appropriate {@link android.util.Log} method or take other appropriate actions.</p>
 
diff --git a/docs/html/guide/webapps/index.jd b/docs/html/guide/webapps/index.jd
index df7ddbe..a188d2b 100644
--- a/docs/html/guide/webapps/index.jd
+++ b/docs/html/guide/webapps/index.jd
@@ -1,16 +1,50 @@
 page.title=Web Apps
-page.landing=true
-page.landing.intro=Android has always been about connectivity and providing a great web browsing experience, so building your app with web technologies can be a great opportunity. Not only can you build an app on the web and still optimize your designs for Android's various screen sizes and densities, but you can also embed web-based content into your Android app using WebView.
-page.landing.image=
 
 @jd:body
 
-<div class="landing-docs">
+<div class="figure" style="width:327px">
+  <img src="{@docRoot}images/webapps/webapps.png" alt="" />
+  <p class="img-caption"><strong>Figure 1.</strong> You can make your web content available to
+users in two ways: in a traditional web browser and in an Android application, by
+including a WebView in the layout.</p>
+</div>
 
-  <div class="col-6">
-  </div>
+<p>There are essentially two ways to deliver an application on Android: as a
+client-side application (developed using the Android SDK and installed on user devices in an APK)
+or as a web application (developed using web standards and accessed through a web
+browser&mdash;there's nothing to install on user devices).</p>
 
-  <div class="col-6">
-  </div>
+<p>If you chose to provide a web-based app for Android-powered devices, you can rest
+assured that major web browsers for Android (and the {@link android.webkit.WebView} framework)
+allow you to specify viewport and style properties that make your web pages appear at the proper
+size and scale on all screen configurations.</p>
 
-</div>
\ No newline at end of file
+<p>Figure 1 illustrates how you can provide access to your web pages from either
+a web browser or your your own Android app. However, you shouldn't develop an Android
+app simply as a means to view your web site. Rather, the web pages you embed in your
+Android app should be designed especially for that environment. You can even define an
+interface between your Android application and your web pages that allows JavaScript in the web
+pages to call upon APIs in your Android application&mdash;providing Android APIs to your web-based
+application.</p>
+
+<p>To start developing web pages for Android-powered devices, see the following documents:</p>
+
+<dl>
+  <dt><a href="{@docRoot}guide/webapps/targeting.html"><strong>Supporting Different Screens from Web
+  Apps</strong></a></dt>
+  <dd>How to properly size your web app on Android-powered devices and support
+multiple screen densities. The information in this document is important if you're building a web
+application that you at least expect to be available on Android-powered devices (which you should
+assume for anything you publish on the web), but especially if you're targeting mobile devices
+or using {@link android.webkit.WebView}.</dd>
+  <dt><a href="{@docRoot}guide/webapps/webview.html"><strong>Building Web Apps in
+WebView</strong></a></dt>
+  <dd>How to embed web pages into your Android application using {@link
+  android.webkit.WebView} and bind JavaScript to Android APIs.</dd>
+  <dt><a href="{@docRoot}guide/webapps/debugging.html"><strong>Debugging Web Apps</strong></a></dt>
+  <dd>How to debug web apps using JavaScript Console APIs.</dd>
+  <dt><a href="{@docRoot}guide/webapps/best-practices.html"><strong>Best Practices for Web
+Apps</strong></a></dt>
+  <dd>A list of practices you should follow, in order to provide an effective web application on
+Android-powered devices.</dd>
+</dl>
\ No newline at end of file
diff --git a/docs/html/guide/webapps/overview.jd b/docs/html/guide/webapps/overview.jd
deleted file mode 100644
index 069290a..0000000
--- a/docs/html/guide/webapps/overview.jd
+++ /dev/null
@@ -1,71 +0,0 @@
-page.title=Web Apps Overview
-@jd:body
-
-<div class="figure" style="width:327px">
-  <img src="{@docRoot}images/webapps/webapps.png" alt="" />
-  <p class="img-caption"><strong>Figure 1.</strong> You can make your web content available to
-users in two ways: in a traditional web browser and in an Android application, by
-including a WebView in the layout.</p>
-</div>
-
-<p>There are essentially two ways to deliver an application on Android: as a
-client-side application (developed using the Android SDK and installed on user devices as an {@code
-.apk}) or as a web application (developed using web standards and accessed through a web
-browser&mdash;there's nothing to install on user devices).</p>
-
-<p>The approach you choose for your application could depend on several factors, but Android makes
-the decision to develop a web application easier by providing:</p>
-<ul>
-  <li>Support for viewport properties that allow you to properly size your web application
-based on the screen size</li>
-  <li>CSS and JavaScript features that allow you to provide different styles and images
-based on the screen's pixel density (screen resolution)</li>
-</ul>
-
-<p>Thus, your decision to develop a web application for Android can exclude consideration for
-screen support, because it's already easy to make your web pages look good on all types of screens
-powered by Android.</p>
-
-<p>Another great feature of Android is that you don't have to build your application purely on
-the client or purely on the web. You can mix the two together by developing a client-side Android
-application that embeds some web pages (using a {@link android.webkit.WebView} in your Android
-application layout). Figure 1 visualizes how you can provide access to your web pages from either
-a web browser or your Android application. However, you shouldn't develop an Android
-application simply as a means to launch your web site. Rather, the web pages you embed in your
-Android application should be designed especially for that environment. You can even define an
-interface between your Android application and your web pages that allows JavaScript in the web
-pages to call upon APIs in your Android application&mdash;providing Android APIs to your web-based
-application.</p>
-
-<p>Since Android 1.0, {@link android.webkit.WebView} has been available for Android
-applications to embed web content in their layout and bind JavaScript to Android APIs. After
-Android added support for more screen densities (adding support for high and low-density
-screens), Android 2.0 added features to the WebKit framework to allow web pages to specify
-viewport properties and query the screen density in order to modify styles
-and image assets, as mentioned above. Because these features are a part of Android's WebKit
-framework, both the Android Browser (the default web browser provided with the platform) and
-{@link android.webkit.WebView} support the same viewport and screen density features.</p>
-
-<p>To develop a web application for Android-powered devices, you should read the
-following documents:</p>
-
-<dl>
-  <dt><a href="{@docRoot}guide/webapps/targeting.html"><strong>Targeting Screens from Web
-Apps</strong></a></dt>
-  <dd>How to properly size your web app on Android-powered devices and support
-multiple screen densities. The information in this document is important if you're building a web
-application that you at least expect to be available on Android-powered devices (which you should
-assume for anything you publish on the web), but especially if you're targeting mobile devices
-or using {@link android.webkit.WebView}.</dd>
-  <dt><a href="{@docRoot}guide/webapps/webview.html"><strong>Building Web Apps in
-WebView</strong></a></dt>
-  <dd>How to embed web pages into your Android application using {@link android.webkit.WebView} and
-bind JavaScript to Android APIs.</dd>
-  <dt><a href="{@docRoot}guide/webapps/debugging.html"><strong>Debugging Web Apps</strong></a></dt>
-  <dd>How to debug web apps using JavaScript Console APIs.</dd>
-  <dt><a href="{@docRoot}guide/webapps/best-practices.html"><strong>Best Practices for Web
-Apps</strong></a></dt>
-  <dd>A list of practices you should follow, in order to provide an effective web application on
-Android-powered devices.</dd>
-</dl>
-
diff --git a/docs/html/guide/webapps/targeting.jd b/docs/html/guide/webapps/targeting.jd
index 7410202..7e02340 100644
--- a/docs/html/guide/webapps/targeting.jd
+++ b/docs/html/guide/webapps/targeting.jd
@@ -1,16 +1,8 @@
-page.title=Targeting Screens from Web Apps
+page.title=Supporting Different Screens in Web Apps
 @jd:body
 
 <div id="qv-wrapper">
 <div id="qv">
-<h2>Quickview</h2>
-<ul>
-  <li>You can target your web page for different screens using viewport metadata, CSS, and
-JavaScript</li>
-  <li>Techniques in this document work for Android 2.0 and greater, and for web pages rendered
-in the default Android Browser and in a {@link android.webkit.WebView}</li>
-</ul>
-
 <h2>In this document</h2>
 <ol>
 <li><a href="#Metadata">Using Viewport Metadata</a>
@@ -24,78 +16,88 @@
 <li><a href="#DensityJS">targeting Device Density with JavaScript</a></li>
 </ol>
 
+<h2>See also</h2>
+<ul>
+  <li><a href="https://developers.google.com/chrome/mobile/docs/webview/pixelperfect"
+  >Pixel-Perfect UI in the WebView</a></li>
+  <li><a href="http://www.html5rocks.com/en/mobile/responsivedesign/" class="external-link">Creating
+  a Mobile-First Responsive Web Design</a></li>
+  <li><a href="http://www.html5rocks.com/en/mobile/high-dpi/" class="external-link">High
+  DPI Images for Variable Pixel Densities</a></li>
+</ul>
+
 </div>
 </div>
 
 
-<p>If you're developing a web application for Android or redesigning one for mobile devices, you
-should carefully consider how your web pages appear on different kinds of screens. Because
-Android is available on devices with different types of screens, you should account for some factors
-that affect the way your web pages appear on Android devices.</p>
+<p>Because Android is available on devices with a variety of screen sizes and pixel densities, you
+should account for these factors in your web design so your web pages always appear at the
+appropriate size.</p>
 
-<p class="note"><strong>Note:</strong> The features described in this document are supported
-by the Android Browser application (provided with the default Android platform) and {@link
-android.webkit.WebView} (the framework view widget for displaying web pages), on Android 2.0 and
-greater. Third-party web browsers running on Android might not support these features for
-controlling the viewport size and screen densities.</p>
 
-<p>When targeting your web pages for Android devices, there are two fundamental factors that you
+<p>When targeting your web pages for Android devices, there are two major factors that you
 should account for:</p>
 
 <dl>
-  <dt>The size of the viewport and scale of the web page</dt>
-    <dd>When the Android Browser loads a web page, the default behavior is to load the
-page in "overview mode," which provides a zoomed-out perspective of the web page. You can override
-this behavior for your web page by defining the default dimensions of the viewport or the initial
-scale of the viewport. You can also control how much the user can zoom in and out of your web
-page, if at all. The user can also disable overview mode in the
-Browser settings, so you should never assume that your page will load in overview mode. You
-should instead customize the viewport size and/or scale as appropriate for your page.</p>
-    <p>However, when your page is rendered in a {@link android.webkit.WebView}, the page loads at
-full zoom (not in "overview mode"). That is, it appears at the default size for the page,
-instead of zoomed out. (This is also how the page appears if the user disables overview
-mode.)</p></dd>
+  <dt><a href="#Viewport">The viewport</a></dt>
+    <dd>The viewport is the rectangular area that provides a drawable region for your web page.
+    You can specify several viewport properties, such as its size and initial scale. Most important
+    is the view port width, which defines the total number of horizontal pixels available from the web page's point of
+    view (the number of CSS pixels available).
+   </dd>
 
-  <dt>The device's screen density</dt>
-    <dd>The screen density (the number of pixels per inch) on an Android-powered device affects
-the resolution and size at which a web page is displayed. (There are three screen density
-categories: low, medium, and high.) The Android Browser and {@link android.webkit.WebView}
-compensate for variations in the screen
-density by scaling a web page so that all devices display the web page at the same perceivable size
-as a medium-density screen. If graphics are an important element of your web design, you
-should pay close attention to the scaling that occurs on different densities, because image scaling
-can produce artifacts (blurring and pixelation).
-      <p>To provide the best visual representation on all
-screen densities, you should control how scaling occurs by providing viewport metadata about
-your web page's target screen density and providing alternative graphics for different screen
-densities, which you can apply to different screens using CSS or JavaScript.</p></dd>
+  <dt><a href="#DensityCSS">The screen density</a></dt>
+<dd>The {@link android.webkit.WebView} class and most web browsers on Android convert your CSS
+pixel values to density-independent pixel values, so your web page appears at the same perceivable
+size as a medium-density screen (about 160dpi). However, if graphics are an important element of
+your web design, you should pay close attention to the scaling that occurs on different densities,
+because a 300px-wide image on a 320dpi screen will be scaled up (using more physical pixels per CSS
+pixel), which can produce artifacts (blurring and pixelation).</dd>
+
 </dl>
 
-<p>The rest of this document describes how you can account for these effects and provide a good
-design on multiple types of screens.</p>
 
 
 
-<h2 id="Metadata">Using Viewport Metadata</h2>
 
-<p>The viewport is the area in which your web page is drawn. Although the viewport's visible area
-matches the size of the screen,
-the viewport has its own dimensions that determine the number of pixels available to a web page.
-That is, the number of pixels available to a web page before it exceeds the screen area is
-defined by the dimensions of the viewport,
-not the dimensions of the device screen. For example, although a device screen might have a width of
-480 pixels, the viewport can have a width of 800 pixels, so that a web page designed to be 800
-pixels wide is completely visible on the screen.</p>
+<h2 id="Viewport">Specifying Viewport Properties</h2>
 
-<p>You can define properties of the viewport for your web page using the {@code "viewport"}
-property in an HTML {@code &lt;meta&gt;} tag (which must
-be placed in your document {@code &lt;head&gt;}). You can define multiple viewport properties in the
-{@code &lt;meta&gt;} tag's {@code content} attribute. For example, you can define the height and
-width of the viewport, the initial scale of the page, and the target screen density.
-Each viewport property in the {@code content} attribute must be separated by a comma.</p>
+<p>The viewport is the area in which your web page is drawn. Although the viewport's total visible
+area matches the size of the screen when zoomed all the way out, the viewport has its own pixel
+dimensions that it makes available to a web page. For example, although a device screen might
+have physical a width
+of 480 pixels, the viewport can have a width of 800 pixels. This allows a web page designed at 800
+pixels wide to be completely visible on the screen when the viewport scale is 1.0. Most web browsers on
+Android (including Chrome) set the viewport to a large size by default (known as "wide viewport
+mode" at about 980px wide). Many browsers also zoom out as far as possible, by default, to
+show the full viewport width (known as "overview mode").</p>
 
-<p>For example, the following snippet from an HTML document specifies that the viewport width
-should exactly match the device screen width and that the ability to zoom should be disabled:</p>
+<p class="note"><strong>Note:</strong>
+When your page is rendered in a {@link android.webkit.WebView}, it does not use wide viewport mode
+(the page appears at full zoom) by default. You can enable wide viewport mode
+with {@link android.webkit.WebSettings#setUseWideViewPort setUseWideViewPort()}.</p>
+
+<p>You can define properties of the viewport for your web page, such as the width and initial zoom
+level, using the {@code &lt;meta name="viewport" ...>} tag in your document
+{@code &lt;head&gt;}.</p>
+
+<p>The following syntax shows all of the
+supported viewport properties and the types of values accepted by each one:</p>
+
+<pre>
+&lt;meta name="viewport"
+      content="
+          <b>height</b> = [<em>pixel_value</em> | "device-height"] ,
+          <b>width</b> = [<em>pixel_value</em> | "device-width"] ,
+          <b>initial-scale</b> = <em>float_value</em> ,
+          <b>minimum-scale</b> = <em>float_value</em> ,
+          <b>maximum-scale</b> = <em>float_value</em> ,
+          <b>user-scalable</b> = ["yes" | "no"]
+          " /&gt;
+</pre>
+
+<p>For example, the following {@code &lt;meta&gt;} tag specifies that the viewport width
+should exactly match the device screen's width and that the ability to zoom should be disabled:</p>
 
 <pre>
 &lt;head&gt;
@@ -104,235 +106,17 @@
 &lt;/head&gt;
 </pre>
 
-<p>That's an example of just two viewport properties. The following syntax shows all of the
-supported viewport properties and the general types of values accepted by each one:</p>
 
-<pre>
-&lt;meta name="viewport"
-      content="
-          <b>height</b> = [<em>pixel_value</em> | device-height] ,
-          <b>width</b> = [<em>pixel_value</em> | device-width ] ,
-          <b>initial-scale</b> = <em>float_value</em> ,
-          <b>minimum-scale</b> = <em>float_value</em> ,
-          <b>maximum-scale</b> = <em>float_value</em> ,
-          <b>user-scalable</b> = [yes | no] ,
-          <b>target-densitydpi</b> = [<em>dpi_value</em> | device-dpi |
-                               high-dpi | medium-dpi | low-dpi]
-          " /&gt;
-</pre>
+<p>When optimizing your site for mobile devices, you should usually set the width to
+{@code "device-width"} so the size fits exactly on all devices, then use CSS media queries to 
+flexibly adapt layouts to suit different screen sizes.
 
-<p>The following sections discuss how to use each of these viewport properties and exactly what the
-accepted values are.</p>
-
-<div class="figure" style="width:300px">
-  <img src="{@docRoot}images/webapps/compare-default.png" alt="" height="300" />
-  <p class="img-caption"><strong>Figure 1.</strong> A web page with an image that's 320 pixels
-wide, in the Android Browser when there is no viewport metadata set (with "overview mode"
-enabled, the viewport is 800 pixels wide, by default).</p>
-</div>
-
-
-<div class="figure" style="width:300px">
-  <img src="{@docRoot}images/webapps/compare-width400.png" alt="" height="300" />
-  <p class="img-caption"><strong>Figure 2.</strong> A web page with viewport {@code width=400} and
-"overview mode" enabled (the image in the web page is 320 pixels wide).</p>
-</div>
-
-
-<h3 id="ViewportSize">Defining the viewport size</h3>
-
-<p>Viewport's {@code height} and {@code width} properties allow you to specify the size of the
-viewport (the number of pixels available to the web page before it goes off screen).</p>
-
-<p>As mentioned in the introduction above, the Android Browser loads pages in "overview mode" by
-default (unless disable by the user), which sets the minimum viewport width to 800 pixels. So, if
-your web page specifies its size to be 320 pixels wide, then your page appears smaller than the
-visible screen (even if the physical screen is 320 pixels wide, because the viewport simulates a
-drawable area that's 800 pixels wide), as shown in figure 1. To avoid this effect, you should
-explicitly define the viewport {@code width} to match the width for which you have designed your web
-page.</p>
-
-<p>For example, if your web page is designed to be exactly 320 pixels wide, then you might
-want to specify that size for the viewport width:</p>
-
-<pre>
-&lt;meta name="viewport" content="width=320" /&gt;
-</pre>
-
-<p>In this case, your web page exactly fits the screen width, because the web page width and
-viewport width are the same.</p>
-
-<p class="note"><strong>Note:</strong> Width values that are greater than 10,000 are ignored and
-values less than (or equal to) 320 result in a value equal to the device-width (discussed below).
-Height values that are greater then 10,000 or less than 200 are also ignored.</p>
-
-<p>To demonstrate how this property affects the size of
-your web page, figure 2 shows a web page that contains an image that's 320 pixels
-wide, but with the viewport width set to 400.</p>
-
-
-<p class="note"><strong>Note:</strong> If you set the viewport width to match your web page width
-and the device's screen width does <em>not</em> match those dimensions, then the web page
-still fits the screen even if the device has a high or low-density screen, because the
-Android Browser and {@link android.webkit.WebView} scale web pages to match the perceived size on a
-medium-density screen, by default (as you can see in figure 2, when comparing the hdpi device to the
-mdpi device). Screen densities are discussed more in <a href="#ViewportDensity">Defining the
-viewport target density</a>.</p>
-
-
-<h4>Automatic sizing</h4>
-
-<p>As an alternative to specifying the viewport dimensions with exact pixels, you can set the
-viewport size to always match the dimensions of the device screen, by defining the
-viewport properties {@code height}
-and {@code width} with the values {@code device-height} and {@code device-width}, respectively. This
-is appropriate when you're developing a web application that has a fluid width (not fixed width),
-but you want it to appear as if it's fixed (to perfectly fit every screen as
-if the web page width is set to match each screen). For example:</p>
-
-<pre>
-&lt;meta name="viewport" content="width=device-width" /&gt;
-</pre>
-
-<p>This results in the viewport width matching whatever the current screen width is, as shown in
-figure 3. It's important to notice that, this results in images being scaled to fit the screen
-when the current device does not match the <a href="#ViewportDensity">target
-density</a>, which is medium-density if you don't specify otherwise. As a result, the image
-displayed on the high-density device in figure 3 is scaled up in order to match the width
-of a screen with a medium-density screen.</p>
-
-<div class="figure" style="width:300px">
-  <img src="{@docRoot}images/webapps/compare-initialscale.png" alt="" height="300" />
-  <p class="img-caption"><strong>Figure 3.</strong> A web page with viewport {@code
-width=device-width} <em>or</em> {@code initial-scale=1.0}.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> If you instead want {@code
-device-width} and {@code device-height} to match the physical screen pixels for every device,
-instead of scaling your web page to match the target density, then you must also include
-the {@code target-densitydpi} property with a value of {@code device-dpi}. This is discussed more in
-the section about <a href="#ViewportDensity">Defining the viewport density</a>. Otherwise, simply
-using {@code device-height} and {@code device-width} to define the viewport size makes your web page
-fit every device screen, but scaling occurs on your images in order to adjust for different screen
-densities.</p>
-
-
-
-<h3 id="ViewportScale">Defining the viewport scale</h3>
-
-<p>The scale of the viewport defines the level of zoom applied to the web page. Viewport
-properties allow you to specify the scale of your web page in the following ways:</p>
-<dl>
-  <dt>{@code initial-scale}</dt>
-  <dd>The initial scale of the page. The value is a float that indicates a multiplier for your web
-page size, relative to the screen size. For example, if you set the initial scale to "1.0" then the
-web page is displayed to match the resolution of the <a href="#ViewportDensity">target
-density</a> 1-to-1. If set to "2.0", then the page is enlarged (zoomed in) by a factor of 2.
-    <p>The default initial scale is calculated to fit the web page in the viewport size.
-Because the default viewport width is 800 pixels, if the device screen resolution is less than
-800 pixels wide, the initial scale is something less than 1.0, by default, in order to fit the
-800-pixel-wide page on the screen.</p></dd>
-
-  <dt>{@code minimum-scale}</dt>
-  <dd>The minimum scale to allow. The value is a float that indicates the minimum multiplier for
-your web page size, relative to the screen size. For example, if you set this to "1.0", then the
-page can't zoom out because the minimum size is 1-to-1 with the <a href="#ViewportDensity">target
-density</a>.</dd>
-
-  <dt>{@code maximum-scale}</dt>
-  <dd>The maximum scale to allow for the page. The value is a float that indicates the
-maximum multiplier for your web page size,
-relative to the screen size. For example, if you set this to "2.0", then the page can't
-zoom in more than 2 times the target size.</dd>
-
-  <dt>{@code user-scalable}</dt>
-  <dd>Whether the user can change the scale of the page at all (zoom in and out). Set to {@code yes}
-to allow scaling and {@code no} to disallow scaling. The default is {@code yes}. If you set
-this to {@code no}, then the {@code minimum-scale} and {@code maximum-scale} are ignored,
-because scaling is not possible.</dd>
-</dl>
-
-<p>All scale values must be within the range 0.01&ndash;10.</p>
-
-<p>For example:</p>
-
-<pre>
-&lt;meta name="viewport" content="initial-scale=1.0" /&gt;
-</pre>
-
-<p>This metadata sets the initial scale to be full sized, relative to the viewport's target
-density.</p>
+<p class="note"><strong>Note:</strong> You should disable user scaling only when you're certain
+that your web page layout is flexible and the content will fit the width of small screens.</p>
 
 
 
 
-<h3 id="ViewportDensity">Defining the viewport target density</h3>
-
-<p>The density of a device's screen is based on the screen resolution, as defined by the number of
-dots per inch (dpi). There are three screen
-density categories supported by Android: low (ldpi), medium (mdpi), and high (hdpi). A screen
-with low density has fewer available pixels per inch, whereas a screen with high density has more
-pixels per inch (compared to a medium density screen). The Android Browser and {@link
-android.webkit.WebView} target a medium density screen by default.</p>
-
-
-<div class="figure" style="width:300px">
-  <img src="{@docRoot}images/webapps/compare-initialscale-devicedpi.png" alt="" height="300" />
-  <p class="img-caption"><strong>Figure 4.</strong> A web page with viewport {@code
-width=device-width} and {@code target-densitydpi=device-dpi}.</p>
-</div>
-
-
-<p>Because the default target density is medium, when users have a device with a low or high density
-screen, the Android Browser and {@link android.webkit.WebView} scale web pages (effectively zoom
-the pages) so they display at a
-size that matches the perceived appearance on a medium density screen. More specifically, the
-Android Browser and {@link android.webkit.WebView} apply approximately 1.5x scaling to web pages
-on a high density screen (because its screen pixels are smaller) and approximately 0.75x scaling to
-pages on a low density screen (because its screen pixels are bigger).</p>
-
-<p>Due to this default scaling, figures 1, 2, and 3 show the example web page at the same physical
-size on both the high and medium density device (the high-density device shows the
-web page with a default scale factor that is 1.5 times larger than the actual pixel resolution, to
-match the target density). This can introduce some undesirable artifacts in your images.
-For example, although an image appears the same size on a medium and high-density device, the image
-on the high-density device appears more blurry, because the image is designed to be 320 pixels
-wide, but is drawn with 480 pixels.</p>
-
-<p>You can change the target screen density for your web page using the {@code target-densitydpi}
-viewport property. It accepts the following values:</p>
-
-<ul>
-<li><code>device-dpi</code> - Use the device's native dpi as the target dpi. Default scaling never
-occurs.</li>
-<li><code>high-dpi</code> - Use hdpi as the target dpi. Medium and low density screens scale down
-as appropriate.</li>
-<li><code>medium-dpi</code> - Use mdpi as the target dpi. High density screens scale up and low
-density screens scale down. This is the default target density.</li>
-<li><code>low-dpi</code> - Use ldpi as the target dpi. Medium and high density screens scale up
-as appropriate.</li>
-<li><em><code>&lt;value&gt;</code></em> - Specify a dpi value to use as the target dpi. Values must
-be within the range 70&ndash;400.</li>
-</ul></p>
-
-<p>For example, to prevent the Android Browser and {@link android.webkit.WebView} from scaling
-your web page for different screen densities, set
-the {@code target-densitydpi} viewport property to {@code device-dpi}. When you do, the page is
-not scaled. Instead, the page is displayed at a size that matches the current screen's
-density. In this case, you should also define the viewport width to match the device width, so your
-web page naturally fits the screen size. For example:</p>
-
-<pre>
-&lt;meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" /&gt;
-</pre>
-
-<p>Figure 4 shows a web page using these viewport settings&mdash;the high-density device
-now displays the page smaller because its physical pixels are smaller than those on the
-medium-density device, so no scaling occurs and the 320-pixel-wide image is drawn using exactly 320
-pixels on both screens. (This is how you should define your viewport if
-you want to customize your web page based on screen density and provide different image assets for
-different densities, <a href="#DensityCSS">with CSS</a> or
-<a href="#DensityJS">with JavaScript</a>.)</p>
 
 
 <h2 id="DensityCSS">Targeting Device Density with CSS</h2>
@@ -349,17 +133,9 @@
 <pre>
 &lt;link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.5)" href="hdpi.css" /&gt;
 &lt;link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.0)" href="mdpi.css" /&gt;
-&lt;link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 0.75)" href="ldpi.css" /&gt;
 </pre>
 
 
-<div class="figure" style="width:300px">
-  <img src="{@docRoot}images/webapps/compare-width-devicedpi-css.png" alt="" height="300" />
-  <p class="img-caption"><strong>Figure 5.</strong> A web page with CSS that's targetted to
-specific screen densities using the {@code -webkit-device-pixel-ratio} media feature. Notice
-that the hdpi device shows a different image that's applied in CSS.</p>
-</div>
-
 <p>Or, specify the different styles in one stylesheet:</p>
 
 <pre class="no-pretty-print">
@@ -382,27 +158,10 @@
 }
 </pre>
 
-<p class="note"><strong>Note:</strong> The default style for {@code #header} applies the image
-designed for medium-density devices in order to support devices running a version of Android less
-than 2.0, which do not support the {@code -webkit-device-pixel-ratio} media feature.</p>
 
-<p>The types of styles you might want to adjust based on the screen density depend on how you've
-defined your viewport properties. To provide fully-customized styles that tailor your web page for
-each of the supported densities, you should set your viewport properties so the viewport width and
-density match the device. That is:</p>
-
-<pre>
-&lt;meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" /&gt;
-</pre>
-
-<p>This way, the Android Browser and {@link android.webkit.WebView} do not perform scaling on your
-web page and the viewport width
-matches the screen width exactly. On their own, these viewport properties create results shown in
-figure 4. However, by adding some custom CSS using the {@code -webkit-device-pixel-ratio} media
-feature, you can apply different styles. For example, figure 5 shows a web page with these viewport
-properties and also some CSS added that applies a high-resolution image for high-density
-screens.</p>
-
+<p>For more information about handling different screen densities, especially images, see
+<a href="http://www.html5rocks.com/en/mobile/high-dpi/" class="external-link">High
+  DPI Images for Variable Pixel Densities</a>.</li>
 
 
 <h2 id="DensityJS">Targeting Device Density with JavaScript</h2>
@@ -432,8 +191,3 @@
 </pre>
 
 
-
-
-
-
-
diff --git a/docs/html/guide/webapps/webview.jd b/docs/html/guide/webapps/webview.jd
index c87be06..9b46b5b 100644
--- a/docs/html/guide/webapps/webview.jd
+++ b/docs/html/guide/webapps/webview.jd
@@ -136,7 +136,6 @@
 setUserAgentString()}, then query the custom user agent in your web page to verify that the
 client requesting your web page is actually your Android application.</p>
 
-from your Android SDK {@code tools/} directory
 <h3 id="BindingJavaScript">Binding JavaScript code to Android code</h3>
 
 <p>When developing a web application that's designed specifically for the {@link
diff --git a/docs/html/images/distribute/hichat-n5-port.jpg b/docs/html/images/distribute/hichat-n5-port.jpg
new file mode 100644
index 0000000..b93e983
--- /dev/null
+++ b/docs/html/images/distribute/hichat-n5-port.jpg
Binary files differ
diff --git a/docs/html/images/distribute/indian-rummy-n4-land.jpg b/docs/html/images/distribute/indian-rummy-n4-land.jpg
new file mode 100644
index 0000000..61943fc
--- /dev/null
+++ b/docs/html/images/distribute/indian-rummy-n4-land.jpg
Binary files differ
diff --git a/docs/html/images/distribute/zombie-ragdoll-n5-land.jpg b/docs/html/images/distribute/zombie-ragdoll-n5-land.jpg
new file mode 100644
index 0000000..e2bf6b5
--- /dev/null
+++ b/docs/html/images/distribute/zombie-ragdoll-n5-land.jpg
Binary files differ
diff --git a/docs/html/images/gcm/CCS-ack.png b/docs/html/images/gcm/CCS-ack.png
new file mode 100644
index 0000000..bce2ab2
--- /dev/null
+++ b/docs/html/images/gcm/CCS-ack.png
Binary files differ
diff --git a/docs/html/images/gcm/GCM-arch.png b/docs/html/images/gcm/GCM-arch.png
new file mode 100644
index 0000000..e8ffb15
--- /dev/null
+++ b/docs/html/images/gcm/GCM-arch.png
Binary files differ
diff --git a/docs/html/images/gp-edu-ads-iab.png b/docs/html/images/gp-edu-ads-iab.png
new file mode 100644
index 0000000..07ccaee
--- /dev/null
+++ b/docs/html/images/gp-edu-ads-iab.png
Binary files differ
diff --git a/docs/html/images/gp-edu-apps-n7.jpg b/docs/html/images/gp-edu-apps-n7.jpg
new file mode 100644
index 0000000..c2e3e21
--- /dev/null
+++ b/docs/html/images/gp-edu-apps-n7.jpg
Binary files differ
diff --git a/docs/html/images/gp-edu-hero14.jpg b/docs/html/images/gp-edu-hero14.jpg
new file mode 100644
index 0000000..69b02e2
--- /dev/null
+++ b/docs/html/images/gp-edu-hero14.jpg
Binary files differ
diff --git a/docs/html/images/gp-edu-hero7.png b/docs/html/images/gp-edu-hero7.png
deleted file mode 100644
index 84abdef..0000000
--- a/docs/html/images/gp-edu-hero7.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/gp-edu-knum-landscape.png b/docs/html/images/gp-edu-knum-landscape.png
deleted file mode 100644
index aaec6dc..0000000
--- a/docs/html/images/gp-edu-knum-landscape.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/kk-devices.png b/docs/html/images/kk-devices.png
new file mode 100644
index 0000000..3c7bbf1
--- /dev/null
+++ b/docs/html/images/kk-devices.png
Binary files differ
diff --git a/docs/html/images/nfc/dual-mode.png b/docs/html/images/nfc/dual-mode.png
index 8e484a8..ea32551 100644
--- a/docs/html/images/nfc/dual-mode.png
+++ b/docs/html/images/nfc/dual-mode.png
Binary files differ
diff --git a/docs/html/images/nfc/dual-mode@2x.png b/docs/html/images/nfc/dual-mode@2x.png
new file mode 100644
index 0000000..47184f8
--- /dev/null
+++ b/docs/html/images/nfc/dual-mode@2x.png
Binary files differ
diff --git a/docs/html/images/nfc/host-based-card.png b/docs/html/images/nfc/host-based-card.png
index 0431b27..9d5d190 100644
--- a/docs/html/images/nfc/host-based-card.png
+++ b/docs/html/images/nfc/host-based-card.png
Binary files differ
diff --git a/docs/html/images/nfc/host-based-card@2x.png b/docs/html/images/nfc/host-based-card@2x.png
new file mode 100644
index 0000000..9606f64
--- /dev/null
+++ b/docs/html/images/nfc/host-based-card@2x.png
Binary files differ
diff --git a/docs/html/images/nfc/protocol-stack.png b/docs/html/images/nfc/protocol-stack.png
index 71bdfe9..e4d118d 100644
--- a/docs/html/images/nfc/protocol-stack.png
+++ b/docs/html/images/nfc/protocol-stack.png
Binary files differ
diff --git a/docs/html/images/nfc/protocol-stack@2x.png b/docs/html/images/nfc/protocol-stack@2x.png
new file mode 100644
index 0000000..d7856e8
--- /dev/null
+++ b/docs/html/images/nfc/protocol-stack@2x.png
Binary files differ
diff --git a/docs/html/images/nfc/secure-element.png b/docs/html/images/nfc/secure-element.png
index c8133de..9ade250 100644
--- a/docs/html/images/nfc/secure-element.png
+++ b/docs/html/images/nfc/secure-element.png
Binary files differ
diff --git a/docs/html/images/nfc/secure-element@2x.png b/docs/html/images/nfc/secure-element@2x.png
new file mode 100644
index 0000000..bb4dadc
--- /dev/null
+++ b/docs/html/images/nfc/secure-element@2x.png
Binary files differ
diff --git a/docs/html/images/opengl/ogl-triangle-projected.png b/docs/html/images/opengl/ogl-triangle-projected.png
index d10bbdc..4b18b98 100644
--- a/docs/html/images/opengl/ogl-triangle-projected.png
+++ b/docs/html/images/opengl/ogl-triangle-projected.png
Binary files differ
diff --git a/docs/html/images/opengl/ogl-triangle-touch.png b/docs/html/images/opengl/ogl-triangle-touch.png
index 35177a4..8323dd9 100644
--- a/docs/html/images/opengl/ogl-triangle-touch.png
+++ b/docs/html/images/opengl/ogl-triangle-touch.png
Binary files differ
diff --git a/docs/html/images/opengl/ogl-triangle.png b/docs/html/images/opengl/ogl-triangle.png
index 3d4a385..66047ab 100644
--- a/docs/html/images/opengl/ogl-triangle.png
+++ b/docs/html/images/opengl/ogl-triangle.png
Binary files differ
diff --git a/docs/html/images/systrace/systrace-button.png b/docs/html/images/systrace/systrace-button.png
new file mode 100644
index 0000000..7d93ad0
--- /dev/null
+++ b/docs/html/images/systrace/systrace-button.png
Binary files differ
diff --git a/docs/html/images/tools/sync-project.png b/docs/html/images/tools/sync-project.png
new file mode 100644
index 0000000..09e1835
--- /dev/null
+++ b/docs/html/images/tools/sync-project.png
Binary files differ
diff --git a/docs/html/images/training/imm-states.png b/docs/html/images/training/imm-states.png
new file mode 100644
index 0000000..59c4092
--- /dev/null
+++ b/docs/html/images/training/imm-states.png
Binary files differ
diff --git a/docs/html/images/training/imm-sticky.png b/docs/html/images/training/imm-sticky.png
new file mode 100644
index 0000000..31b118a
--- /dev/null
+++ b/docs/html/images/training/imm-sticky.png
Binary files differ
diff --git a/docs/html/images/training/system-ui.png b/docs/html/images/training/system-ui.png
index a3aea65..2c13c75 100644
--- a/docs/html/images/training/system-ui.png
+++ b/docs/html/images/training/system-ui.png
Binary files differ
diff --git a/docs/html/images/webapps/web-viewport-320@2x.png b/docs/html/images/webapps/web-viewport-320@2x.png
new file mode 100644
index 0000000..f6b2bac
--- /dev/null
+++ b/docs/html/images/webapps/web-viewport-320@2x.png
Binary files differ
diff --git a/docs/html/images/webapps/web-viewport-default@2x.png b/docs/html/images/webapps/web-viewport-default@2x.png
new file mode 100644
index 0000000..a3f8d53
--- /dev/null
+++ b/docs/html/images/webapps/web-viewport-default@2x.png
Binary files differ
diff --git a/docs/html/images/webapps/web-viewport-devicewidth@2x.png b/docs/html/images/webapps/web-viewport-devicewidth@2x.png
new file mode 100644
index 0000000..3832f4c
--- /dev/null
+++ b/docs/html/images/webapps/web-viewport-devicewidth@2x.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 5c805f8..191e0fb 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -1,6 +1,7 @@
 fullpage=true
 no_footer_links=true
 carousel=true
+excludeFromSuggestions=true
 page.metaDescription=The official site for Android developers. Provides the Android SDK and documentation for app developers and designers.
 page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3f61-WpRguHq-aNjtF7xJjMTSi79as" />
 
@@ -14,78 +15,62 @@
         <a href="" class="slideshow-next">Next</a>
         <div class="frame">
             <ul>
+                <!-- set explicit widths as needed to prevent overflow issues -->
 
                 <li class="item carousel-home">
-                    <div class="content-left col-7">
-                        <a href="/about/versions/kitkat.html"><img src="/images/home/kk-hero.jpg" style="width:242px;padding-top:72px;"></a>
-                    </div>
-                    <div class="content-right col-6">
+                  <div class="content-left col-7" style="width:400px;">
+                    <a href="{@docRoot}about/versions/kitkat.html">
+                      <img src="{@docRoot}images/home/kk-hero.jpg" width="242" style="padding-top:72px;">
+                    </a>
+                  </div>
+                  <div class="content-right col-4" style="width:340px;">
                     <h1>Android 4.4 KitKat!</h1>
                     <p>A new version of Android is here, with great new features, APIs, and tools for developers.</p>
                     <p>Android 4.4 is built to run on more devices than ever before, and gives you more ways to showcase your content and create beautiful, useful, and innovative apps.</p>
                     <p>Learn about what's new in the Platform Highlights and see the API Overview for details.</p>
-                    <p><a href="/about/versions/kitkat.html" class="button">Check out the highlights</a></p>
-                    </div>
+                    <p><a href="{@docRoot}about/versions/kitkat.html" class="button">Check out the highlights</a></p>
+                  </div>
                 </li>
 
                 <li class="item carousel-home">
-                    <div class="content-left col-11" style="padding-top:65px;">
-                      <a href="https://www.youtube.com/watch?v=sONcojECWXs&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K&index=1">
-                                          <img src="/images/title-devbytes-kk.jpg" style="margin-top:22px;width:600px;">
-                        </a>
-                      </div>
-
-                    <div class="content-right col-4">
+                  <div class="content-left col-11" style="padding-top:65px;">
+                    <a href="https://www.youtube.com/watch?v=sONcojECWXs&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K&index=1">
+                      <img src="{@docRoot}images/title-devbytes-kk.jpg" style="margin-top:0px;width:600px;">
+                    </a>
+                  </div>
+                  <div class="content-right col-4">
                     <h1 style="white-space:nowrap;line-height:1.2em;">DevBytes: <br />Android 4.4</h1>
                     <p>Join the DevBytes team for a look at what's new in Android 4.4 KitKat&nbsp;&mdash; new ways to make your apps beautiful, printing, storage access framework, and more.</p>
                     <p><a href="https://www.youtube.com/watch?v=sONcojECWXs&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K&index=1" class="button">Watch the video </a></p>
-                    </div>
+                  </div>
                 </li>
 
-
                 <li class="item carousel-home">
-                    <div class="content-left col-10"><a href="/design/patterns/new.html">
-                        <img src="/design/media/design_elements_landing.png" style="margin-top:30px">
-                        </a>
-                    </div>
-                    <div class="content-right col-5">
+                  <div class="content-left col-19" style="width:580px;">
+                    <a href="{@docRoot}design/patterns/new.html">
+                      <img src="{@docRoot}design/media/design_elements_landing.png" style="margin-top:30px">
+                    </a>
+                  </div>
+                  <div class="content-right col-4" style="width:280px;">
                     <h1>Design for Android KitKat</h1>
                     <p>Android KitKat brings a refreshed UI with updated styles, patterns, and gestures to use in your apps. </p>
                     <p>We've updated the Android Design guidelines and added new pages on branding, fullscreen, and more. </p>
-                    <p><a href="/design/patterns/new.html" class="button">See what's new</a></p>
-                    </div>
+                    <p><a href="{@docRoot}design/patterns/new.html" class="button">See what's new</a></p>
+                  </div>
                 </li>
 
-                <!--<li class="item carousel-home">
-                    <div class="content-left col-11" style="padding-top:65px;">
-                      <a href="http://www.youtube.com/watch?v=6QHkv-bSlds&list=PLWz5rJ2EKKc8j2B95zGMb8muZvrIy-wcF&index=1">
-                                          <img src="/images/title-adia-kk.png" style="margin-top:22px;width:600px;">
-                        </a>
-                      </div>
-
-                    <div class="content-right col-4">
+                <li class="item carousel-home">
+                  <div class="content-left col-11" style="padding-top:65px;">
+                    <a href="http://www.youtube.com/watch?v=6QHkv-bSlds&list=PLWz5rJ2EKKc8j2B95zGMb8muZvrIy-wcF&index=1">
+                      <img src="{@docRoot}images/title-adia-kk.png" style="margin-top:0px;width:600px;">
+                    </a>
+                  </div>
+                  <div class="content-right col-4">
                     <h1 style="white-space:nowrap;line-height:1.2em;">ADIA: <br />Android 4.4</h1>
                     </p>Join the Android Design in Action team for a walkthrough of new developer features, UX changes, and updates to design guidelines in Android 4.4.</p>
                     <p><a href="http://www.youtube.com/watch?v=6QHkv-bSlds&list=PLWz5rJ2EKKc8j2B95zGMb8muZvrIy-wcF&index=1" class="button">Watch the video </a></p>
-                    </div>
-                </li> -->
-               <!-- <li class="item carousel-home">
-                    <div class="content-left col-11" style="padding-top:10px;">
-                        <a href="/channels/io2013.html">
-                          <img src="/images/home/io-videos-2013.png" style="margin:60px 0 0;
-                          box-shadow: 3px 10px 18px 1px #999;">
-                        </a>
-                    </div>
-                    <div class="content-right col-4">
-                    <h1>Hands-on with New KitKat Features</h1>
-                    <p>If you weren't able to attend Google I/O in person or couldn't make it
-                    to all the talks, you can catch up on the action
-                    with all the recordings, brought to you by
-                    <a href="http://developers.google.com/live">Google Developers Live</a>.</p>
-                    <p><a href="/channels/io2013.html" class="button"
-                    >See the Android talks</a></p>
-                    </div>
-                </li> -->
+                  </div>
+                </li>
            </ul>
         </div>
     </div>
diff --git a/docs/html/license.jd b/docs/html/license.jd
index 20e68fa..b98c912 100644
--- a/docs/html/license.jd
+++ b/docs/html/license.jd
@@ -1,5 +1,6 @@
 page.title=Content License
 fullpage=1
+excludeFromSuggestions=true
 @jd:body
 
 <div class="wrap" style="width:940px;">
diff --git a/docs/html/offline.jd b/docs/html/offline.jd
index 73da779..6d4483f 100644
--- a/docs/html/offline.jd
+++ b/docs/html/offline.jd
@@ -1,5 +1,6 @@
 home=true
 page.title=Welcome
+excludeFromSuggestions=true
 @jd:body
 
 <style type="text/css">
diff --git a/docs/html/reference/com/google/android/gms/R.attr.html b/docs/html/reference/com/google/android/gms/R.attr.html
index 1e4794f..d1de6ff 100644
--- a/docs/html/reference/com/google/android/gms/R.attr.html
+++ b/docs/html/reference/com/google/android/gms/R.attr.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/R.color.html b/docs/html/reference/com/google/android/gms/R.color.html
index e18f487..47bba85 100644
--- a/docs/html/reference/com/google/android/gms/R.color.html
+++ b/docs/html/reference/com/google/android/gms/R.color.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/R.drawable.html b/docs/html/reference/com/google/android/gms/R.drawable.html
index 3946968..deb40c2 100644
--- a/docs/html/reference/com/google/android/gms/R.drawable.html
+++ b/docs/html/reference/com/google/android/gms/R.drawable.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/R.html b/docs/html/reference/com/google/android/gms/R.html
index e731b8e..4eec6ae 100644
--- a/docs/html/reference/com/google/android/gms/R.html
+++ b/docs/html/reference/com/google/android/gms/R.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/R.id.html b/docs/html/reference/com/google/android/gms/R.id.html
index dc59f21..f5c0a9a 100644
--- a/docs/html/reference/com/google/android/gms/R.id.html
+++ b/docs/html/reference/com/google/android/gms/R.id.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/R.integer.html b/docs/html/reference/com/google/android/gms/R.integer.html
index 1c72378..ff5338d 100644
--- a/docs/html/reference/com/google/android/gms/R.integer.html
+++ b/docs/html/reference/com/google/android/gms/R.integer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/R.string.html b/docs/html/reference/com/google/android/gms/R.string.html
index cf92f5c..ee2e867 100644
--- a/docs/html/reference/com/google/android/gms/R.string.html
+++ b/docs/html/reference/com/google/android/gms/R.string.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/R.styleable.html b/docs/html/reference/com/google/android/gms/R.styleable.html
index 7f37faf..a151380 100644
--- a/docs/html/reference/com/google/android/gms/R.styleable.html
+++ b/docs/html/reference/com/google/android/gms/R.styleable.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/AdListener.html b/docs/html/reference/com/google/android/gms/ads/AdListener.html
index 5665c54..321230f 100644
--- a/docs/html/reference/com/google/android/gms/ads/AdListener.html
+++ b/docs/html/reference/com/google/android/gms/ads/AdListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/AdRequest.Builder.html b/docs/html/reference/com/google/android/gms/ads/AdRequest.Builder.html
index 2a3d395..f1088d0 100644
--- a/docs/html/reference/com/google/android/gms/ads/AdRequest.Builder.html
+++ b/docs/html/reference/com/google/android/gms/ads/AdRequest.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/AdRequest.html b/docs/html/reference/com/google/android/gms/ads/AdRequest.html
index d5d9738..951173a 100644
--- a/docs/html/reference/com/google/android/gms/ads/AdRequest.html
+++ b/docs/html/reference/com/google/android/gms/ads/AdRequest.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/AdSize.html b/docs/html/reference/com/google/android/gms/ads/AdSize.html
index 6724572..81b7ae4 100644
--- a/docs/html/reference/com/google/android/gms/ads/AdSize.html
+++ b/docs/html/reference/com/google/android/gms/ads/AdSize.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/AdView.html b/docs/html/reference/com/google/android/gms/ads/AdView.html
index cc1f550..85ec19d 100644
--- a/docs/html/reference/com/google/android/gms/ads/AdView.html
+++ b/docs/html/reference/com/google/android/gms/ads/AdView.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/InterstitialAd.html b/docs/html/reference/com/google/android/gms/ads/InterstitialAd.html
index c1c3fe0..5c7b0c9 100644
--- a/docs/html/reference/com/google/android/gms/ads/InterstitialAd.html
+++ b/docs/html/reference/com/google/android/gms/ads/InterstitialAd.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html b/docs/html/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html
index e8d832d..c4bb33e 100644
--- a/docs/html/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html
+++ b/docs/html/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html b/docs/html/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html
index b1d6731..11ca36f 100644
--- a/docs/html/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html
+++ b/docs/html/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
@@ -752,7 +763,7 @@
  <p>
  It is intended that the advertising ID completely replace existing usage of other
  identifiers for ads purposes (such as use of <code>ANDROID_ID</code> in
- <code><a href="/">ERROR(/Settings.Secure)</a></code>) when Google Play Services is available. Cases where
+ <code><a href="/reference/android/provider/Settings.Secure.html">Settings.Secure</a></code>) when Google Play Services is available. Cases where
  Google Play Services is unavailable are indicated by a
  <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesNotAvailableException.html">GooglePlayServicesNotAvailableException</a></code> being thrown by getAdvertisingIdInfo().
 </p>
@@ -1204,7 +1215,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>context</td>
-          <td>Current <code><a href="/reference/android/content/Context.html">Context</a></code> (such as the current <code><a href="/">ERROR(/Activity)</a></code>).</td>
+          <td>Current <code><a href="/reference/android/content/Context.html">Context</a></code> (such as the current <code><a href="/reference/android/app/Activity.html">Activity</a></code>).</td>
         </tr>
       </table>
   </div>
diff --git a/docs/html/reference/com/google/android/gms/ads/identifier/package-summary.html b/docs/html/reference/com/google/android/gms/ads/identifier/package-summary.html
index 59f719a..f20721a 100644
--- a/docs/html/reference/com/google/android/gms/ads/identifier/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/ads/identifier/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/mediation/NetworkExtras.html b/docs/html/reference/com/google/android/gms/ads/mediation/NetworkExtras.html
index c82c4f6..baf2486 100644
--- a/docs/html/reference/com/google/android/gms/ads/mediation/NetworkExtras.html
+++ b/docs/html/reference/com/google/android/gms/ads/mediation/NetworkExtras.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/mediation/admob/AdMobExtras.html b/docs/html/reference/com/google/android/gms/ads/mediation/admob/AdMobExtras.html
index 6d1aa4a..1befa17 100644
--- a/docs/html/reference/com/google/android/gms/ads/mediation/admob/AdMobExtras.html
+++ b/docs/html/reference/com/google/android/gms/ads/mediation/admob/AdMobExtras.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/mediation/admob/package-summary.html b/docs/html/reference/com/google/android/gms/ads/mediation/admob/package-summary.html
index 7117324..d1333de 100644
--- a/docs/html/reference/com/google/android/gms/ads/mediation/admob/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/ads/mediation/admob/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/mediation/customevent/CustomEventExtras.html b/docs/html/reference/com/google/android/gms/ads/mediation/customevent/CustomEventExtras.html
index 3d4c0f3..d2db70e 100644
--- a/docs/html/reference/com/google/android/gms/ads/mediation/customevent/CustomEventExtras.html
+++ b/docs/html/reference/com/google/android/gms/ads/mediation/customevent/CustomEventExtras.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/mediation/customevent/package-summary.html b/docs/html/reference/com/google/android/gms/ads/mediation/customevent/package-summary.html
index b2e831e..14f321f 100644
--- a/docs/html/reference/com/google/android/gms/ads/mediation/customevent/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/ads/mediation/customevent/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/mediation/package-summary.html b/docs/html/reference/com/google/android/gms/ads/mediation/package-summary.html
index c6ca1d6..635eff2 100644
--- a/docs/html/reference/com/google/android/gms/ads/mediation/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/ads/mediation/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/ads/package-summary.html b/docs/html/reference/com/google/android/gms/ads/package-summary.html
index 8c96a79..ea28ff1 100644
--- a/docs/html/reference/com/google/android/gms/ads/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/ads/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/appstate/AppState.html b/docs/html/reference/com/google/android/gms/appstate/AppState.html
index bc61b35..356d960 100644
--- a/docs/html/reference/com/google/android/gms/appstate/AppState.html
+++ b/docs/html/reference/com/google/android/gms/appstate/AppState.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/appstate/AppStateBuffer.html b/docs/html/reference/com/google/android/gms/appstate/AppStateBuffer.html
index e4e34a6..9b62726 100644
--- a/docs/html/reference/com/google/android/gms/appstate/AppStateBuffer.html
+++ b/docs/html/reference/com/google/android/gms/appstate/AppStateBuffer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/appstate/AppStateClient.Builder.html b/docs/html/reference/com/google/android/gms/appstate/AppStateClient.Builder.html
index ab28269..abf8e78 100644
--- a/docs/html/reference/com/google/android/gms/appstate/AppStateClient.Builder.html
+++ b/docs/html/reference/com/google/android/gms/appstate/AppStateClient.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/appstate/AppStateClient.html b/docs/html/reference/com/google/android/gms/appstate/AppStateClient.html
index 2ea169f..d5809a6 100644
--- a/docs/html/reference/com/google/android/gms/appstate/AppStateClient.html
+++ b/docs/html/reference/com/google/android/gms/appstate/AppStateClient.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/appstate/OnSignOutCompleteListener.html b/docs/html/reference/com/google/android/gms/appstate/OnSignOutCompleteListener.html
index 4bd073e..0c32261 100644
--- a/docs/html/reference/com/google/android/gms/appstate/OnSignOutCompleteListener.html
+++ b/docs/html/reference/com/google/android/gms/appstate/OnSignOutCompleteListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/appstate/OnStateDeletedListener.html b/docs/html/reference/com/google/android/gms/appstate/OnStateDeletedListener.html
index b145688..70a762e 100644
--- a/docs/html/reference/com/google/android/gms/appstate/OnStateDeletedListener.html
+++ b/docs/html/reference/com/google/android/gms/appstate/OnStateDeletedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/appstate/OnStateListLoadedListener.html b/docs/html/reference/com/google/android/gms/appstate/OnStateListLoadedListener.html
index 0f2cefb..73da7d9 100644
--- a/docs/html/reference/com/google/android/gms/appstate/OnStateListLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/appstate/OnStateListLoadedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/appstate/OnStateLoadedListener.html b/docs/html/reference/com/google/android/gms/appstate/OnStateLoadedListener.html
index e4ce5ed..9442754 100644
--- a/docs/html/reference/com/google/android/gms/appstate/OnStateLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/appstate/OnStateLoadedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/appstate/package-summary.html b/docs/html/reference/com/google/android/gms/appstate/package-summary.html
index da6cd9a..50ef3d7 100644
--- a/docs/html/reference/com/google/android/gms/appstate/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/appstate/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/auth/GoogleAuthException.html b/docs/html/reference/com/google/android/gms/auth/GoogleAuthException.html
index 2d6392e..5de9deb 100644
--- a/docs/html/reference/com/google/android/gms/auth/GoogleAuthException.html
+++ b/docs/html/reference/com/google/android/gms/auth/GoogleAuthException.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/auth/GoogleAuthUtil.html b/docs/html/reference/com/google/android/gms/auth/GoogleAuthUtil.html
index 74f6dac..7f74d08 100644
--- a/docs/html/reference/com/google/android/gms/auth/GoogleAuthUtil.html
+++ b/docs/html/reference/com/google/android/gms/auth/GoogleAuthUtil.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/auth/GooglePlayServicesAvailabilityException.html b/docs/html/reference/com/google/android/gms/auth/GooglePlayServicesAvailabilityException.html
index 2600f30..56c3d6c 100644
--- a/docs/html/reference/com/google/android/gms/auth/GooglePlayServicesAvailabilityException.html
+++ b/docs/html/reference/com/google/android/gms/auth/GooglePlayServicesAvailabilityException.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/auth/RecoveryDecision.html b/docs/html/reference/com/google/android/gms/auth/RecoveryDecision.html
index 59a1346..f375b27 100644
--- a/docs/html/reference/com/google/android/gms/auth/RecoveryDecision.html
+++ b/docs/html/reference/com/google/android/gms/auth/RecoveryDecision.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/auth/UserRecoverableAuthException.html b/docs/html/reference/com/google/android/gms/auth/UserRecoverableAuthException.html
index 6d39781..efcc752 100644
--- a/docs/html/reference/com/google/android/gms/auth/UserRecoverableAuthException.html
+++ b/docs/html/reference/com/google/android/gms/auth/UserRecoverableAuthException.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/auth/UserRecoverableNotifiedException.html b/docs/html/reference/com/google/android/gms/auth/UserRecoverableNotifiedException.html
index 39ae993..3f454ee 100644
--- a/docs/html/reference/com/google/android/gms/auth/UserRecoverableNotifiedException.html
+++ b/docs/html/reference/com/google/android/gms/auth/UserRecoverableNotifiedException.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/auth/package-summary.html b/docs/html/reference/com/google/android/gms/auth/package-summary.html
index 4f3165a..62cff8b 100644
--- a/docs/html/reference/com/google/android/gms/auth/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/auth/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/AccountPicker.html b/docs/html/reference/com/google/android/gms/common/AccountPicker.html
index 8697b8f..036b371 100644
--- a/docs/html/reference/com/google/android/gms/common/AccountPicker.html
+++ b/docs/html/reference/com/google/android/gms/common/AccountPicker.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/ConnectionResult.html b/docs/html/reference/com/google/android/gms/common/ConnectionResult.html
index 84d7f54..1412ec2 100644
--- a/docs/html/reference/com/google/android/gms/common/ConnectionResult.html
+++ b/docs/html/reference/com/google/android/gms/common/ConnectionResult.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html
index 1bc1f05..bb50850 100644
--- a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html
+++ b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html
index a1f52be..b7b196e 100644
--- a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html
+++ b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.html b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.html
index ce3cd96..3b3c9be 100644
--- a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.html
+++ b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesNotAvailableException.html b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesNotAvailableException.html
index d8be4dd..2cd04b9 100644
--- a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesNotAvailableException.html
+++ b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesNotAvailableException.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesRepairableException.html b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesRepairableException.html
index a454fb0..f03309f 100644
--- a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesRepairableException.html
+++ b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesRepairableException.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesUtil.html b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesUtil.html
index ca25152..f891479 100644
--- a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesUtil.html
+++ b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesUtil.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
@@ -1315,8 +1326,8 @@
         <span class="jd-tagtitle">Constant Value: </span>
         <span>
             
-                4030000
-                (0x003d7e30)
+                4034000
+                (0x003d8dd0)
             
         </span>
         </div>
diff --git a/docs/html/reference/com/google/android/gms/common/Scopes.html b/docs/html/reference/com/google/android/gms/common/Scopes.html
index 76618ff..98e6ddd 100644
--- a/docs/html/reference/com/google/android/gms/common/Scopes.html
+++ b/docs/html/reference/com/google/android/gms/common/Scopes.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/SignInButton.html b/docs/html/reference/com/google/android/gms/common/SignInButton.html
index efe6661..cc09fff 100644
--- a/docs/html/reference/com/google/android/gms/common/SignInButton.html
+++ b/docs/html/reference/com/google/android/gms/common/SignInButton.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/UserRecoverableException.html b/docs/html/reference/com/google/android/gms/common/UserRecoverableException.html
index 4fbaf32..a6162b7 100644
--- a/docs/html/reference/com/google/android/gms/common/UserRecoverableException.html
+++ b/docs/html/reference/com/google/android/gms/common/UserRecoverableException.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/annotation/KeepName.html b/docs/html/reference/com/google/android/gms/common/annotation/KeepName.html
index 7d58ef2..ad44294 100644
--- a/docs/html/reference/com/google/android/gms/common/annotation/KeepName.html
+++ b/docs/html/reference/com/google/android/gms/common/annotation/KeepName.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/data/DataBuffer.html b/docs/html/reference/com/google/android/gms/common/data/DataBuffer.html
index b7c9f29..19f8d2d 100644
--- a/docs/html/reference/com/google/android/gms/common/data/DataBuffer.html
+++ b/docs/html/reference/com/google/android/gms/common/data/DataBuffer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/data/DataBufferUtils.html b/docs/html/reference/com/google/android/gms/common/data/DataBufferUtils.html
index 1317c78..63074f5 100644
--- a/docs/html/reference/com/google/android/gms/common/data/DataBufferUtils.html
+++ b/docs/html/reference/com/google/android/gms/common/data/DataBufferUtils.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/data/Freezable.html b/docs/html/reference/com/google/android/gms/common/data/Freezable.html
index 4b3f9602..5e49bf5 100644
--- a/docs/html/reference/com/google/android/gms/common/data/Freezable.html
+++ b/docs/html/reference/com/google/android/gms/common/data/Freezable.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/data/package-summary.html b/docs/html/reference/com/google/android/gms/common/data/package-summary.html
index 43fec35..479afbb 100644
--- a/docs/html/reference/com/google/android/gms/common/data/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/common/data/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html b/docs/html/reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html
index 237a57c..6c41369 100644
--- a/docs/html/reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/images/ImageManager.html b/docs/html/reference/com/google/android/gms/common/images/ImageManager.html
index a1613a0..121e38a6 100644
--- a/docs/html/reference/com/google/android/gms/common/images/ImageManager.html
+++ b/docs/html/reference/com/google/android/gms/common/images/ImageManager.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/images/package-summary.html b/docs/html/reference/com/google/android/gms/common/images/package-summary.html
index 4d0498b..091f541 100644
--- a/docs/html/reference/com/google/android/gms/common/images/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/common/images/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/common/package-summary.html b/docs/html/reference/com/google/android/gms/common/package-summary.html
index 851ba14..4cfbc17 100644
--- a/docs/html/reference/com/google/android/gms/common/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/common/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/Game.html b/docs/html/reference/com/google/android/gms/games/Game.html
index c26ce43..b2d3254 100644
--- a/docs/html/reference/com/google/android/gms/games/Game.html
+++ b/docs/html/reference/com/google/android/gms/games/Game.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/GameBuffer.html b/docs/html/reference/com/google/android/gms/games/GameBuffer.html
index dbd040e..3b1582c 100644
--- a/docs/html/reference/com/google/android/gms/games/GameBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/GameBuffer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/GameEntity.html b/docs/html/reference/com/google/android/gms/games/GameEntity.html
index 60d1867..b279344 100644
--- a/docs/html/reference/com/google/android/gms/games/GameEntity.html
+++ b/docs/html/reference/com/google/android/gms/games/GameEntity.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/GamesActivityResultCodes.html b/docs/html/reference/com/google/android/gms/games/GamesActivityResultCodes.html
index 1213a32..caec38e 100644
--- a/docs/html/reference/com/google/android/gms/games/GamesActivityResultCodes.html
+++ b/docs/html/reference/com/google/android/gms/games/GamesActivityResultCodes.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/GamesClient.Builder.html b/docs/html/reference/com/google/android/gms/games/GamesClient.Builder.html
index 0de7ffa..28bd52c 100644
--- a/docs/html/reference/com/google/android/gms/games/GamesClient.Builder.html
+++ b/docs/html/reference/com/google/android/gms/games/GamesClient.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/GamesClient.html b/docs/html/reference/com/google/android/gms/games/GamesClient.html
index cb89c93..20f3072 100644
--- a/docs/html/reference/com/google/android/gms/games/GamesClient.html
+++ b/docs/html/reference/com/google/android/gms/games/GamesClient.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/OnGamesLoadedListener.html b/docs/html/reference/com/google/android/gms/games/OnGamesLoadedListener.html
index d6068df..5152163 100644
--- a/docs/html/reference/com/google/android/gms/games/OnGamesLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/games/OnGamesLoadedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/OnPlayersLoadedListener.html b/docs/html/reference/com/google/android/gms/games/OnPlayersLoadedListener.html
index 58e3ecb..d4e5e74 100644
--- a/docs/html/reference/com/google/android/gms/games/OnPlayersLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/games/OnPlayersLoadedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/OnSignOutCompleteListener.html b/docs/html/reference/com/google/android/gms/games/OnSignOutCompleteListener.html
index 0d0248e..a298976 100644
--- a/docs/html/reference/com/google/android/gms/games/OnSignOutCompleteListener.html
+++ b/docs/html/reference/com/google/android/gms/games/OnSignOutCompleteListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/PageDirection.html b/docs/html/reference/com/google/android/gms/games/PageDirection.html
index 844d321..957d6f6 100644
--- a/docs/html/reference/com/google/android/gms/games/PageDirection.html
+++ b/docs/html/reference/com/google/android/gms/games/PageDirection.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/Player.html b/docs/html/reference/com/google/android/gms/games/Player.html
index 6669fcc..a43b86e 100644
--- a/docs/html/reference/com/google/android/gms/games/Player.html
+++ b/docs/html/reference/com/google/android/gms/games/Player.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/PlayerBuffer.html b/docs/html/reference/com/google/android/gms/games/PlayerBuffer.html
index 55b119e..298ebf8 100644
--- a/docs/html/reference/com/google/android/gms/games/PlayerBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/PlayerBuffer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/PlayerEntity.html b/docs/html/reference/com/google/android/gms/games/PlayerEntity.html
index 09f383e..e47f0b7 100644
--- a/docs/html/reference/com/google/android/gms/games/PlayerEntity.html
+++ b/docs/html/reference/com/google/android/gms/games/PlayerEntity.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/achievement/Achievement.html b/docs/html/reference/com/google/android/gms/games/achievement/Achievement.html
index be51769..84137c3 100644
--- a/docs/html/reference/com/google/android/gms/games/achievement/Achievement.html
+++ b/docs/html/reference/com/google/android/gms/games/achievement/Achievement.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/achievement/AchievementBuffer.html b/docs/html/reference/com/google/android/gms/games/achievement/AchievementBuffer.html
index 1f3ead1..a793583 100644
--- a/docs/html/reference/com/google/android/gms/games/achievement/AchievementBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/achievement/AchievementBuffer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/achievement/OnAchievementUpdatedListener.html b/docs/html/reference/com/google/android/gms/games/achievement/OnAchievementUpdatedListener.html
index c464922..7486dd65 100644
--- a/docs/html/reference/com/google/android/gms/games/achievement/OnAchievementUpdatedListener.html
+++ b/docs/html/reference/com/google/android/gms/games/achievement/OnAchievementUpdatedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/achievement/OnAchievementsLoadedListener.html b/docs/html/reference/com/google/android/gms/games/achievement/OnAchievementsLoadedListener.html
index 9d38268..e0a7458 100644
--- a/docs/html/reference/com/google/android/gms/games/achievement/OnAchievementsLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/games/achievement/OnAchievementsLoadedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/achievement/package-summary.html b/docs/html/reference/com/google/android/gms/games/achievement/package-summary.html
index ce00f68..65047e3 100644
--- a/docs/html/reference/com/google/android/gms/games/achievement/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/games/achievement/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/Leaderboard.html b/docs/html/reference/com/google/android/gms/games/leaderboard/Leaderboard.html
index adc0a63..f4c8074 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/Leaderboard.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/Leaderboard.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardBuffer.html b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardBuffer.html
index 37f0760..8316c89 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardBuffer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScore.html b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScore.html
index 71a4266..87a931a 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScore.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScore.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScoreBuffer.html b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScoreBuffer.html
index f480d76..62b58d8 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScoreBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScoreBuffer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html
index 468e5dc..853a92f 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/OnLeaderboardMetadataLoadedListener.html b/docs/html/reference/com/google/android/gms/games/leaderboard/OnLeaderboardMetadataLoadedListener.html
index 6e851b6..4bd2a5c 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/OnLeaderboardMetadataLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/OnLeaderboardMetadataLoadedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/OnLeaderboardScoresLoadedListener.html b/docs/html/reference/com/google/android/gms/games/leaderboard/OnLeaderboardScoresLoadedListener.html
index 1de5a90..b78d488 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/OnLeaderboardScoresLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/OnLeaderboardScoresLoadedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/OnScoreSubmittedListener.html b/docs/html/reference/com/google/android/gms/games/leaderboard/OnScoreSubmittedListener.html
index 3d55b86..ac36f82 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/OnScoreSubmittedListener.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/OnScoreSubmittedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.Result.html b/docs/html/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.Result.html
index 12cc4de..818a012 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.Result.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.Result.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.html b/docs/html/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.html
index e9a08d5..3515b2a 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/package-summary.html b/docs/html/reference/com/google/android/gms/games/leaderboard/package-summary.html
index 552c383..012fc30 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/Invitation.html b/docs/html/reference/com/google/android/gms/games/multiplayer/Invitation.html
index 3a0bd5c..ffd6d9b 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/Invitation.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/Invitation.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationBuffer.html b/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationBuffer.html
index c164d34..b79cdcc 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationBuffer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationEntity.html b/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationEntity.html
index 8ff5f9e..a255b69 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationEntity.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationEntity.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/OnInvitationReceivedListener.html b/docs/html/reference/com/google/android/gms/games/multiplayer/OnInvitationReceivedListener.html
index 164faed..6ad54f4 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/OnInvitationReceivedListener.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/OnInvitationReceivedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/OnInvitationsLoadedListener.html b/docs/html/reference/com/google/android/gms/games/multiplayer/OnInvitationsLoadedListener.html
index 322d139..eb354d4 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/OnInvitationsLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/OnInvitationsLoadedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/Participant.html b/docs/html/reference/com/google/android/gms/games/multiplayer/Participant.html
index c71146e..9483f1c 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/Participant.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/Participant.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantBuffer.html b/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantBuffer.html
index 83d511e..228e0a0 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantBuffer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantEntity.html b/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantEntity.html
index ad1149d..c2e952f 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantEntity.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantEntity.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantUtils.html b/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantUtils.html
index 5e1b7b8..f3c1f11 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantUtils.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantUtils.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/Participatable.html b/docs/html/reference/com/google/android/gms/games/multiplayer/Participatable.html
index 4c7f5e8..a06df5a 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/Participatable.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/Participatable.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/package-summary.html b/docs/html/reference/com/google/android/gms/games/multiplayer/package-summary.html
index d2be94a8..53708bc 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessage.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessage.html
index 1ddb9cf..a5821f5 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessage.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessage.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessageReceivedListener.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessageReceivedListener.html
index 182beeb..f1fb99d 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessageReceivedListener.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessageReceivedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeReliableMessageSentListener.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeReliableMessageSentListener.html
index e0f958c..82b27ef 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeReliableMessageSentListener.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeReliableMessageSentListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeSocket.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeSocket.html
index d6e5b42..86d51c5 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeSocket.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeSocket.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/Room.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/Room.html
index a317f76..5daba7f 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/Room.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/Room.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.Builder.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.Builder.html
index a9f8e25..f422aef4 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.Builder.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.html
index 6d0e58a..305bf58 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomEntity.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomEntity.html
index 75e890d..5457464 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomEntity.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomEntity.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomStatusUpdateListener.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomStatusUpdateListener.html
index 4065ec6..bc4b593 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomStatusUpdateListener.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomStatusUpdateListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomUpdateListener.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomUpdateListener.html
index 108d7b7..8836837 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomUpdateListener.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomUpdateListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/package-summary.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/package-summary.html
index a5cffbe..20da1fe 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/games/package-summary.html b/docs/html/reference/com/google/android/gms/games/package-summary.html
index 53379f6..a12d9aa 100644
--- a/docs/html/reference/com/google/android/gms/games/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/games/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/gcm/GoogleCloudMessaging.html b/docs/html/reference/com/google/android/gms/gcm/GoogleCloudMessaging.html
index d16cea3..613f0ca 100644
--- a/docs/html/reference/com/google/android/gms/gcm/GoogleCloudMessaging.html
+++ b/docs/html/reference/com/google/android/gms/gcm/GoogleCloudMessaging.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/gcm/package-summary.html b/docs/html/reference/com/google/android/gms/gcm/package-summary.html
index f500dd2..886ce1c 100644
--- a/docs/html/reference/com/google/android/gms/gcm/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/gcm/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/location/ActivityRecognitionClient.html b/docs/html/reference/com/google/android/gms/location/ActivityRecognitionClient.html
index 5b2719c..25f355c 100644
--- a/docs/html/reference/com/google/android/gms/location/ActivityRecognitionClient.html
+++ b/docs/html/reference/com/google/android/gms/location/ActivityRecognitionClient.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/location/ActivityRecognitionResult.html b/docs/html/reference/com/google/android/gms/location/ActivityRecognitionResult.html
index c05f728..7f30cb7 100644
--- a/docs/html/reference/com/google/android/gms/location/ActivityRecognitionResult.html
+++ b/docs/html/reference/com/google/android/gms/location/ActivityRecognitionResult.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/location/DetectedActivity.html b/docs/html/reference/com/google/android/gms/location/DetectedActivity.html
index b1b63ca..b275a22 100644
--- a/docs/html/reference/com/google/android/gms/location/DetectedActivity.html
+++ b/docs/html/reference/com/google/android/gms/location/DetectedActivity.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/location/Geofence.Builder.html b/docs/html/reference/com/google/android/gms/location/Geofence.Builder.html
index e90c228..726568c 100644
--- a/docs/html/reference/com/google/android/gms/location/Geofence.Builder.html
+++ b/docs/html/reference/com/google/android/gms/location/Geofence.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/location/Geofence.html b/docs/html/reference/com/google/android/gms/location/Geofence.html
index 4abc3e5..f5f9af4 100644
--- a/docs/html/reference/com/google/android/gms/location/Geofence.html
+++ b/docs/html/reference/com/google/android/gms/location/Geofence.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/location/LocationClient.OnAddGeofencesResultListener.html b/docs/html/reference/com/google/android/gms/location/LocationClient.OnAddGeofencesResultListener.html
index 6744610..90cb569 100644
--- a/docs/html/reference/com/google/android/gms/location/LocationClient.OnAddGeofencesResultListener.html
+++ b/docs/html/reference/com/google/android/gms/location/LocationClient.OnAddGeofencesResultListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/location/LocationClient.OnRemoveGeofencesResultListener.html b/docs/html/reference/com/google/android/gms/location/LocationClient.OnRemoveGeofencesResultListener.html
index d5c9fdb..0e41b15 100644
--- a/docs/html/reference/com/google/android/gms/location/LocationClient.OnRemoveGeofencesResultListener.html
+++ b/docs/html/reference/com/google/android/gms/location/LocationClient.OnRemoveGeofencesResultListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/location/LocationClient.html b/docs/html/reference/com/google/android/gms/location/LocationClient.html
index c083d31..7981ce9 100644
--- a/docs/html/reference/com/google/android/gms/location/LocationClient.html
+++ b/docs/html/reference/com/google/android/gms/location/LocationClient.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/location/LocationListener.html b/docs/html/reference/com/google/android/gms/location/LocationListener.html
index 12befe4..3a9891b 100644
--- a/docs/html/reference/com/google/android/gms/location/LocationListener.html
+++ b/docs/html/reference/com/google/android/gms/location/LocationListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/location/LocationRequest.html b/docs/html/reference/com/google/android/gms/location/LocationRequest.html
index 711374b..bef3ede 100644
--- a/docs/html/reference/com/google/android/gms/location/LocationRequest.html
+++ b/docs/html/reference/com/google/android/gms/location/LocationRequest.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/location/LocationStatusCodes.html b/docs/html/reference/com/google/android/gms/location/LocationStatusCodes.html
index b9e5968..b509bf7 100644
--- a/docs/html/reference/com/google/android/gms/location/LocationStatusCodes.html
+++ b/docs/html/reference/com/google/android/gms/location/LocationStatusCodes.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/location/package-summary.html b/docs/html/reference/com/google/android/gms/location/package-summary.html
index ea7798e..568752c 100644
--- a/docs/html/reference/com/google/android/gms/location/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/location/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/CameraUpdate.html b/docs/html/reference/com/google/android/gms/maps/CameraUpdate.html
index 8295ce0..05e042e 100644
--- a/docs/html/reference/com/google/android/gms/maps/CameraUpdate.html
+++ b/docs/html/reference/com/google/android/gms/maps/CameraUpdate.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/CameraUpdateFactory.html b/docs/html/reference/com/google/android/gms/maps/CameraUpdateFactory.html
index f4684cc..71784c9 100644
--- a/docs/html/reference/com/google/android/gms/maps/CameraUpdateFactory.html
+++ b/docs/html/reference/com/google/android/gms/maps/CameraUpdateFactory.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.CancelableCallback.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.CancelableCallback.html
index 6ddaed5a..cb696d4 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.CancelableCallback.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.CancelableCallback.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.InfoWindowAdapter.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.InfoWindowAdapter.html
index 8c1885e..255094c 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.InfoWindowAdapter.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.InfoWindowAdapter.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnCameraChangeListener.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnCameraChangeListener.html
index 356776e..51efee1 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnCameraChangeListener.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnCameraChangeListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnInfoWindowClickListener.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnInfoWindowClickListener.html
index 748eb5e..08e1945 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnInfoWindowClickListener.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnInfoWindowClickListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMapClickListener.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMapClickListener.html
index be3c396..1177b11 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMapClickListener.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMapClickListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMapLoadedCallback.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMapLoadedCallback.html
index 10c6904..e3cd6b1 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMapLoadedCallback.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMapLoadedCallback.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMapLongClickListener.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMapLongClickListener.html
index 2811b2e..eca8a32 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMapLongClickListener.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMapLongClickListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMarkerClickListener.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMarkerClickListener.html
index 3f5ef8b..5a43126 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMarkerClickListener.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMarkerClickListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMarkerDragListener.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMarkerDragListener.html
index dffd596..9ad543f 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMarkerDragListener.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMarkerDragListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMyLocationButtonClickListener.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMyLocationButtonClickListener.html
index 2163ac9..9ee8148 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMyLocationButtonClickListener.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMyLocationButtonClickListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMyLocationChangeListener.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMyLocationChangeListener.html
index 2938e8a..6d3ec5a 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMyLocationChangeListener.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.OnMyLocationChangeListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.SnapshotReadyCallback.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.SnapshotReadyCallback.html
index 4ce045e..7ca6b21 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.SnapshotReadyCallback.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.SnapshotReadyCallback.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMap.html b/docs/html/reference/com/google/android/gms/maps/GoogleMap.html
index 4ec1355..b5161c4 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMap.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMap.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/GoogleMapOptions.html b/docs/html/reference/com/google/android/gms/maps/GoogleMapOptions.html
index c4cc20e..123087f 100644
--- a/docs/html/reference/com/google/android/gms/maps/GoogleMapOptions.html
+++ b/docs/html/reference/com/google/android/gms/maps/GoogleMapOptions.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/LocationSource.OnLocationChangedListener.html b/docs/html/reference/com/google/android/gms/maps/LocationSource.OnLocationChangedListener.html
index e6e0593..7f2a863 100644
--- a/docs/html/reference/com/google/android/gms/maps/LocationSource.OnLocationChangedListener.html
+++ b/docs/html/reference/com/google/android/gms/maps/LocationSource.OnLocationChangedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/LocationSource.html b/docs/html/reference/com/google/android/gms/maps/LocationSource.html
index d30c652..4c0f63f 100644
--- a/docs/html/reference/com/google/android/gms/maps/LocationSource.html
+++ b/docs/html/reference/com/google/android/gms/maps/LocationSource.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/MapFragment.html b/docs/html/reference/com/google/android/gms/maps/MapFragment.html
index 41131993..4d196eb 100644
--- a/docs/html/reference/com/google/android/gms/maps/MapFragment.html
+++ b/docs/html/reference/com/google/android/gms/maps/MapFragment.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/MapView.html b/docs/html/reference/com/google/android/gms/maps/MapView.html
index 0798249..e3e8697 100644
--- a/docs/html/reference/com/google/android/gms/maps/MapView.html
+++ b/docs/html/reference/com/google/android/gms/maps/MapView.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/MapsInitializer.html b/docs/html/reference/com/google/android/gms/maps/MapsInitializer.html
index da53ea6..335f4ca 100644
--- a/docs/html/reference/com/google/android/gms/maps/MapsInitializer.html
+++ b/docs/html/reference/com/google/android/gms/maps/MapsInitializer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/Projection.html b/docs/html/reference/com/google/android/gms/maps/Projection.html
index b117307..9f1339f 100644
--- a/docs/html/reference/com/google/android/gms/maps/Projection.html
+++ b/docs/html/reference/com/google/android/gms/maps/Projection.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/SupportMapFragment.html b/docs/html/reference/com/google/android/gms/maps/SupportMapFragment.html
index 87dc7a0..23f3c7f 100644
--- a/docs/html/reference/com/google/android/gms/maps/SupportMapFragment.html
+++ b/docs/html/reference/com/google/android/gms/maps/SupportMapFragment.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/UiSettings.html b/docs/html/reference/com/google/android/gms/maps/UiSettings.html
index 21ee737..650d6ff 100644
--- a/docs/html/reference/com/google/android/gms/maps/UiSettings.html
+++ b/docs/html/reference/com/google/android/gms/maps/UiSettings.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/BitmapDescriptor.html b/docs/html/reference/com/google/android/gms/maps/model/BitmapDescriptor.html
index 629875d..cb5fd6f 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/BitmapDescriptor.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/BitmapDescriptor.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/BitmapDescriptorFactory.html b/docs/html/reference/com/google/android/gms/maps/model/BitmapDescriptorFactory.html
index 0c04cdf..680a6fb 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/BitmapDescriptorFactory.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/BitmapDescriptorFactory.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/CameraPosition.Builder.html b/docs/html/reference/com/google/android/gms/maps/model/CameraPosition.Builder.html
index 4348e30..f27f364 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/CameraPosition.Builder.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/CameraPosition.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/CameraPosition.html b/docs/html/reference/com/google/android/gms/maps/model/CameraPosition.html
index 51c897e..d7872e6 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/CameraPosition.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/CameraPosition.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/Circle.html b/docs/html/reference/com/google/android/gms/maps/model/Circle.html
index 7331a35..203b58d 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/Circle.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/Circle.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/CircleOptions.html b/docs/html/reference/com/google/android/gms/maps/model/CircleOptions.html
index 2ce4d54..097d724 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/CircleOptions.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/CircleOptions.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/GroundOverlay.html b/docs/html/reference/com/google/android/gms/maps/model/GroundOverlay.html
index 37e2209..659dab1 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/GroundOverlay.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/GroundOverlay.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/GroundOverlayOptions.html b/docs/html/reference/com/google/android/gms/maps/model/GroundOverlayOptions.html
index ab48973..f50b9ff 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/GroundOverlayOptions.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/GroundOverlayOptions.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/LatLng.html b/docs/html/reference/com/google/android/gms/maps/model/LatLng.html
index a882cc0..9c3a3c1 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/LatLng.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/LatLng.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/LatLngBounds.Builder.html b/docs/html/reference/com/google/android/gms/maps/model/LatLngBounds.Builder.html
index 6b7f7ab..9f624ae 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/LatLngBounds.Builder.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/LatLngBounds.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/LatLngBounds.html b/docs/html/reference/com/google/android/gms/maps/model/LatLngBounds.html
index 5a3b9bd..3060a33 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/LatLngBounds.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/LatLngBounds.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/Marker.html b/docs/html/reference/com/google/android/gms/maps/model/Marker.html
index eadb9f6..caec06d 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/Marker.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/Marker.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/MarkerOptions.html b/docs/html/reference/com/google/android/gms/maps/model/MarkerOptions.html
index becca22..8e1288b 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/MarkerOptions.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/MarkerOptions.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/Polygon.html b/docs/html/reference/com/google/android/gms/maps/model/Polygon.html
index 6767f94..31b6184 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/Polygon.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/Polygon.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/PolygonOptions.html b/docs/html/reference/com/google/android/gms/maps/model/PolygonOptions.html
index fc889a6e..c71883c 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/PolygonOptions.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/PolygonOptions.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/Polyline.html b/docs/html/reference/com/google/android/gms/maps/model/Polyline.html
index 35c59f4..8da560c 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/Polyline.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/Polyline.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/PolylineOptions.html b/docs/html/reference/com/google/android/gms/maps/model/PolylineOptions.html
index b260f58..d25b709 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/PolylineOptions.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/PolylineOptions.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/RuntimeRemoteException.html b/docs/html/reference/com/google/android/gms/maps/model/RuntimeRemoteException.html
index 61071a0..adda6a0 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/RuntimeRemoteException.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/RuntimeRemoteException.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/Tile.html b/docs/html/reference/com/google/android/gms/maps/model/Tile.html
index 9fd011b..272d419 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/Tile.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/Tile.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/TileOverlay.html b/docs/html/reference/com/google/android/gms/maps/model/TileOverlay.html
index 2018867..85712b8 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/TileOverlay.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/TileOverlay.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/TileOverlayOptions.html b/docs/html/reference/com/google/android/gms/maps/model/TileOverlayOptions.html
index 2f4b7fb..819486e 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/TileOverlayOptions.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/TileOverlayOptions.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/TileProvider.html b/docs/html/reference/com/google/android/gms/maps/model/TileProvider.html
index e093cc7..672f0ef 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/TileProvider.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/TileProvider.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/UrlTileProvider.html b/docs/html/reference/com/google/android/gms/maps/model/UrlTileProvider.html
index 5b25b14..8a10d11 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/UrlTileProvider.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/UrlTileProvider.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/VisibleRegion.html b/docs/html/reference/com/google/android/gms/maps/model/VisibleRegion.html
index 80cc1c4..b4fb00f4 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/VisibleRegion.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/VisibleRegion.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/model/package-summary.html b/docs/html/reference/com/google/android/gms/maps/model/package-summary.html
index 21e5538..067647a 100644
--- a/docs/html/reference/com/google/android/gms/maps/model/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/maps/model/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/maps/package-summary.html b/docs/html/reference/com/google/android/gms/maps/package-summary.html
index ed2100c..9f61758 100644
--- a/docs/html/reference/com/google/android/gms/maps/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/maps/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/package-summary.html b/docs/html/reference/com/google/android/gms/package-summary.html
index c703b46..b31dbe7 100644
--- a/docs/html/reference/com/google/android/gms/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/panorama/PanoramaClient.OnPanoramaInfoLoadedListener.html b/docs/html/reference/com/google/android/gms/panorama/PanoramaClient.OnPanoramaInfoLoadedListener.html
index 3357549..415bdc3 100644
--- a/docs/html/reference/com/google/android/gms/panorama/PanoramaClient.OnPanoramaInfoLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/panorama/PanoramaClient.OnPanoramaInfoLoadedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/panorama/PanoramaClient.html b/docs/html/reference/com/google/android/gms/panorama/PanoramaClient.html
index 21714a3..36cacac 100644
--- a/docs/html/reference/com/google/android/gms/panorama/PanoramaClient.html
+++ b/docs/html/reference/com/google/android/gms/panorama/PanoramaClient.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/panorama/package-summary.html b/docs/html/reference/com/google/android/gms/panorama/package-summary.html
index f132452..59712ec 100644
--- a/docs/html/reference/com/google/android/gms/panorama/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/panorama/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusClient.Builder.html b/docs/html/reference/com/google/android/gms/plus/PlusClient.Builder.html
index 8158a2b..fe76201 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusClient.Builder.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusClient.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusClient.OnAccessRevokedListener.html b/docs/html/reference/com/google/android/gms/plus/PlusClient.OnAccessRevokedListener.html
index 47849f4..a604f72 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusClient.OnAccessRevokedListener.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusClient.OnAccessRevokedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusClient.OnMomentsLoadedListener.html b/docs/html/reference/com/google/android/gms/plus/PlusClient.OnMomentsLoadedListener.html
index 43486e0..a7c5abc 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusClient.OnMomentsLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusClient.OnMomentsLoadedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusClient.OnPeopleLoadedListener.html b/docs/html/reference/com/google/android/gms/plus/PlusClient.OnPeopleLoadedListener.html
index 8285506..b3844c3 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusClient.OnPeopleLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusClient.OnPeopleLoadedListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusClient.OrderBy.html b/docs/html/reference/com/google/android/gms/plus/PlusClient.OrderBy.html
index 0d9d025..5aa4ec0 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusClient.OrderBy.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusClient.OrderBy.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusClient.html b/docs/html/reference/com/google/android/gms/plus/PlusClient.html
index 194dfa8..91b64bf 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusClient.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusClient.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusOneButton.DefaultOnPlusOneClickListener.html b/docs/html/reference/com/google/android/gms/plus/PlusOneButton.DefaultOnPlusOneClickListener.html
index d0b19cc..ea048d2 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusOneButton.DefaultOnPlusOneClickListener.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusOneButton.DefaultOnPlusOneClickListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusOneButton.OnPlusOneClickListener.html b/docs/html/reference/com/google/android/gms/plus/PlusOneButton.OnPlusOneClickListener.html
index 9f5d227..e1fa665 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusOneButton.OnPlusOneClickListener.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusOneButton.OnPlusOneClickListener.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusOneButton.html b/docs/html/reference/com/google/android/gms/plus/PlusOneButton.html
index a9c5566..37d9292 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusOneButton.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusOneButton.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusOneButtonWithPopup.html b/docs/html/reference/com/google/android/gms/plus/PlusOneButtonWithPopup.html
index 8072051..4520e14 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusOneButtonWithPopup.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusOneButtonWithPopup.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusOneDummyView.html b/docs/html/reference/com/google/android/gms/plus/PlusOneDummyView.html
index 27ecdbd..237ab42 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusOneDummyView.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusOneDummyView.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusShare.Builder.html b/docs/html/reference/com/google/android/gms/plus/PlusShare.Builder.html
index e983cfc..d3bf559 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusShare.Builder.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusShare.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusShare.html b/docs/html/reference/com/google/android/gms/plus/PlusShare.html
index 4382746..ece13ed 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusShare.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusShare.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/moments/ItemScope.Builder.html b/docs/html/reference/com/google/android/gms/plus/model/moments/ItemScope.Builder.html
index b443b38..b5812bb 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/moments/ItemScope.Builder.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/moments/ItemScope.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/moments/ItemScope.html b/docs/html/reference/com/google/android/gms/plus/model/moments/ItemScope.html
index f5e6595..6d27fa1 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/moments/ItemScope.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/moments/ItemScope.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/moments/Moment.Builder.html b/docs/html/reference/com/google/android/gms/plus/model/moments/Moment.Builder.html
index 63ffc51..eec5ef0 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/moments/Moment.Builder.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/moments/Moment.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/moments/Moment.html b/docs/html/reference/com/google/android/gms/plus/model/moments/Moment.html
index 8f22f7f..800f78a 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/moments/Moment.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/moments/Moment.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/moments/MomentBuffer.html b/docs/html/reference/com/google/android/gms/plus/model/moments/MomentBuffer.html
index 6a69fed..148e933 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/moments/MomentBuffer.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/moments/MomentBuffer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/moments/package-summary.html b/docs/html/reference/com/google/android/gms/plus/model/moments/package-summary.html
index 86485d4..6a34052 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/moments/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/moments/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.AgeRange.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.AgeRange.html
index ca9aa93..1516706 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.AgeRange.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.AgeRange.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.CoverInfo.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.CoverInfo.html
index d311a63..343d55c 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.CoverInfo.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.CoverInfo.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.CoverPhoto.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.CoverPhoto.html
index 8731ce7..28adbcd 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.CoverPhoto.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.CoverPhoto.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.Layout.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.Layout.html
index a0f829a..8b1efdd 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.Layout.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.Layout.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.html
index dc93b4c..d4a750b 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Cover.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Gender.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Gender.html
index 2bbdb30..7ce05ed 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Gender.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Gender.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Image.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Image.html
index 77364bd..fc270ac 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Image.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Image.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Name.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Name.html
index c8d6d79..92b7d6e 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Name.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Name.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.ObjectType.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.ObjectType.html
index 3667ddc..5501f7d 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.ObjectType.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.ObjectType.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Organizations.Type.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Organizations.Type.html
index 027814b..2ea8479 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Organizations.Type.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Organizations.Type.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Organizations.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Organizations.html
index 82b1be5..e03015d 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Organizations.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Organizations.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.PlacesLived.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.PlacesLived.html
index 231aba1..f798987 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.PlacesLived.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.PlacesLived.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.RelationshipStatus.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.RelationshipStatus.html
index 82730d3b..eb43678 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.RelationshipStatus.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.RelationshipStatus.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Urls.Type.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Urls.Type.html
index 4830c12..c20e1e9 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Urls.Type.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Urls.Type.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Urls.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Urls.html
index 0709156..7a53481 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.Urls.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.Urls.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/Person.html b/docs/html/reference/com/google/android/gms/plus/model/people/Person.html
index 7cf1032..9f9cc2b 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/Person.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/Person.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/PersonBuffer.html b/docs/html/reference/com/google/android/gms/plus/model/people/PersonBuffer.html
index aaa6d9c..0a4a2ba 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/PersonBuffer.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/PersonBuffer.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/package-summary.html b/docs/html/reference/com/google/android/gms/plus/model/people/package-summary.html
index 5c493ca..d7b654a 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/plus/package-summary.html b/docs/html/reference/com/google/android/gms/plus/package-summary.html
index 7f6dfad..9cc6c42 100644
--- a/docs/html/reference/com/google/android/gms/plus/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/plus/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/Address.html b/docs/html/reference/com/google/android/gms/wallet/Address.html
index 37e715d..4cd1b11 100644
--- a/docs/html/reference/com/google/android/gms/wallet/Address.html
+++ b/docs/html/reference/com/google/android/gms/wallet/Address.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/Cart.Builder.html b/docs/html/reference/com/google/android/gms/wallet/Cart.Builder.html
index 935b05e..9dd6929 100644
--- a/docs/html/reference/com/google/android/gms/wallet/Cart.Builder.html
+++ b/docs/html/reference/com/google/android/gms/wallet/Cart.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/Cart.html b/docs/html/reference/com/google/android/gms/wallet/Cart.html
index 4a3ef7a..a86823f 100644
--- a/docs/html/reference/com/google/android/gms/wallet/Cart.html
+++ b/docs/html/reference/com/google/android/gms/wallet/Cart.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/EnableWalletOptimizationReceiver.html b/docs/html/reference/com/google/android/gms/wallet/EnableWalletOptimizationReceiver.html
index 1e2422c..813cf1c 100644
--- a/docs/html/reference/com/google/android/gms/wallet/EnableWalletOptimizationReceiver.html
+++ b/docs/html/reference/com/google/android/gms/wallet/EnableWalletOptimizationReceiver.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/FullWallet.html b/docs/html/reference/com/google/android/gms/wallet/FullWallet.html
index 60a5b92..3fe6ec2 100644
--- a/docs/html/reference/com/google/android/gms/wallet/FullWallet.html
+++ b/docs/html/reference/com/google/android/gms/wallet/FullWallet.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/FullWalletRequest.Builder.html b/docs/html/reference/com/google/android/gms/wallet/FullWalletRequest.Builder.html
index 9124a15..a92cd58 100644
--- a/docs/html/reference/com/google/android/gms/wallet/FullWalletRequest.Builder.html
+++ b/docs/html/reference/com/google/android/gms/wallet/FullWalletRequest.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/FullWalletRequest.html b/docs/html/reference/com/google/android/gms/wallet/FullWalletRequest.html
index 816067f..e75b0ca 100644
--- a/docs/html/reference/com/google/android/gms/wallet/FullWalletRequest.html
+++ b/docs/html/reference/com/google/android/gms/wallet/FullWalletRequest.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/LineItem.Builder.html b/docs/html/reference/com/google/android/gms/wallet/LineItem.Builder.html
index ed4a156..dd832e1 100644
--- a/docs/html/reference/com/google/android/gms/wallet/LineItem.Builder.html
+++ b/docs/html/reference/com/google/android/gms/wallet/LineItem.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/LineItem.Role.html b/docs/html/reference/com/google/android/gms/wallet/LineItem.Role.html
index f00653f..992f817 100644
--- a/docs/html/reference/com/google/android/gms/wallet/LineItem.Role.html
+++ b/docs/html/reference/com/google/android/gms/wallet/LineItem.Role.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/LineItem.html b/docs/html/reference/com/google/android/gms/wallet/LineItem.html
index 466e5e5..cf7cfb7 100644
--- a/docs/html/reference/com/google/android/gms/wallet/LineItem.html
+++ b/docs/html/reference/com/google/android/gms/wallet/LineItem.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/LoyaltyWalletObject.html b/docs/html/reference/com/google/android/gms/wallet/LoyaltyWalletObject.html
index 5e73d64..02867c8 100644
--- a/docs/html/reference/com/google/android/gms/wallet/LoyaltyWalletObject.html
+++ b/docs/html/reference/com/google/android/gms/wallet/LoyaltyWalletObject.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/MaskedWallet.html b/docs/html/reference/com/google/android/gms/wallet/MaskedWallet.html
index 40047b8..a6501f9 100644
--- a/docs/html/reference/com/google/android/gms/wallet/MaskedWallet.html
+++ b/docs/html/reference/com/google/android/gms/wallet/MaskedWallet.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/MaskedWalletRequest.Builder.html b/docs/html/reference/com/google/android/gms/wallet/MaskedWalletRequest.Builder.html
index 4e2d6b64..5f6d081 100644
--- a/docs/html/reference/com/google/android/gms/wallet/MaskedWalletRequest.Builder.html
+++ b/docs/html/reference/com/google/android/gms/wallet/MaskedWalletRequest.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/MaskedWalletRequest.html b/docs/html/reference/com/google/android/gms/wallet/MaskedWalletRequest.html
index 10844b9..a45d761 100644
--- a/docs/html/reference/com/google/android/gms/wallet/MaskedWalletRequest.html
+++ b/docs/html/reference/com/google/android/gms/wallet/MaskedWalletRequest.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.Builder.html b/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.Builder.html
index 6e62892..d5c29ea 100644
--- a/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.Builder.html
+++ b/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.Builder.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.Status.Error.html b/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.Status.Error.html
index 8cab605..594363f 100644
--- a/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.Status.Error.html
+++ b/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.Status.Error.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.Status.html b/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.Status.html
index 5282ce5..3a19e5d 100644
--- a/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.Status.html
+++ b/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.Status.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.html b/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.html
index d2a357f..a265dbf 100644
--- a/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.html
+++ b/docs/html/reference/com/google/android/gms/wallet/NotifyTransactionStatusRequest.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/OfferWalletObject.html b/docs/html/reference/com/google/android/gms/wallet/OfferWalletObject.html
index 558bbb6..0ddbae1 100644
--- a/docs/html/reference/com/google/android/gms/wallet/OfferWalletObject.html
+++ b/docs/html/reference/com/google/android/gms/wallet/OfferWalletObject.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/ProxyCard.html b/docs/html/reference/com/google/android/gms/wallet/ProxyCard.html
index 9cc1c28..3c2819c 100644
--- a/docs/html/reference/com/google/android/gms/wallet/ProxyCard.html
+++ b/docs/html/reference/com/google/android/gms/wallet/ProxyCard.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/WalletClient.html b/docs/html/reference/com/google/android/gms/wallet/WalletClient.html
index 654013c..b13e283 100644
--- a/docs/html/reference/com/google/android/gms/wallet/WalletClient.html
+++ b/docs/html/reference/com/google/android/gms/wallet/WalletClient.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
@@ -782,9 +793,9 @@
  new account and do not reuse the Google transaction ID associated with the old account - this is
  a new transaction.
  <p>
- We recommend that you <a href="http://getinstantbuy.withgoogle.com/">apply for API access</a>
- before starting development. During development, use the sandbox environment by specifying
- <code><a href="/reference/com/google/android/gms/wallet/WalletConstants.html#ENVIRONMENT_SANDBOX">ENVIRONMENT_SANDBOX</a></code> in the constructor.
+ We recommend that you <a class="external-link" href="http://getinstantbuy.withgoogle.com/">apply
+ for API access</a> before starting development. During development, use the sandbox environment by
+ specifying <code><a href="/reference/com/google/android/gms/wallet/WalletConstants.html#ENVIRONMENT_SANDBOX">ENVIRONMENT_SANDBOX</a></code> in the constructor.
 </p>
 
 
diff --git a/docs/html/reference/com/google/android/gms/wallet/WalletConstants.html b/docs/html/reference/com/google/android/gms/wallet/WalletConstants.html
index 3d61c1c..d3b4634 100644
--- a/docs/html/reference/com/google/android/gms/wallet/WalletConstants.html
+++ b/docs/html/reference/com/google/android/gms/wallet/WalletConstants.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -308,6 +309,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -375,6 +379,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -517,29 +525,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/com/google/android/gms/wallet/package-summary.html b/docs/html/reference/com/google/android/gms/wallet/package-summary.html
index 88436d1..49a4278 100644
--- a/docs/html/reference/com/google/android/gms/wallet/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/wallet/package-summary.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -309,6 +310,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -376,6 +380,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -518,29 +526,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/reference/gms-packages.html b/docs/html/reference/gms-packages.html
index 47ee3bb..0a2450b 100644
--- a/docs/html/reference/gms-packages.html
+++ b/docs/html/reference/gms-packages.html
@@ -97,6 +97,7 @@
 <script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
 <script type="text/javascript">
   var toRoot = "/";
+  var metaTags = [];
   var devsite = false;
 </script>
 <script src="/assets/js/docs.js" type="text/javascript"></script>
@@ -307,6 +308,9 @@
                         <li><a href="/google/index.html">Google Services</a>
                         </li>
                         
+                          <li><a href="/samples/index.html">Samples</a>
+                          </li>
+                        
                       </ul>
                     </li>
                     <li class="distribute last">
@@ -374,6 +378,10 @@
                   >Google Services</a>
                 </li>
                 
+                  <li class="samples"><a href="/samples/index.html"
+                    >Samples</a>
+                  </li>
+                
             </ul>
         </div>
         
@@ -516,29 +524,32 @@
 
 
 
-  <li class="nav-section">
+   <li class="nav-section">
       <div class="nav-section-header"><a href="/google/gcm/index.html">
         <span class="en">Google Cloud Messaging</span></a>
       </div>
       <ul>
+        <li><a href="/google/gcm/gcm.html">
+            <span class="en">Overview</span></a>
+        </li>
         <li><a href="/google/gcm/gs.html">
             <span class="en">Getting Started</span></a>
         </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
+        <li><a href="/google/gcm/client.html">
+            <span class="en">Implementing GCM Client</span></a>
         </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
+        <li class="nav-section"><div class="nav-section-header"><a href="/google/gcm/server.html">
+              <span class="en">Implementing GCM Server</span></a></div>
+              <ul>
+              <li><a href="/google/gcm/ccs.html">
+              <span class="en">CCS (XMPP)</span></a></li>
+              <li><a href="/google/gcm/http.html">
+              <span class="en">HTTP</span></a></li>
+              </ul>
         </li>
         <li><a href="/google/gcm/notifications.html">
               <span class="en">User Notifications</span></a>
         </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
         <li><a href="/google/gcm/adv.html">
             <span class="en">Advanced Topics</span></a>
         </li>
diff --git a/docs/html/samples/index.jd b/docs/html/samples/index.jd
index c1213b6..ab15e32 100644
--- a/docs/html/samples/index.jd
+++ b/docs/html/samples/index.jd
@@ -1,5 +1,5 @@
 page.title=Samples
-page.tags="samples","examples","code"
+page.tags=samples,examples,code
 
 @jd:body
 
diff --git a/docs/html/samples/samples_toc.cs b/docs/html/samples/samples_toc.cs
index 3de31b9..2007f22 100644
--- a/docs/html/samples/samples_toc.cs
+++ b/docs/html/samples/samples_toc.cs
@@ -1,6 +1,4 @@
-
 <ul id="nav" class="samples-nav">
-
 <script type="text/javascript">
 <!--
     buildToggleLists();
@@ -8,9 +6,9 @@
 //-->
 </script>
   <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/samples/index.html">
+    <div class="nav-section-header empty"><a href="<?cs var:toroot ?>samples/index.html">
       <span class="en">About the Samples</span></a>
     </div>
   </li>
-
-  <li class="nav-section"><div class="nav-section-header"><a href="/samples/topic.html#t=Background" title="Background">Background</a></div><ul><li class="nav-section"><div class="nav-section-header"><a href="/samples/repeatingAlarm/index.html" title="repeatingAlarm">repeatingAlarm</a></div><ul><li><a href="/samples/repeatingAlarm/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/repeatingAlarm/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/repeatingAlarm/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/repeatingAlarm/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/repeatingAlarm/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/repeatingAlarm/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/repeatingAlarm/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/repeatingAlarm/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/repeatingAlarm/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/repeatingAlarm/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/repeatingAlarm/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/repeatingAlarm/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/repeatingAlarm/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/repeatingAlarm/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common">com.example.android.common/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="activities">activities/</a></div><ul><li><a href="/samples/repeatingAlarm/src/com.example.android.common/activities/SampleActivityBase.html" title="SampleActivityBase.java">SampleActivityBase.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="logger">logger/</a></div><ul><li><a href="/samples/repeatingAlarm/src/com.example.android.common/logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/repeatingAlarm/src/com.example.android.common/logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/repeatingAlarm/src/com.example.android.common/logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/repeatingAlarm/src/com.example.android.common/logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/repeatingAlarm/src/com.example.android.common/logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/repeatingAlarm/src/com.example.android.common/logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.repeatingalarm">com.example.android.repeatingalarm/</a></div><ul><li><a href="/samples/repeatingAlarm/src/com.example.android.repeatingalarm/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li><li><a href="/samples/repeatingAlarm/src/com.example.android.repeatingalarm/RepeatingAlarmFragment.html" title="RepeatingAlarmFragment.java">RepeatingAlarmFragment.java</a></li></ul></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/topic.html#t=Connectivity" title="Connectivity">Connectivity</a></div><ul style="display: none;"><li class="nav-section"><div class="nav-section-header"><a href="/samples/BluetoothLeGatt/index.html" title="BluetoothLeGatt">BluetoothLeGatt</a></div><ul style="display: none;"><li><a href="/samples/BluetoothLeGatt/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BluetoothLeGatt/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BluetoothLeGatt/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BluetoothLeGatt/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BluetoothLeGatt/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BluetoothLeGatt/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BluetoothLeGatt/res/layout/actionbar_indeterminate_progress.html" title="actionbar_indeterminate_progress.xml">actionbar_indeterminate_progress.xml</a></li><li><a href="/samples/BluetoothLeGatt/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/BluetoothLeGatt/res/layout/gatt_services_characteristics.html" title="gatt_services_characteristics.xml">gatt_services_characteristics.xml</a></li><li><a href="/samples/BluetoothLeGatt/res/layout/listitem_device.html" title="listitem_device.xml">listitem_device.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/BluetoothLeGatt/res/menu/gatt_services.html" title="gatt_services.xml">gatt_services.xml</a></li><li><a href="/samples/BluetoothLeGatt/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BluetoothLeGatt/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BluetoothLeGatt/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BluetoothLeGatt/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BluetoothLeGatt/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BluetoothLeGatt/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BluetoothLeGatt/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul style="display: none;"><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.bluetoothlegatt">com.example.android.bluetoothlegatt/</a></div><ul style="display: none;"><li><a href="/samples/BluetoothLeGatt/src/com.example.android.bluetoothlegatt/BluetoothLeService.html" title="BluetoothLeService.java">BluetoothLeService.java</a></li><li><a href="/samples/BluetoothLeGatt/src/com.example.android.bluetoothlegatt/DeviceControlActivity.html" title="DeviceControlActivity.java">DeviceControlActivity.java</a></li><li><a href="/samples/BluetoothLeGatt/src/com.example.android.bluetoothlegatt/DeviceScanActivity.html" title="DeviceScanActivity.java">DeviceScanActivity.java</a></li><li><a href="/samples/BluetoothLeGatt/src/com.example.android.bluetoothlegatt/SampleGattAttributes.html" title="SampleGattAttributes.java">SampleGattAttributes.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/NetworkConnect/index.html" title="NetworkConnect">NetworkConnect</a></div><ul><li><a href="/samples/NetworkConnect/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/NetworkConnect/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/NetworkConnect/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/NetworkConnect/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/NetworkConnect/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/NetworkConnect/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/NetworkConnect/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/NetworkConnect/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/NetworkConnect/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/NetworkConnect/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/NetworkConnect/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/NetworkConnect/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/NetworkConnect/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/NetworkConnect/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/NetworkConnect/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common.logger">com.example.android.common.logger/</a></div><ul><li><a href="/samples/NetworkConnect/src/com.example.android.common.logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/NetworkConnect/src/com.example.android.common.logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/NetworkConnect/src/com.example.android.common.logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/NetworkConnect/src/com.example.android.common.logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/NetworkConnect/src/com.example.android.common.logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/NetworkConnect/src/com.example.android.common.logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.networkconnect">com.example.android.networkconnect/</a></div><ul><li><a href="/samples/NetworkConnect/src/com.example.android.networkconnect/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li><li><a href="/samples/NetworkConnect/src/com.example.android.networkconnect/SimpleTextFragment.html" title="SimpleTextFragment.java">SimpleTextFragment.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/BasicNetworking/index.html" title="BasicNetworking">BasicNetworking</a></div><ul><li><a href="/samples/BasicNetworking/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BasicNetworking/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicNetworking/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BasicNetworking/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BasicNetworking/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BasicNetworking/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BasicNetworking/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/BasicNetworking/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/BasicNetworking/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BasicNetworking/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BasicNetworking/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicNetworking/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BasicNetworking/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BasicNetworking/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicNetworking/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.basicnetworking">com.example.android.basicnetworking/</a></div><ul><li><a href="/samples/BasicNetworking/src/com.example.android.basicnetworking/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li><li><a href="/samples/BasicNetworking/src/com.example.android.basicnetworking/SimpleTextFragment.html" title="SimpleTextFragment.java">SimpleTextFragment.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common.logger">com.example.android.common.logger/</a></div><ul><li><a href="/samples/BasicNetworking/src/com.example.android.common.logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/BasicNetworking/src/com.example.android.common.logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/BasicNetworking/src/com.example.android.common.logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/BasicNetworking/src/com.example.android.common.logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/BasicNetworking/src/com.example.android.common.logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/BasicNetworking/src/com.example.android.common.logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/BasicSyncAdapter/index.html" title="BasicSyncAdapter">BasicSyncAdapter</a></div><ul><li><a href="/samples/BasicSyncAdapter/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BasicSyncAdapter/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicSyncAdapter/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BasicSyncAdapter/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BasicSyncAdapter/res/drawable-xhdpi/ic_action_refresh.html" title="ic_action_refresh.png">ic_action_refresh.png</a></li><li><a href="/samples/BasicSyncAdapter/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BasicSyncAdapter/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BasicSyncAdapter/res/layout/actionbar_indeterminate_progress.html" title="actionbar_indeterminate_progress.xml">actionbar_indeterminate_progress.xml</a></li><li><a href="/samples/BasicSyncAdapter/res/layout/activity_entry_list.html" title="activity_entry_list.xml">activity_entry_list.xml</a></li><li><a href="/samples/BasicSyncAdapter/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/BasicSyncAdapter/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BasicSyncAdapter/res/values/attrs.html" title="attrs.xml">attrs.xml</a></li><li><a href="/samples/BasicSyncAdapter/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BasicSyncAdapter/res/values/dimen.html" title="dimen.xml">dimen.xml</a></li><li><a href="/samples/BasicSyncAdapter/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicSyncAdapter/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BasicSyncAdapter/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BasicSyncAdapter/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicSyncAdapter/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="xml">xml/</a></div><ul><li><a href="/samples/BasicSyncAdapter/res/xml/authenticator.html" title="authenticator.xml">authenticator.xml</a></li><li><a href="/samples/BasicSyncAdapter/res/xml/syncadapter.html" title="syncadapter.xml">syncadapter.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.basicsyncadapter">com.example.android.basicsyncadapter/</a></div><ul><li><a href="/samples/BasicSyncAdapter/src/com.example.android.basicsyncadapter/EntryListActivity.html" title="EntryListActivity.java">EntryListActivity.java</a></li><li><a href="/samples/BasicSyncAdapter/src/com.example.android.basicsyncadapter/EntryListFragment.html" title="EntryListFragment.java">EntryListFragment.java</a></li><li><a href="/samples/BasicSyncAdapter/src/com.example.android.basicsyncadapter/SyncAdapter.html" title="SyncAdapter.java">SyncAdapter.java</a></li><li><a href="/samples/BasicSyncAdapter/src/com.example.android.basicsyncadapter/SyncService.html" title="SyncService.java">SyncService.java</a></li><li><a href="/samples/BasicSyncAdapter/src/com.example.android.basicsyncadapter/SyncUtils.html" title="SyncUtils.java">SyncUtils.java</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="net">net/</a></div><ul><li><a href="/samples/BasicSyncAdapter/src/com.example.android.basicsyncadapter/net/FeedParser.html" title="FeedParser.java">FeedParser.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="provider">provider/</a></div><ul><li><a href="/samples/BasicSyncAdapter/src/com.example.android.basicsyncadapter/provider/FeedContract.html" title="FeedContract.java">FeedContract.java</a></li><li><a href="/samples/BasicSyncAdapter/src/com.example.android.basicsyncadapter/provider/FeedProvider.html" title="FeedProvider.java">FeedProvider.java</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common">com.example.android.common/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="accounts">accounts/</a></div><ul><li><a href="/samples/BasicSyncAdapter/src/com.example.android.common/accounts/GenericAccountService.html" title="GenericAccountService.java">GenericAccountService.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="db">db/</a></div><ul><li><a href="/samples/BasicSyncAdapter/src/com.example.android.common/db/SelectionBuilder.html" title="SelectionBuilder.java">SelectionBuilder.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="logger">logger/</a></div><ul><li><a href="/samples/BasicSyncAdapter/src/com.example.android.common/logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/BasicSyncAdapter/src/com.example.android.common/logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/BasicSyncAdapter/src/com.example.android.common/logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/BasicSyncAdapter/src/com.example.android.common/logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/BasicSyncAdapter/src/com.example.android.common/logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/BasicSyncAdapter/src/com.example.android.common/logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/topic.html#t=Content" title="Content">Content</a></div><ul><li class="nav-section"><div class="nav-section-header"><a href="/samples/BasicContactables/index.html" title="BasicContactables">BasicContactables</a></div><ul><li><a href="/samples/BasicContactables/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BasicContactables/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicContactables/res/drawable-hdpi/ic_search_api_holo_light.html" title="ic_search_api_holo_light.png">ic_search_api_holo_light.png</a></li><li><a href="/samples/BasicContactables/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BasicContactables/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicContactables/res/drawable-mdpi/ic_search_api_holo_light.html" title="ic_search_api_holo_light.png">ic_search_api_holo_light.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BasicContactables/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicContactables/res/drawable-xhdpi/ic_search_api_holo_light.html" title="ic_search_api_holo_light.png">ic_search_api_holo_light.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BasicContactables/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BasicContactables/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/BasicContactables/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/BasicContactables/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BasicContactables/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BasicContactables/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicContactables/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BasicContactables/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BasicContactables/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicContactables/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="xml">xml/</a></div><ul><li><a href="/samples/BasicContactables/res/xml/searchable.html" title="searchable.xml">searchable.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.basiccontactables">com.example.android.basiccontactables/</a></div><ul><li><a href="/samples/BasicContactables/src/com.example.android.basiccontactables/ContactablesLoaderCallbacks.html" title="ContactablesLoaderCallbacks.java">ContactablesLoaderCallbacks.java</a></li><li><a href="/samples/BasicContactables/src/com.example.android.basiccontactables/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common.logger">com.example.android.common.logger/</a></div><ul><li><a href="/samples/BasicContactables/src/com.example.android.common.logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/BasicContactables/src/com.example.android.common.logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/BasicContactables/src/com.example.android.common.logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/BasicContactables/src/com.example.android.common.logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/BasicContactables/src/com.example.android.common.logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/BasicContactables/src/com.example.android.common.logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/AppRestrictions/index.html" title="AppRestrictions">AppRestrictions</a></div><ul><li><a href="/samples/AppRestrictions/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/AppRestrictions/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/AppRestrictions/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/AppRestrictions/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/AppRestrictions/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/AppRestrictions/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/AppRestrictions/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/AppRestrictions/res/layout/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/AppRestrictions/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/AppRestrictions/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/AppRestrictions/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/AppRestrictions/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/AppRestrictions/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/AppRestrictions/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="xml">xml/</a></div><ul><li><a href="/samples/AppRestrictions/res/xml/custom_prefs.html" title="custom_prefs.xml">custom_prefs.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.apprestrictions">com.example.android.apprestrictions/</a></div><ul><li><a href="/samples/AppRestrictions/src/com.example.android.apprestrictions/CustomRestrictionsActivity.html" title="CustomRestrictionsActivity.java">CustomRestrictionsActivity.java</a></li><li><a href="/samples/AppRestrictions/src/com.example.android.apprestrictions/CustomRestrictionsFragment.html" title="CustomRestrictionsFragment.java">CustomRestrictionsFragment.java</a></li><li><a href="/samples/AppRestrictions/src/com.example.android.apprestrictions/GetRestrictionsReceiver.html" title="GetRestrictionsReceiver.java">GetRestrictionsReceiver.java</a></li><li><a href="/samples/AppRestrictions/src/com.example.android.apprestrictions/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/StorageClient/index.html" title="StorageClient">StorageClient</a></div><ul><li><a href="/samples/StorageClient/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/StorageClient/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/StorageClient/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/StorageClient/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/StorageClient/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/StorageClient/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/StorageClient/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/StorageClient/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/StorageClient/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/StorageClient/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/StorageClient/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/StorageClient/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/StorageClient/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/StorageClient/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common">com.example.android.common/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="activities">activities/</a></div><ul><li><a href="/samples/StorageClient/src/com.example.android.common/activities/SampleActivityBase.html" title="SampleActivityBase.java">SampleActivityBase.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="logger">logger/</a></div><ul><li><a href="/samples/StorageClient/src/com.example.android.common/logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/StorageClient/src/com.example.android.common/logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/StorageClient/src/com.example.android.common/logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/StorageClient/src/com.example.android.common/logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/StorageClient/src/com.example.android.common/logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/StorageClient/src/com.example.android.common/logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.storageclient">com.example.android.storageclient/</a></div><ul><li><a href="/samples/StorageClient/src/com.example.android.storageclient/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li><li><a href="/samples/StorageClient/src/com.example.android.storageclient/StorageClientFragment.html" title="StorageClientFragment.java">StorageClientFragment.java</a></li></ul></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/topic.html#t=Input" title="Input">Input</a></div><ul><li class="nav-section"><div class="nav-section-header"><a href="/samples/BasicMultitouch/index.html" title="BasicMultitouch">BasicMultitouch</a></div><ul><li><a href="/samples/BasicMultitouch/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BasicMultitouch/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicMultitouch/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BasicMultitouch/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BasicMultitouch/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BasicMultitouch/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BasicMultitouch/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/BasicMultitouch/res/layout/layout_mainactivity.html" title="layout_mainactivity.xml">layout_mainactivity.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BasicMultitouch/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BasicMultitouch/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicMultitouch/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BasicMultitouch/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BasicMultitouch/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicMultitouch/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-v11">values-v11/</a></div><ul><li><a href="/samples/BasicMultitouch/res/values-v11/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-v14">values-v14/</a></div><ul><li><a href="/samples/BasicMultitouch/res/values-v14/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.basicmultitouch">com.example.android.basicmultitouch/</a></div><ul><li><a href="/samples/BasicMultitouch/src/com.example.android.basicmultitouch/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li><li><a href="/samples/BasicMultitouch/src/com.example.android.basicmultitouch/Pools.html" title="Pools.java">Pools.java</a></li><li><a href="/samples/BasicMultitouch/src/com.example.android.basicmultitouch/TouchDisplayView.html" title="TouchDisplayView.java">TouchDisplayView.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common.logger">com.example.android.common.logger/</a></div><ul><li><a href="/samples/BasicMultitouch/src/com.example.android.common.logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/BasicMultitouch/src/com.example.android.common.logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/BasicMultitouch/src/com.example.android.common.logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/BasicMultitouch/src/com.example.android.common.logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/BasicMultitouch/src/com.example.android.common.logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/BasicMultitouch/src/com.example.android.common.logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/BasicGestureDetect/index.html" title="BasicGestureDetect">BasicGestureDetect</a></div><ul><li><a href="/samples/BasicGestureDetect/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BasicGestureDetect/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicGestureDetect/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BasicGestureDetect/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BasicGestureDetect/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BasicGestureDetect/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BasicGestureDetect/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/BasicGestureDetect/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BasicGestureDetect/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BasicGestureDetect/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicGestureDetect/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BasicGestureDetect/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BasicGestureDetect/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicGestureDetect/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.basicgesturedetect">com.example.android.basicgesturedetect/</a></div><ul><li><a href="/samples/BasicGestureDetect/src/com.example.android.basicgesturedetect/BasicGestureDetectFragment.html" title="BasicGestureDetectFragment.java">BasicGestureDetectFragment.java</a></li><li><a href="/samples/BasicGestureDetect/src/com.example.android.basicgesturedetect/GestureListener.html" title="GestureListener.java">GestureListener.java</a></li><li><a href="/samples/BasicGestureDetect/src/com.example.android.basicgesturedetect/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common">com.example.android.common/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="activities">activities/</a></div><ul><li><a href="/samples/BasicGestureDetect/src/com.example.android.common/activities/SampleActivityBase.html" title="SampleActivityBase.java">SampleActivityBase.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="logger">logger/</a></div><ul><li><a href="/samples/BasicGestureDetect/src/com.example.android.common/logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/BasicGestureDetect/src/com.example.android.common/logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/BasicGestureDetect/src/com.example.android.common/logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/BasicGestureDetect/src/com.example.android.common/logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/BasicGestureDetect/src/com.example.android.common/logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/BasicGestureDetect/src/com.example.android.common/logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/topic.html#t=Media" title="Media">Media</a></div><ul><li class="nav-section"><div class="nav-section-header"><a href="/samples/BasicMediaRouter/index.html" title="BasicMediaRouter">BasicMediaRouter</a></div><ul><li><a href="/samples/BasicMediaRouter/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BasicMediaRouter/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicMediaRouter/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BasicMediaRouter/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BasicMediaRouter/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BasicMediaRouter/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BasicMediaRouter/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/BasicMediaRouter/res/layout/display.html" title="display.xml">display.xml</a></li><li><a href="/samples/BasicMediaRouter/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/BasicMediaRouter/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BasicMediaRouter/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BasicMediaRouter/res/values/colors.html" title="colors.xml">colors.xml</a></li><li><a href="/samples/BasicMediaRouter/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicMediaRouter/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BasicMediaRouter/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BasicMediaRouter/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicMediaRouter/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.basicmediarouter">com.example.android.basicmediarouter/</a></div><ul><li><a href="/samples/BasicMediaRouter/src/com.example.android.basicmediarouter/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li><li><a href="/samples/BasicMediaRouter/src/com.example.android.basicmediarouter/SamplePresentation.html" title="SamplePresentation.java">SamplePresentation.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common.logger">com.example.android.common.logger/</a></div><ul><li><a href="/samples/BasicMediaRouter/src/com.example.android.common.logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/BasicMediaRouter/src/com.example.android.common.logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/BasicMediaRouter/src/com.example.android.common.logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/BasicMediaRouter/src/com.example.android.common.logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/BasicMediaRouter/src/com.example.android.common.logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/BasicMediaRouter/src/com.example.android.common.logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/BasicMediaDecoder/index.html" title="BasicMediaDecoder">BasicMediaDecoder</a></div><ul><li><a href="/samples/BasicMediaDecoder/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable">drawable/</a></div><ul><li><a href="/samples/BasicMediaDecoder/res/drawable/selector_play.html" title="selector_play.xml">selector_play.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BasicMediaDecoder/res/drawable-hdpi/ic_action_play.html" title="ic_action_play.png">ic_action_play.png</a></li><li><a href="/samples/BasicMediaDecoder/res/drawable-hdpi/ic_action_play_disabled.html" title="ic_action_play_disabled.png">ic_action_play_disabled.png</a></li><li><a href="/samples/BasicMediaDecoder/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicMediaDecoder/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BasicMediaDecoder/res/drawable-mdpi/ic_action_play.html" title="ic_action_play.png">ic_action_play.png</a></li><li><a href="/samples/BasicMediaDecoder/res/drawable-mdpi/ic_action_play_disabled.html" title="ic_action_play_disabled.png">ic_action_play_disabled.png</a></li><li><a href="/samples/BasicMediaDecoder/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BasicMediaDecoder/res/drawable-xhdpi/ic_action_play.html" title="ic_action_play.png">ic_action_play.png</a></li><li><a href="/samples/BasicMediaDecoder/res/drawable-xhdpi/ic_action_play_disabled.html" title="ic_action_play_disabled.png">ic_action_play_disabled.png</a></li><li><a href="/samples/BasicMediaDecoder/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BasicMediaDecoder/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BasicMediaDecoder/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/BasicMediaDecoder/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/BasicMediaDecoder/res/menu/action_menu.html" title="action_menu.xml">action_menu.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="raw">raw/</a></div><ul><li><a href="/samples/BasicMediaDecoder/res/raw/vid_bigbuckbunny.html" title="vid_bigbuckbunny.mp4">vid_bigbuckbunny.mp4</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BasicMediaDecoder/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BasicMediaDecoder/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicMediaDecoder/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BasicMediaDecoder/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BasicMediaDecoder/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicMediaDecoder/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.basicmediadecoder">com.example.android.basicmediadecoder/</a></div><ul><li><a href="/samples/BasicMediaDecoder/src/com.example.android.basicmediadecoder/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common.media">com.example.android.common.media/</a></div><ul><li><a href="/samples/BasicMediaDecoder/src/com.example.android.common.media/CameraHelper.html" title="CameraHelper.java">CameraHelper.java</a></li><li><a href="/samples/BasicMediaDecoder/src/com.example.android.common.media/MediaCodecWrapper.html" title="MediaCodecWrapper.java">MediaCodecWrapper.java</a></li></ul></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/topic.html#t=Security" title="Security">Security</a></div><ul><li class="nav-section"><div class="nav-section-header"><a href="/samples/BasicAndroidKeyStore/index.html" title="BasicAndroidKeyStore">BasicAndroidKeyStore</a></div><ul><li><a href="/samples/BasicAndroidKeyStore/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BasicAndroidKeyStore/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicAndroidKeyStore/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BasicAndroidKeyStore/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BasicAndroidKeyStore/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BasicAndroidKeyStore/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BasicAndroidKeyStore/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/BasicAndroidKeyStore/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BasicAndroidKeyStore/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BasicAndroidKeyStore/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicAndroidKeyStore/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BasicAndroidKeyStore/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BasicAndroidKeyStore/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicAndroidKeyStore/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.basicandroidkeystore">com.example.android.basicandroidkeystore/</a></div><ul><li><a href="/samples/BasicAndroidKeyStore/src/com.example.android.basicandroidkeystore/BasicAndroidKeyStoreFragment.html" title="BasicAndroidKeyStoreFragment.java">BasicAndroidKeyStoreFragment.java</a></li><li><a href="/samples/BasicAndroidKeyStore/src/com.example.android.basicandroidkeystore/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li><li><a href="/samples/BasicAndroidKeyStore/src/com.example.android.basicandroidkeystore/SecurityConstants.html" title="SecurityConstants.java">SecurityConstants.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common">com.example.android.common/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="activities">activities/</a></div><ul><li><a href="/samples/BasicAndroidKeyStore/src/com.example.android.common/activities/SampleActivityBase.html" title="SampleActivityBase.java">SampleActivityBase.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="logger">logger/</a></div><ul><li><a href="/samples/BasicAndroidKeyStore/src/com.example.android.common/logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/BasicAndroidKeyStore/src/com.example.android.common/logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/BasicAndroidKeyStore/src/com.example.android.common/logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/BasicAndroidKeyStore/src/com.example.android.common/logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/BasicAndroidKeyStore/src/com.example.android.common/logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/BasicAndroidKeyStore/src/com.example.android.common/logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/topic.html#t=Testing" title="Testing">Testing</a></div><ul><li class="nav-section"><div class="nav-section-header"><a href="/samples/ActivityInstrumentation/index.html" title="ActivityInstrumentation">ActivityInstrumentation</a></div><ul><li><a href="/samples/ActivityInstrumentation/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/ActivityInstrumentation/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/ActivityInstrumentation/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/ActivityInstrumentation/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/ActivityInstrumentation/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/ActivityInstrumentation/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/ActivityInstrumentation/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/ActivityInstrumentation/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/ActivityInstrumentation/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/ActivityInstrumentation/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/ActivityInstrumentation/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/ActivityInstrumentation/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/ActivityInstrumentation/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/ActivityInstrumentation/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw720dp-land">values-sw720dp-land/</a></div><ul><li><a href="/samples/ActivityInstrumentation/res/values-sw720dp-land/dimens.html" title="dimens.xml">dimens.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.activityinstrumentation">com.example.android.activityinstrumentation/</a></div><ul><li><a href="/samples/ActivityInstrumentation/src/com.example.android.activityinstrumentation/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common.logger">com.example.android.common.logger/</a></div><ul><li><a href="/samples/ActivityInstrumentation/src/com.example.android.common.logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/ActivityInstrumentation/src/com.example.android.common.logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/ActivityInstrumentation/src/com.example.android.common.logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/ActivityInstrumentation/src/com.example.android.common.logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/ActivityInstrumentation/src/com.example.android.common.logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/ActivityInstrumentation/src/com.example.android.common.logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/topic.html#t=UI" title="UI">UI</a></div><ul><li class="nav-section"><div class="nav-section-header"><a href="/samples/BasicAccessibility/index.html" title="BasicAccessibility">BasicAccessibility</a></div><ul><li><a href="/samples/BasicAccessibility/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BasicAccessibility/res/drawable-hdpi/ic_action_discard.html" title="ic_action_discard.png">ic_action_discard.png</a></li><li><a href="/samples/BasicAccessibility/res/drawable-hdpi/ic_action_info.html" title="ic_action_info.png">ic_action_info.png</a></li><li><a href="/samples/BasicAccessibility/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicAccessibility/res/drawable-hdpi/partly_cloudy.html" title="partly_cloudy.png">partly_cloudy.png</a></li><li><a href="/samples/BasicAccessibility/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BasicAccessibility/res/drawable-mdpi/ic_action_discard.html" title="ic_action_discard.png">ic_action_discard.png</a></li><li><a href="/samples/BasicAccessibility/res/drawable-mdpi/ic_action_info.html" title="ic_action_info.png">ic_action_info.png</a></li><li><a href="/samples/BasicAccessibility/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BasicAccessibility/res/drawable-xhdpi/ic_action_discard.html" title="ic_action_discard.png">ic_action_discard.png</a></li><li><a href="/samples/BasicAccessibility/res/drawable-xhdpi/ic_action_info.html" title="ic_action_info.png">ic_action_info.png</a></li><li><a href="/samples/BasicAccessibility/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BasicAccessibility/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BasicAccessibility/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/BasicAccessibility/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BasicAccessibility/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BasicAccessibility/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicAccessibility/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BasicAccessibility/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BasicAccessibility/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicAccessibility/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw720dp-land">values-sw720dp-land/</a></div><ul><li><a href="/samples/BasicAccessibility/res/values-sw720dp-land/dimens.html" title="dimens.xml">dimens.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.basicaccessibility">com.example.android.basicaccessibility/</a></div><ul><li><a href="/samples/BasicAccessibility/src/com.example.android.basicaccessibility/DialView.html" title="DialView.java">DialView.java</a></li><li><a href="/samples/BasicAccessibility/src/com.example.android.basicaccessibility/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common.logger">com.example.android.common.logger/</a></div><ul><li><a href="/samples/BasicAccessibility/src/com.example.android.common.logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/BasicAccessibility/src/com.example.android.common.logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/BasicAccessibility/src/com.example.android.common.logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/BasicAccessibility/src/com.example.android.common.logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/BasicAccessibility/src/com.example.android.common.logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/BasicAccessibility/src/com.example.android.common.logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/HorizontalPaging/index.html" title="HorizontalPaging">HorizontalPaging</a></div><ul><li><a href="/samples/HorizontalPaging/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/HorizontalPaging/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/HorizontalPaging/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/HorizontalPaging/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/HorizontalPaging/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/HorizontalPaging/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/HorizontalPaging/res/layout/fragment_main_dummy.html" title="fragment_main_dummy.xml">fragment_main_dummy.xml</a></li><li><a href="/samples/HorizontalPaging/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/HorizontalPaging/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/HorizontalPaging/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/HorizontalPaging/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/HorizontalPaging/res/values/styles.html" title="styles.xml">styles.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw720dp-land">values-sw720dp-land/</a></div><ul><li><a href="/samples/HorizontalPaging/res/values/values-sw720dp-land/dimens.html" title="dimens.xml">dimens.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/HorizontalPaging/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/HorizontalPaging/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.horizontalpaging">com.example.android.horizontalpaging/</a></div><ul><li><a href="/samples/HorizontalPaging/src/com.example.android.horizontalpaging/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/ShareActionProvider/index.html" title="ShareActionProvider">ShareActionProvider</a></div><ul><li><a href="/samples/ShareActionProvider/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/ShareActionProvider/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/ShareActionProvider/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/ShareActionProvider/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/ShareActionProvider/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/ShareActionProvider/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/ShareActionProvider/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/ShareActionProvider/res/layout/item_image.html" title="item_image.xml">item_image.xml</a></li><li><a href="/samples/ShareActionProvider/res/layout/item_text.html" title="item_text.xml">item_text.xml</a></li><li><a href="/samples/ShareActionProvider/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/ShareActionProvider/res/menu/main_menu.html" title="main_menu.xml">main_menu.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/ShareActionProvider/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/ShareActionProvider/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/ShareActionProvider/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/ShareActionProvider/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/ShareActionProvider/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/ShareActionProvider/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.actionbarcompat.shareactionprovider">com.example.android.actionbarcompat.shareactionprovider/</a></div><ul><li><a href="/samples/ShareActionProvider/src/com.example.android.actionbarcompat.shareactionprovider/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="content">content/</a></div><ul><li><a href="/samples/ShareActionProvider/src/com.example.android.actionbarcompat.shareactionprovider/content/AssetProvider.html" title="AssetProvider.java">AssetProvider.java</a></li><li><a href="/samples/ShareActionProvider/src/com.example.android.actionbarcompat.shareactionprovider/content/ContentItem.html" title="ContentItem.java">ContentItem.java</a></li></ul></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/Styled/index.html" title="Styled">Styled</a></div><ul><li><a href="/samples/Styled/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable">drawable/</a></div><ul><li><a href="/samples/Styled/res/drawable/pressed_background.html" title="pressed_background.xml">pressed_background.xml</a></li><li><a href="/samples/Styled/res/drawable/progress_horizontal.html" title="progress_horizontal.xml">progress_horizontal.xml</a></li><li><a href="/samples/Styled/res/drawable/selectable_background.html" title="selectable_background.xml">selectable_background.xml</a></li><li><a href="/samples/Styled/res/drawable/spinner_background_ab.html" title="spinner_background_ab.xml">spinner_background_ab.xml</a></li><li><a href="/samples/Styled/res/drawable/tab_indicator_ab.html" title="tab_indicator_ab.xml">tab_indicator_ab.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/Styled/res/drawable-hdpi/ab_bottom_solid_styled.9.html" title="ab_bottom_solid_styled.9.png">ab_bottom_solid_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/ab_solid_styled.9.html" title="ab_solid_styled.9.png">ab_solid_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/ab_stacked_solid_styled.9.html" title="ab_stacked_solid_styled.9.png">ab_stacked_solid_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/ic_action_location.html" title="ic_action_location.png">ic_action_location.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/ic_action_refresh.html" title="ic_action_refresh.png">ic_action_refresh.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/ic_action_settings.html" title="ic_action_settings.png">ic_action_settings.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/list_focused_styled.9.html" title="list_focused_styled.9.png">list_focused_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/menu_dropdown_panel_styled.9.html" title="menu_dropdown_panel_styled.9.png">menu_dropdown_panel_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/progress_bg_styled.9.html" title="progress_bg_styled.9.png">progress_bg_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/progress_primary_styled.9.html" title="progress_primary_styled.9.png">progress_primary_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/progress_secondary_styled.9.html" title="progress_secondary_styled.9.png">progress_secondary_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/spinner_ab_default_styled.9.html" title="spinner_ab_default_styled.9.png">spinner_ab_default_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/spinner_ab_disabled_styled.9.html" title="spinner_ab_disabled_styled.9.png">spinner_ab_disabled_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/spinner_ab_focused_styled.9.html" title="spinner_ab_focused_styled.9.png">spinner_ab_focused_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/spinner_ab_pressed_styled.9.html" title="spinner_ab_pressed_styled.9.png">spinner_ab_pressed_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/tab_selected_focused_styled.9.html" title="tab_selected_focused_styled.9.png">tab_selected_focused_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/tab_selected_pressed_styled.9.html" title="tab_selected_pressed_styled.9.png">tab_selected_pressed_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/tab_selected_styled.9.html" title="tab_selected_styled.9.png">tab_selected_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/tab_unselected_focused_styled.9.html" title="tab_unselected_focused_styled.9.png">tab_unselected_focused_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/tab_unselected_pressed_styled.9.html" title="tab_unselected_pressed_styled.9.png">tab_unselected_pressed_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/Styled/res/drawable-mdpi/ab_bottom_solid_styled.9.html" title="ab_bottom_solid_styled.9.png">ab_bottom_solid_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/ab_solid_styled.9.html" title="ab_solid_styled.9.png">ab_solid_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/ab_stacked_solid_styled.9.html" title="ab_stacked_solid_styled.9.png">ab_stacked_solid_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/ic_action_location.html" title="ic_action_location.png">ic_action_location.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/ic_action_refresh.html" title="ic_action_refresh.png">ic_action_refresh.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/ic_action_settings.html" title="ic_action_settings.png">ic_action_settings.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/list_focused_styled.9.html" title="list_focused_styled.9.png">list_focused_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/menu_dropdown_panel_styled.9.html" title="menu_dropdown_panel_styled.9.png">menu_dropdown_panel_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/progress_bg_styled.9.html" title="progress_bg_styled.9.png">progress_bg_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/progress_primary_styled.9.html" title="progress_primary_styled.9.png">progress_primary_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/progress_secondary_styled.9.html" title="progress_secondary_styled.9.png">progress_secondary_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/spinner_ab_default_styled.9.html" title="spinner_ab_default_styled.9.png">spinner_ab_default_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/spinner_ab_disabled_styled.9.html" title="spinner_ab_disabled_styled.9.png">spinner_ab_disabled_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/spinner_ab_focused_styled.9.html" title="spinner_ab_focused_styled.9.png">spinner_ab_focused_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/spinner_ab_pressed_styled.9.html" title="spinner_ab_pressed_styled.9.png">spinner_ab_pressed_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/tab_selected_focused_styled.9.html" title="tab_selected_focused_styled.9.png">tab_selected_focused_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/tab_selected_pressed_styled.9.html" title="tab_selected_pressed_styled.9.png">tab_selected_pressed_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/tab_selected_styled.9.html" title="tab_selected_styled.9.png">tab_selected_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/tab_unselected_focused_styled.9.html" title="tab_unselected_focused_styled.9.png">tab_unselected_focused_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-mdpi/tab_unselected_pressed_styled.9.html" title="tab_unselected_pressed_styled.9.png">tab_unselected_pressed_styled.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/Styled/res/drawable-xhdpi/ab_bottom_solid_styled.9.html" title="ab_bottom_solid_styled.9.png">ab_bottom_solid_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/ab_solid_styled.9.html" title="ab_solid_styled.9.png">ab_solid_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/ab_stacked_solid_styled.9.html" title="ab_stacked_solid_styled.9.png">ab_stacked_solid_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/ic_action_location.html" title="ic_action_location.png">ic_action_location.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/ic_action_refresh.html" title="ic_action_refresh.png">ic_action_refresh.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/ic_action_settings.html" title="ic_action_settings.png">ic_action_settings.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/list_focused_styled.9.html" title="list_focused_styled.9.png">list_focused_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/menu_dropdown_panel_styled.9.html" title="menu_dropdown_panel_styled.9.png">menu_dropdown_panel_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/progress_bg_styled.9.html" title="progress_bg_styled.9.png">progress_bg_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/progress_primary_styled.9.html" title="progress_primary_styled.9.png">progress_primary_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/progress_secondary_styled.9.html" title="progress_secondary_styled.9.png">progress_secondary_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/spinner_ab_default_styled.9.html" title="spinner_ab_default_styled.9.png">spinner_ab_default_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/spinner_ab_disabled_styled.9.html" title="spinner_ab_disabled_styled.9.png">spinner_ab_disabled_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/spinner_ab_focused_styled.9.html" title="spinner_ab_focused_styled.9.png">spinner_ab_focused_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/spinner_ab_pressed_styled.9.html" title="spinner_ab_pressed_styled.9.png">spinner_ab_pressed_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/tab_selected_focused_styled.9.html" title="tab_selected_focused_styled.9.png">tab_selected_focused_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/tab_selected_pressed_styled.9.html" title="tab_selected_pressed_styled.9.png">tab_selected_pressed_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/tab_selected_styled.9.html" title="tab_selected_styled.9.png">tab_selected_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/tab_unselected_focused_styled.9.html" title="tab_unselected_focused_styled.9.png">tab_unselected_focused_styled.9.png</a></li><li><a href="/samples/Styled/res/drawable-xhdpi/tab_unselected_pressed_styled.9.html" title="tab_unselected_pressed_styled.9.png">tab_unselected_pressed_styled.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/Styled/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/Styled/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/Styled/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/Styled/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/Styled/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/Styled/res/values/colors.html" title="colors.xml">colors.xml</a></li><li><a href="/samples/Styled/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/Styled/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/Styled/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/Styled/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/Styled/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-v14">values-v14/</a></div><ul><li><a href="/samples/Styled/res/values-v14/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.actionbarcompat.styled">com.example.android.actionbarcompat.styled/</a></div><ul><li><a href="/samples/Styled/src/com.example.android.actionbarcompat.styled/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/Basic/index.html" title="Basic">Basic</a></div><ul><li><a href="/samples/Basic/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/Basic/res/drawable-hdpi/ic_action_location.html" title="ic_action_location.png">ic_action_location.png</a></li><li><a href="/samples/Basic/res/drawable-hdpi/ic_action_refresh.html" title="ic_action_refresh.png">ic_action_refresh.png</a></li><li><a href="/samples/Basic/res/drawable-hdpi/ic_action_settings.html" title="ic_action_settings.png">ic_action_settings.png</a></li><li><a href="/samples/Basic/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/Basic/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/Basic/res/drawable-mdpi/ic_action_location.html" title="ic_action_location.png">ic_action_location.png</a></li><li><a href="/samples/Basic/res/drawable-mdpi/ic_action_refresh.html" title="ic_action_refresh.png">ic_action_refresh.png</a></li><li><a href="/samples/Basic/res/drawable-mdpi/ic_action_settings.html" title="ic_action_settings.png">ic_action_settings.png</a></li><li><a href="/samples/Basic/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/Basic/res/drawable-xhdpi/ic_action_location.html" title="ic_action_location.png">ic_action_location.png</a></li><li><a href="/samples/Basic/res/drawable-xhdpi/ic_action_refresh.html" title="ic_action_refresh.png">ic_action_refresh.png</a></li><li><a href="/samples/Basic/res/drawable-xhdpi/ic_action_settings.html" title="ic_action_settings.png">ic_action_settings.png</a></li><li><a href="/samples/Basic/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/Basic/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/Basic/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/Basic/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/Basic/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/Basic/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/Basic/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/Basic/res/values/ids.html" title="ids.xml">ids.xml</a></li><li><a href="/samples/Basic/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/Basic/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/Basic/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/Basic/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.actionbarcompat.basic">com.example.android.actionbarcompat.basic/</a></div><ul><li><a href="/samples/Basic/src/com.example.android.actionbarcompat.basic/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/ImmersiveMode/index.html" title="ImmersiveMode">ImmersiveMode</a></div><ul><li><a href="/samples/ImmersiveMode/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/ImmersiveMode/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/ImmersiveMode/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/ImmersiveMode/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/ImmersiveMode/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/ImmersiveMode/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/ImmersiveMode/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/ImmersiveMode/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/ImmersiveMode/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/ImmersiveMode/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/ImmersiveMode/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/ImmersiveMode/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/ImmersiveMode/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/ImmersiveMode/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common">com.example.android.common/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="activities">activities/</a></div><ul><li><a href="/samples/ImmersiveMode/src/com.example.android.common/activities/SampleActivityBase.html" title="SampleActivityBase.java">SampleActivityBase.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="logger">logger/</a></div><ul><li><a href="/samples/ImmersiveMode/src/com.example.android.common/logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/ImmersiveMode/src/com.example.android.common/logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/ImmersiveMode/src/com.example.android.common/logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/ImmersiveMode/src/com.example.android.common/logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/ImmersiveMode/src/com.example.android.common/logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/ImmersiveMode/src/com.example.android.common/logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.immersivemode">com.example.android.immersivemode/</a></div><ul><li><a href="/samples/ImmersiveMode/src/com.example.android.immersivemode/ImmersiveModeFragment.html" title="ImmersiveModeFragment.java">ImmersiveModeFragment.java</a></li><li><a href="/samples/ImmersiveMode/src/com.example.android.immersivemode/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/TextSwitcher/index.html" title="TextSwitcher">TextSwitcher</a></div><ul><li><a href="/samples/TextSwitcher/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/TextSwitcher/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/TextSwitcher/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/TextSwitcher/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/TextSwitcher/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/TextSwitcher/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/TextSwitcher/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/TextSwitcher/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/TextSwitcher/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/TextSwitcher/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/TextSwitcher/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/TextSwitcher/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/TextSwitcher/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/TextSwitcher/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw720dp-land">values-sw720dp-land/</a></div><ul><li><a href="/samples/TextSwitcher/res/values-sw720dp-land/dimens.html" title="dimens.xml">dimens.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-v11">values-v11/</a></div><ul><li><a href="/samples/TextSwitcher/res/values-v11/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-v14">values-v14/</a></div><ul><li><a href="/samples/TextSwitcher/res/values-v14/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common.logger">com.example.android.common.logger/</a></div><ul><li><a href="/samples/TextSwitcher/src/com.example.android.common.logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/TextSwitcher/src/com.example.android.common.logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/TextSwitcher/src/com.example.android.common.logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/TextSwitcher/src/com.example.android.common.logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/TextSwitcher/src/com.example.android.common.logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/TextSwitcher/src/com.example.android.common.logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.textswitcher">com.example.android.textswitcher/</a></div><ul><li><a href="/samples/TextSwitcher/src/com.example.android.textswitcher/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/BorderlessButtons/index.html" title="BorderlessButtons">BorderlessButtons</a></div><ul><li><a href="/samples/BorderlessButtons/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BorderlessButtons/res/drawable-hdpi/ic_action_delete.html" title="ic_action_delete.png">ic_action_delete.png</a></li><li><a href="/samples/BorderlessButtons/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BorderlessButtons/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BorderlessButtons/res/drawable-mdpi/ic_action_delete.html" title="ic_action_delete.png">ic_action_delete.png</a></li><li><a href="/samples/BorderlessButtons/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BorderlessButtons/res/drawable-xhdpi/ic_action_delete.html" title="ic_action_delete.png">ic_action_delete.png</a></li><li><a href="/samples/BorderlessButtons/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BorderlessButtons/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BorderlessButtons/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/BorderlessButtons/res/layout/list_item.html" title="list_item.xml">list_item.xml</a></li><li><a href="/samples/BorderlessButtons/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/BorderlessButtons/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BorderlessButtons/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BorderlessButtons/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BorderlessButtons/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BorderlessButtons/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BorderlessButtons/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BorderlessButtons/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.borderlessbuttons">com.example.android.borderlessbuttons/</a></div><ul><li><a href="/samples/BorderlessButtons/src/com.example.android.borderlessbuttons/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common.logger">com.example.android.common.logger/</a></div><ul><li><a href="/samples/BorderlessButtons/src/com.example.android.common.logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/BorderlessButtons/src/com.example.android.common.logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/BorderlessButtons/src/com.example.android.common.logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/BorderlessButtons/src/com.example.android.common.logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/BorderlessButtons/src/com.example.android.common.logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/BorderlessButtons/src/com.example.android.common.logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/BasicNotifications/index.html" title="BasicNotifications">BasicNotifications</a></div><ul><li><a href="/samples/BasicNotifications/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BasicNotifications/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicNotifications/res/drawable-hdpi/ic_stat_notification.html" title="ic_stat_notification.png">ic_stat_notification.png</a></li><li><a href="/samples/BasicNotifications/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi-v11">drawable-hdpi-v11/</a></div><ul><li><a href="/samples/BasicNotifications/res/drawable-hdpi-v11/ic_stat_notification.html" title="ic_stat_notification.png">ic_stat_notification.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi-v9">drawable-hdpi-v9/</a></div><ul><li><a href="/samples/BasicNotifications/res/drawable-hdpi-v9/ic_stat_notification.html" title="ic_stat_notification.png">ic_stat_notification.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-ldpi-v11">drawable-ldpi-v11/</a></div><ul><li><a href="/samples/BasicNotifications/res/drawable-ldpi-v11/ic_stat_notification.html" title="ic_stat_notification.png">ic_stat_notification.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-ldpi-v9">drawable-ldpi-v9/</a></div><ul><li><a href="/samples/BasicNotifications/res/drawable-ldpi-v9/ic_stat_notification.html" title="ic_stat_notification.png">ic_stat_notification.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BasicNotifications/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicNotifications/res/drawable-mdpi/ic_stat_notification.html" title="ic_stat_notification.png">ic_stat_notification.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi-v11">drawable-mdpi-v11/</a></div><ul><li><a href="/samples/BasicNotifications/res/drawable-mdpi-v11/ic_stat_notification.html" title="ic_stat_notification.png">ic_stat_notification.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi-v9">drawable-mdpi-v9/</a></div><ul><li><a href="/samples/BasicNotifications/res/drawable-mdpi-v9/ic_stat_notification.html" title="ic_stat_notification.png">ic_stat_notification.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BasicNotifications/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicNotifications/res/drawable-xhdpi/ic_stat_notification.html" title="ic_stat_notification.png">ic_stat_notification.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi-v11">drawable-xhdpi-v11/</a></div><ul><li><a href="/samples/BasicNotifications/res/drawable-xhdpi-v11/ic_stat_notification.html" title="ic_stat_notification.png">ic_stat_notification.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi-v9">drawable-xhdpi-v9/</a></div><ul><li><a href="/samples/BasicNotifications/res/drawable-xhdpi-v9/ic_stat_notification.html" title="ic_stat_notification.png">ic_stat_notification.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BasicNotifications/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BasicNotifications/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/BasicNotifications/res/layout/sample_layout.html" title="sample_layout.xml">sample_layout.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BasicNotifications/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BasicNotifications/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicNotifications/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BasicNotifications/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BasicNotifications/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicNotifications/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.basicnotifications">com.example.android.basicnotifications/</a></div><ul><li><a href="/samples/BasicNotifications/src/com.example.android.basicnotifications/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/AdvancedImmersiveMode/index.html" title="AdvancedImmersiveMode">AdvancedImmersiveMode</a></div><ul><li><a href="/samples/AdvancedImmersiveMode/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/AdvancedImmersiveMode/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/AdvancedImmersiveMode/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/AdvancedImmersiveMode/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/AdvancedImmersiveMode/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/AdvancedImmersiveMode/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/AdvancedImmersiveMode/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/AdvancedImmersiveMode/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/AdvancedImmersiveMode/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/AdvancedImmersiveMode/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/AdvancedImmersiveMode/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/AdvancedImmersiveMode/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/AdvancedImmersiveMode/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/AdvancedImmersiveMode/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.advancedimmersivemode">com.example.android.advancedimmersivemode/</a></div><ul><li><a href="/samples/AdvancedImmersiveMode/src/com.example.android.advancedimmersivemode/AdvancedImmersiveModeFragment.html" title="AdvancedImmersiveModeFragment.java">AdvancedImmersiveModeFragment.java</a></li><li><a href="/samples/AdvancedImmersiveMode/src/com.example.android.advancedimmersivemode/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common">com.example.android.common/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="activities">activities/</a></div><ul><li><a href="/samples/AdvancedImmersiveMode/src/com.example.android.common/activities/SampleActivityBase.html" title="SampleActivityBase.java">SampleActivityBase.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="logger">logger/</a></div><ul><li><a href="/samples/AdvancedImmersiveMode/src/com.example.android.common/logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/AdvancedImmersiveMode/src/com.example.android.common/logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/AdvancedImmersiveMode/src/com.example.android.common/logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/AdvancedImmersiveMode/src/com.example.android.common/logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/AdvancedImmersiveMode/src/com.example.android.common/logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/AdvancedImmersiveMode/src/com.example.android.common/logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/BasicImmersiveMode/index.html" title="BasicImmersiveMode">BasicImmersiveMode</a></div><ul><li><a href="/samples/BasicImmersiveMode/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/BasicImmersiveMode/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/BasicImmersiveMode/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/BasicImmersiveMode/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/BasicImmersiveMode/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/BasicImmersiveMode/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/BasicImmersiveMode/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/BasicImmersiveMode/res/menu/main.html" title="main.xml">main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/BasicImmersiveMode/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/BasicImmersiveMode/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicImmersiveMode/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/BasicImmersiveMode/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/BasicImmersiveMode/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/BasicImmersiveMode/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.basicimmersivemode">com.example.android.basicimmersivemode/</a></div><ul><li><a href="/samples/BasicImmersiveMode/src/com.example.android.basicimmersivemode/BasicImmersiveModeFragment.html" title="BasicImmersiveModeFragment.java">BasicImmersiveModeFragment.java</a></li><li><a href="/samples/BasicImmersiveMode/src/com.example.android.basicimmersivemode/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common">com.example.android.common/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="activities">activities/</a></div><ul><li><a href="/samples/BasicImmersiveMode/src/com.example.android.common/activities/SampleActivityBase.html" title="SampleActivityBase.java">SampleActivityBase.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="logger">logger/</a></div><ul><li><a href="/samples/BasicImmersiveMode/src/com.example.android.common/logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/BasicImmersiveMode/src/com.example.android.common/logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/BasicImmersiveMode/src/com.example.android.common/logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/BasicImmersiveMode/src/com.example.android.common/logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/BasicImmersiveMode/src/com.example.android.common/logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/BasicImmersiveMode/src/com.example.android.common/logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/CustomChoiceList/index.html" title="CustomChoiceList">CustomChoiceList</a></div><ul><li><a href="/samples/CustomChoiceList/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="color">color/</a></div><ul><li><a href="/samples/CustomChoiceList/res/color/hideable_text_color.html" title="hideable_text_color.xml">hideable_text_color.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable">drawable/</a></div><ul><li><a href="/samples/CustomChoiceList/res/drawable/ic_hideable_item.html" title="ic_hideable_item.xml">ic_hideable_item.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/CustomChoiceList/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/CustomChoiceList/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/CustomChoiceList/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/CustomChoiceList/res/drawable-xhdpi/ic_hideable_item_checked.html" title="ic_hideable_item_checked.png">ic_hideable_item_checked.png</a></li><li><a href="/samples/CustomChoiceList/res/drawable-xhdpi/ic_hideable_item_unchecked.html" title="ic_hideable_item_unchecked.png">ic_hideable_item_unchecked.png</a></li><li><a href="/samples/CustomChoiceList/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/CustomChoiceList/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/CustomChoiceList/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/CustomChoiceList/res/layout/list_item.html" title="list_item.xml">list_item.xml</a></li><li><a href="/samples/CustomChoiceList/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/CustomChoiceList/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/CustomChoiceList/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/CustomChoiceList/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/CustomChoiceList/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/CustomChoiceList/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common.logger">com.example.android.common.logger/</a></div><ul><li><a href="/samples/CustomChoiceList/src/com.example.android.common.logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/CustomChoiceList/src/com.example.android.common.logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/CustomChoiceList/src/com.example.android.common.logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/CustomChoiceList/src/com.example.android.common.logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/CustomChoiceList/src/com.example.android.common.logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/CustomChoiceList/src/com.example.android.common.logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.customchoicelist">com.example.android.customchoicelist/</a></div><ul><li><a href="/samples/CustomChoiceList/src/com.example.android.customchoicelist/CheckableLinearLayout.html" title="CheckableLinearLayout.java">CheckableLinearLayout.java</a></li><li><a href="/samples/CustomChoiceList/src/com.example.android.customchoicelist/Cheeses.html" title="Cheeses.java">Cheeses.java</a></li><li><a href="/samples/CustomChoiceList/src/com.example.android.customchoicelist/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/DoneBar/index.html" title="DoneBar">DoneBar</a></div><ul><li><a href="/samples/DoneBar/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/DoneBar/res/drawable-hdpi/ic_action_cancel.html" title="ic_action_cancel.png">ic_action_cancel.png</a></li><li><a href="/samples/DoneBar/res/drawable-hdpi/ic_action_done.html" title="ic_action_done.png">ic_action_done.png</a></li><li><a href="/samples/DoneBar/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/DoneBar/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/DoneBar/res/drawable-mdpi/ic_action_cancel.html" title="ic_action_cancel.png">ic_action_cancel.png</a></li><li><a href="/samples/DoneBar/res/drawable-mdpi/ic_action_done.html" title="ic_action_done.png">ic_action_done.png</a></li><li><a href="/samples/DoneBar/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/DoneBar/res/drawable-xhdpi/ic_action_cancel.html" title="ic_action_cancel.png">ic_action_cancel.png</a></li><li><a href="/samples/DoneBar/res/drawable-xhdpi/ic_action_done.html" title="ic_action_done.png">ic_action_done.png</a></li><li><a href="/samples/DoneBar/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/DoneBar/res/drawable-xhdpi/sample_dashboard_item_background.9.html" title="sample_dashboard_item_background.9.png">sample_dashboard_item_background.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/DoneBar/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/DoneBar/res/layout/actionbar_custom_view_done.html" title="actionbar_custom_view_done.xml">actionbar_custom_view_done.xml</a></li><li><a href="/samples/DoneBar/res/layout/actionbar_custom_view_done_cancel.html" title="actionbar_custom_view_done_cancel.xml">actionbar_custom_view_done_cancel.xml</a></li><li><a href="/samples/DoneBar/res/layout/activity_done_bar.html" title="activity_done_bar.xml">activity_done_bar.xml</a></li><li><a href="/samples/DoneBar/res/layout/activity_done_button.html" title="activity_done_button.xml">activity_done_button.xml</a></li><li><a href="/samples/DoneBar/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/DoneBar/res/layout/activity_sample_dashboard.html" title="activity_sample_dashboard.xml">activity_sample_dashboard.xml</a></li><li><a href="/samples/DoneBar/res/layout/include_cancel_button.html" title="include_cancel_button.xml">include_cancel_button.xml</a></li><li><a href="/samples/DoneBar/res/layout/include_done_button.html" title="include_done_button.xml">include_done_button.xml</a></li><li><a href="/samples/DoneBar/res/layout/sample_dashboard_item.html" title="sample_dashboard_item.xml">sample_dashboard_item.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/DoneBar/res/menu/cancel.html" title="cancel.xml">cancel.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/DoneBar/res/values/activitycards-strings.html" title="activitycards-strings.xml">activitycards-strings.xml</a></li><li><a href="/samples/DoneBar/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/DoneBar/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/DoneBar/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/DoneBar/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/DoneBar/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/DoneBar/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.donebar">com.example.android.donebar/</a></div><ul><li><a href="/samples/DoneBar/src/com.example.android.donebar/DoneBarActivity.html" title="DoneBarActivity.java">DoneBarActivity.java</a></li><li><a href="/samples/DoneBar/src/com.example.android.donebar/DoneButtonActivity.html" title="DoneButtonActivity.java">DoneButtonActivity.java</a></li><li><a href="/samples/DoneBar/src/com.example.android.donebar/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/ListPopupMenu/index.html" title="ListPopupMenu">ListPopupMenu</a></div><ul><li><a href="/samples/ListPopupMenu/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/ListPopupMenu/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/ListPopupMenu/res/drawable-hdpi/ic_overflow.html" title="ic_overflow.png">ic_overflow.png</a></li><li><a href="/samples/ListPopupMenu/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/ListPopupMenu/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/ListPopupMenu/res/drawable-mdpi/ic_overflow.html" title="ic_overflow.png">ic_overflow.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/ListPopupMenu/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/ListPopupMenu/res/drawable-xhdpi/ic_overflow.html" title="ic_overflow.png">ic_overflow.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/ListPopupMenu/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/ListPopupMenu/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/ListPopupMenu/res/layout/list_item.html" title="list_item.xml">list_item.xml</a></li><li><a href="/samples/ListPopupMenu/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="menu">menu/</a></div><ul><li><a href="/samples/ListPopupMenu/res/menu/popup.html" title="popup.xml">popup.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/ListPopupMenu/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/ListPopupMenu/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/ListPopupMenu/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/ListPopupMenu/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/ListPopupMenu/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/ListPopupMenu/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.actionbarcompat.listpopupmenu">com.example.android.actionbarcompat.listpopupmenu/</a></div><ul><li><a href="/samples/ListPopupMenu/src/com.example.android.actionbarcompat.listpopupmenu/Cheeses.html" title="Cheeses.java">Cheeses.java</a></li><li><a href="/samples/ListPopupMenu/src/com.example.android.actionbarcompat.listpopupmenu/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li><li><a href="/samples/ListPopupMenu/src/com.example.android.actionbarcompat.listpopupmenu/PopupListFragment.html" title="PopupListFragment.java">PopupListFragment.java</a></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/CustomNotifications/index.html" title="CustomNotifications">CustomNotifications</a></div><ul><li><a href="/samples/CustomNotifications/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/CustomNotifications/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/CustomNotifications/res/drawable-hdpi/ic_stat_custom.html" title="ic_stat_custom.png">ic_stat_custom.png</a></li><li><a href="/samples/CustomNotifications/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi-v11">drawable-hdpi-v11/</a></div><ul><li><a href="/samples/CustomNotifications/res/drawable-hdpi-v11/ic_stat_custom.html" title="ic_stat_custom.png">ic_stat_custom.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi-v9">drawable-hdpi-v9/</a></div><ul><li><a href="/samples/CustomNotifications/res/drawable-hdpi-v9/ic_stat_custom.html" title="ic_stat_custom.png">ic_stat_custom.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-ldpi-v11">drawable-ldpi-v11/</a></div><ul><li><a href="/samples/CustomNotifications/res/drawable-ldpi-v11/ic_stat_custom.html" title="ic_stat_custom.png">ic_stat_custom.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-ldpi-v9">drawable-ldpi-v9/</a></div><ul><li><a href="/samples/CustomNotifications/res/drawable-ldpi-v9/ic_stat_custom.html" title="ic_stat_custom.png">ic_stat_custom.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/CustomNotifications/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/CustomNotifications/res/drawable-mdpi/ic_stat_custom.html" title="ic_stat_custom.png">ic_stat_custom.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi-v11">drawable-mdpi-v11/</a></div><ul><li><a href="/samples/CustomNotifications/res/drawable-mdpi-v11/ic_stat_custom.html" title="ic_stat_custom.png">ic_stat_custom.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi-v9">drawable-mdpi-v9/</a></div><ul><li><a href="/samples/CustomNotifications/res/drawable-mdpi-v9/ic_stat_custom.html" title="ic_stat_custom.png">ic_stat_custom.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/CustomNotifications/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/CustomNotifications/res/drawable-xhdpi/ic_stat_custom.html" title="ic_stat_custom.png">ic_stat_custom.png</a></li><li><a href="/samples/CustomNotifications/res/drawable-xhdpi/robot.html" title="robot.png">robot.png</a></li><li><a href="/samples/CustomNotifications/res/drawable-xhdpi/robot_expanded.html" title="robot_expanded.png">robot_expanded.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi-v11">drawable-xhdpi-v11/</a></div><ul><li><a href="/samples/CustomNotifications/res/drawable-xhdpi-v11/ic_stat_custom.html" title="ic_stat_custom.png">ic_stat_custom.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi-v9">drawable-xhdpi-v9/</a></div><ul><li><a href="/samples/CustomNotifications/res/drawable-xhdpi-v9/ic_stat_custom.html" title="ic_stat_custom.png">ic_stat_custom.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/CustomNotifications/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/CustomNotifications/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/CustomNotifications/res/layout/notification.html" title="notification.xml">notification.xml</a></li><li><a href="/samples/CustomNotifications/res/layout/notification_expanded.html" title="notification_expanded.xml">notification_expanded.xml</a></li><li><a href="/samples/CustomNotifications/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/CustomNotifications/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/CustomNotifications/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/CustomNotifications/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/CustomNotifications/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/CustomNotifications/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/CustomNotifications/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw720dp-land">values-sw720dp-land/</a></div><ul><li><a href="/samples/CustomNotifications/res/values-sw720dp-land/dimens.html" title="dimens.xml">dimens.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-v9">values-v9/</a></div><ul><li><a href="/samples/CustomNotifications/res/values-v9/styles.html" title="styles.xml">styles.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.customnotifications">com.example.android.customnotifications/</a></div><ul><li><a href="/samples/CustomNotifications/src/com.example.android.customnotifications/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li></ul></li></ul></li></ul></li><li class="nav-section"><div class="nav-section-header"><a href="/samples/topic.html#t=Views" title="Views">Views</a></div><ul><li class="nav-section"><div class="nav-section-header"><a href="/samples/TextLinkify/index.html" title="TextLinkify">TextLinkify</a></div><ul><li><a href="/samples/TextLinkify/AndroidManifest.html" title="AndroidManifest.xml">AndroidManifest.xml</a></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="res">res/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-hdpi">drawable-hdpi/</a></div><ul><li><a href="/samples/TextLinkify/res/drawable-hdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li><li><a href="/samples/TextLinkify/res/drawable-hdpi/tile.9.html" title="tile.9.png">tile.9.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-mdpi">drawable-mdpi/</a></div><ul><li><a href="/samples/TextLinkify/res/drawable-mdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xhdpi">drawable-xhdpi/</a></div><ul><li><a href="/samples/TextLinkify/res/drawable-xhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="drawable-xxhdpi">drawable-xxhdpi/</a></div><ul><li><a href="/samples/TextLinkify/res/drawable-xxhdpi/ic_launcher.html" title="ic_launcher.png">ic_launcher.png</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="layout">layout/</a></div><ul><li><a href="/samples/TextLinkify/res/layout/activity_main.html" title="activity_main.xml">activity_main.xml</a></li><li><a href="/samples/TextLinkify/res/layout/sample_main.html" title="sample_main.xml">sample_main.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values">values/</a></div><ul><li><a href="/samples/TextLinkify/res/values/base-strings.html" title="base-strings.xml">base-strings.xml</a></li><li><a href="/samples/TextLinkify/res/values/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/TextLinkify/res/values/strings.html" title="strings.xml">strings.xml</a></li><li><a href="/samples/TextLinkify/res/values/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw600dp">values-sw600dp/</a></div><ul><li><a href="/samples/TextLinkify/res/values-sw600dp/dimens.html" title="dimens.xml">dimens.xml</a></li><li><a href="/samples/TextLinkify/res/values-sw600dp/styles.html" title="styles.xml">styles.xml</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="values-sw720dp-land">values-sw720dp-land/</a></div><ul><li><a href="/samples/TextLinkify/res/values-sw720dp-land/dimens.html" title="dimens.xml">dimens.xml</a></li></ul></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="src">src/</a></div><ul><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.common.logger">com.example.android.common.logger/</a></div><ul><li><a href="/samples/TextLinkify/src/com.example.android.common.logger/Log.html" title="Log.java">Log.java</a></li><li><a href="/samples/TextLinkify/src/com.example.android.common.logger/LogFragment.html" title="LogFragment.java">LogFragment.java</a></li><li><a href="/samples/TextLinkify/src/com.example.android.common.logger/LogNode.html" title="LogNode.java">LogNode.java</a></li><li><a href="/samples/TextLinkify/src/com.example.android.common.logger/LogView.html" title="LogView.java">LogView.java</a></li><li><a href="/samples/TextLinkify/src/com.example.android.common.logger/LogWrapper.html" title="LogWrapper.java">LogWrapper.java</a></li><li><a href="/samples/TextLinkify/src/com.example.android.common.logger/MessageOnlyLogFilter.html" title="MessageOnlyLogFilter.java">MessageOnlyLogFilter.java</a></li></ul></li><li class="nav-section sticky"><div class="nav-section-header empty"><a href="#" onclick="return false;" title="com.example.android.textlinkify">com.example.android.textlinkify/</a></div><ul><li><a href="/samples/TextLinkify/src/com.example.android.textlinkify/MainActivity.html" title="MainActivity.java">MainActivity.java</a></li></ul></li></ul></li></ul></li></ul></li></ul>
+  <?cs var:samples_toc_tree ?>
+ </ul>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index a77cdfb..bc22416 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -1,5 +1,5 @@
 page.title=Android SDK
-page.tags="download"
+page.tags=download
 page.template=sdk
 header.hide=1
 page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index 88fd7df..66c3034 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -74,12 +74,14 @@
 
 <div class="sidebox-wrapper">
 <div class="sidebox">
-<h2>Join the translation pilot</h2>
-<p>Google Play is offering <a
-href="{@docRoot}distribute/googleplay/publish/localizing.html#gp-trans">
-translation services</a> as part of a pilot program. If you are interested,
-sign up for the pilot program on the APK page in your Developer Console.</p>
-</div></div>
+<h2>App Translations in Google Play</h2>
+<p>Google Play <a href="{@docRoot}distribute/googleplay/publish/localizing.html#gp-trans">App 
+Translation Service</a> is available in the Developer Console to help you
+localize your app for a global user base. You can browse qualified vendors, get
+estimates, upload strings for translation, and then import the translations directly
+into your app.</p>
+</div>
+</div>
 
 <p>ADT Translation Manager Plugin is an Android SDK Tools plugin that helps
 you work with strings that you are localizing. It's designed to work
@@ -97,7 +99,8 @@
 localization works instantly.</p>
 
 <p>For more information about translation services in Google Play, see <a
-href="{@docRoot}distribute/googleplay/publish/localizing.html#gp-trans">Purchase professional translations through the Developer Console</a>.</p>
+href="{@docRoot}distribute/googleplay/publish/localizing.html#gp-trans">Purchase
+professional translations through the Developer Console</a>.</p>
 
 <p>To install the ADT Translation Manager Plugin follow these steps:</p>
 
diff --git a/docs/html/sdk/installing/studio.jd b/docs/html/sdk/installing/studio.jd
index f2fd79b..f3027a9 100644
--- a/docs/html/sdk/installing/studio.jd
+++ b/docs/html/sdk/installing/studio.jd
@@ -1,5 +1,5 @@
 page.title=Getting Started with Android Studio
-page.tags="studio"
+page.tags=studio
 @jd:body
 
 
@@ -253,36 +253,36 @@
     <td>Windows</td>
     <td>
   <a onclick="return onDownload(this)" id="win-studio"
-      href="http://dl.google.com/android/studio/android-studio-bundle-132.883541-windows.exe">
-      android-studio-bundle-132.883541-windows.exe
+      href="http://dl.google.com/android/studio/install/0.3.2/android-studio-bundle-132.893413-windows.exe">
+      android-studio-bundle-132.893413-windows.exe
       </a>
     </td>
-    <td>448245492 bytes</td>
-    <td>ca5f5c4d21b4350ddf3bda7021a6ee5e</td>
+    <td>484345454 bytes</td>
+    <td>14cbf0109a822688f4e2f886c0b0c85a</td>
   </tr>
 
   <tr>
     <td><nobr>Mac OS X</nobr></td>
     <td>
   <a onclick="return onDownload(this)" id="mac-studio"
-    href="http://dl.google.com/android/studio/android-studio-bundle-132.883541-mac.dmg">
-    android-studio-bundle-132.883541-mac.dmg
+    href="http://dl.google.com/android/studio/install/0.3.2/android-studio-bundle-132.893413-mac.dmg">
+    android-studio-bundle-132.893413-mac.dmg
     </a>
     </td>
-    <td>427317993 bytes</td>
-    <td>67831af6e7896a0a146d43423fabb542</td>
+    <td>463332508 bytes</td>
+    <td>0cd4ac59864890f7de57314bcc7ea5aa</td>
   </tr>
 
   <tr>
     <td>Linux</td>
     <td>
   <a onclick="return onDownload(this)" id="linux-studio"
-    href="http://dl.google.com/android/studio/android-studio-bundle-132.883541-linux.tgz">
-    android-studio-bundle-132.883541-linux.tgz
+    href="http://dl.google.com/android/studio/install/0.3.2/android-studio-bundle-132.893413-linux.tgz">
+    android-studio-bundle-132.893413-linux.tgz
     </a>
     </td>
-    <td>451652493 bytes</td>
-    <td>7a6f9b12b2cd5321ab0818b51306e01c</td>
+    <td>487694946 bytes</td>
+    <td>9f1306100314b03ff5b691b94f154501</td>
   </tr>
   </table>
 
@@ -294,7 +294,8 @@
 
 <p>If you already have Android Studio installed, in most cases, you can upgrade to the latest
 version by installing a patch. From within Android Studio, select
-<strong>Help &gt; Check for updates</strong> to see whether an update is available.</p>
+<strong>Help &gt; Check for updates</strong> (on Mac, <strong>Android Studio &gt;
+Check for updates</strong>) to see whether an update is available.</p>
 
 <p>If an update is not available,
 follow the <a href="#Installing">installation instructions</a> below and replace your existing
@@ -423,7 +424,7 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
-      alt=""/>Android Studio v0.3.1</a> <em>(Oct 2013)</em>
+      alt=""/>Android Studio v0.3.2</a> <em>(Oct 2013)</em>
   </p>
 
   <div class="toggle-content-toggleme">
@@ -617,7 +618,7 @@
   if (os) {
     /* set up primary ACE download button */
     $('#download-ide-button').show();
-    $('#download-ide-button').append("Download Android Studio <span class='small'>v0.3.1</span>"
+    $('#download-ide-button').append("Download Android Studio <span class='small'>v0.3.2</span>"
         + "<br/> <span class='small'>for " + os + "</span>");
     $('#download-ide-button').click(function() {return onDownload(this,true);}).attr('href', bundlename);
 
@@ -663,6 +664,7 @@
       $("#tos").hide();
       $("#main").show();
       location.hash = "Updating";
+      _gaq.push(['_trackEvent', 'SDK', 'Android Studio', $("#downloadForRealz").html()]);
       return true;
     } else {
       $("label#agreeLabel,#bitpicker input").parent().stop().animate({color: "#258AAF"}, 200,
diff --git a/docs/html/sdk/win-usb.jd b/docs/html/sdk/win-usb.jd
index 5ca38c6..c287a0c 100644
--- a/docs/html/sdk/win-usb.jd
+++ b/docs/html/sdk/win-usb.jd
@@ -191,27 +191,19 @@
 </div>
 </div>
 
-<p>The Google USB Driver is for <strong>Windows only</strong> and provides the
-necessary drivers for the following devices:</p>
-  <ul>
-    <li>ADP1 / T-Mobile G1*</li>
-    <li>ADP2 / Google Ion / T-Mobile myTouch 3G*</li>
-    <li>Verizon Droid*</li>
-    <li>Nexus One</li>
-    <li>Nexus S</li>
-    <li>Nexus 4</li>
-    <li>Nexus 7</li>
-    <li>Nexus 10</li>
-  </ul>
-  <p>* <em>Or similar hardware on other carriers</em></p>
-
-  <p>All other devices require Windows drivers provided by the respective hardware manufacturer,
-  as listed in the <a href="{@docRoot}tools/extras/oem-usb.html">OEM USB Drivers</a> document.</p>
-
-  <p>The Galaxy Nexus driver is distributed by <a
+<p>The Google USB Driver is <strong>required for Windows only</strong> in order to perform
+<a href="{@docRoot}tools/help/adb.html">adb</a> debugging with any of
+the <strong>Google Nexus devices</strong>. The one exception is the
+Galaxy Nexus: the driver for Galaxy Nexus is distributed by <a
 href="http://www.samsung.com/us/support/downloads/verizon-wireless/SCH-I515MSAVZW">Samsung</a>
 (listed as model SCH-I515).</p>
 
+<p>Windows drivers for all other devices are provided by the respective hardware
+manufacturer, as listed in the <a href="{@docRoot}tools/extras/oem-usb.html">OEM USB Drivers</a>
+document.</p>
+
+
+
 <p class="note"><strong>Note:</strong>
 If you're developing on Mac OS X or Linux, then you <strong>do not</strong> need to install a USB
 driver. To start developing with your device, read
diff --git a/docs/html/support.jd b/docs/html/support.jd
index 2f1222f..63bed30 100644
--- a/docs/html/support.jd
+++ b/docs/html/support.jd
@@ -1,5 +1,6 @@
 page.title=Developer Support
 fullpage=1
+excludeFromSuggestions=true
 @jd:body
 
 <div class="wrap" style="width:940px;">
@@ -16,6 +17,8 @@
 <h5>Community and Office Hours</h5>
 <p style="color:#888">
 
+<a href="https://plus.google.com/+AndroidDevelopers">Android Developers</a> on Google+<br />
+<a href="https://plus.google.com/communities/105153134372062985968">Android Development community</a> on Google+<br />
 <a href="http://groups.google.com/group/android-developers">android-developers</a> support forum<br />
 <a href="http://groups.google.com/group/android-ndk">android-ndk</a> support forum<br />
 <a href="http://groups.google.com/group/android-security-discuss">android-security-discuss</a> support forum<br />
@@ -71,4 +74,4 @@
 
 
 </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/docs/html/tools/adk/adk.jd b/docs/html/tools/adk/adk.jd
index 1651747..7e75c11 100644
--- a/docs/html/tools/adk/adk.jd
+++ b/docs/html/tools/adk/adk.jd
@@ -1,5 +1,5 @@
 page.title=Accessory Development Kit 2011 Guide
-page.tags="adk"
+page.tags=adk
 @jd:body
 
   <div id="qv-wrapper">
diff --git a/docs/html/tools/adk/adk2.jd b/docs/html/tools/adk/adk2.jd
index c60e920..d69125a 100644
--- a/docs/html/tools/adk/adk2.jd
+++ b/docs/html/tools/adk/adk2.jd
@@ -1,5 +1,5 @@
 page.title=Accessory Development Kit 2012 Guide
-page.tags="adk"
+page.tags=adk
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/tools/adk/index.jd b/docs/html/tools/adk/index.jd
index e035115..e08748fc 100644
--- a/docs/html/tools/adk/index.jd
+++ b/docs/html/tools/adk/index.jd
@@ -1,5 +1,5 @@
 page.title=Accessory Development Kit
-page.tags="adk"
+page.tags=adk
 @jd:body
 
 <p>The Accessory Development Kit (ADK) is a reference implementation for hardware manufacturers and
diff --git a/docs/html/tools/debugging/debugging-memory.jd b/docs/html/tools/debugging/debugging-memory.jd
index 0454293..fccb67e 100644
--- a/docs/html/tools/debugging/debugging-memory.jd
+++ b/docs/html/tools/debugging/debugging-memory.jd
@@ -1,5 +1,5 @@
 page.title=Investigating Your RAM Usage
-page.tags="memory","OutOfMemoryError"
+page.tags=memory,OutOfMemoryError
 @jd:body
 
  <div id="qv-wrapper">
@@ -181,11 +181,18 @@
 
 <h2 id="ViewingAllocations">Viewing Overall Memory Allocations</h2>
 
-<p>For further analysis, you may want to observe how that your app's memory is
-divided between different categories, which you can do with the <code>adb meminfo</code> data.</p>
+<p>For further analysis, you may want to observe how your app's memory is
+divided between different types of RAM allocation with the
+following <a href="{@docRoot}tools/help/adb.html">adb</a> command:</p>
 
-<p>When talking about how much RAM your app is using with this data, the key metrics
-discussed below are:</p>
+<pre class="no-pretty-print">
+adb shell dumpsys meminfo &lt;package_name>
+</pre>
+
+<p>The output lists all of your app's current allocations, measured in kilobytes.</p>
+
+<p>When inspecting this information, you should be familiar with the
+following types of allocation:</p>
 
 <dl>
 <dt>Private (Clean and Dirty) RAM</dt>
@@ -210,15 +217,9 @@
 actual RAM weight of a process and for comparison against the RAM use of other processes and the
 total available RAM.</p>
 
-<p>You can look at the memory use of your app (measured in kilobytes) with the
-following adb command:</p>
-
-<pre class="no-pretty-print">
-adb shell dumpsys meminfo &lt;package_name>
-</pre>
 
 <p>For example, below is the the output for Gmail’s process on a tablet device. There is a lot of
-information here, but key points for discussion are highlighted in different colors.</p>
+information here, but key points for discussion are listed below.</p>
 
 <p class="note"><strong>Note:</strong> The information you see may vary slightly from what is shown
 here, as some details of the output differ across platform versions.</p>
@@ -491,4 +492,4 @@
 <p class="note"><strong>Tip:</strong> You can also perform the above steps by using the "monkey"
 test framework. For more information on running the monkey test framework, read the <a href=
 "{@docRoot}tools/help/monkeyrunner_concepts.html">monkeyrunner</a>
-documentation.</p>
\ No newline at end of file
+documentation.</p>
diff --git a/docs/html/tools/debugging/debugging-tracing.jd b/docs/html/tools/debugging/debugging-tracing.jd
index 8653da6..bd4afbc 100644
--- a/docs/html/tools/debugging/debugging-tracing.jd
+++ b/docs/html/tools/debugging/debugging-tracing.jd
@@ -38,8 +38,7 @@
   <h2 id="traceviewLayout">Traceview Layout</h2>
 
   <p>When you have a trace log file (generated by adding tracing code to your application or by DDMS),
-  you can have Traceview load the log files and display their data in a window visualizes your application
-  in two panels:</p>
+  you can load the log files in Traceview, which displays the log data in two panels:</p>
 
   <ul>
     <li>A <a href="#timelinepanel">timeline panel</a> -- describes when each thread and method
@@ -53,12 +52,11 @@
   
   <h3 id="timelinepanel">Timeline Panel</h3>
 
-  <p>The image below shows a close up of the timeline panel. Each thread&rsquo;s execution is shown
+  <p>Figure 1 shows a close up of the timeline panel. Each thread&rsquo;s execution is shown
   in its own row, with time increasing to the right. Each method is shown in another color (colors
   are reused in a round-robin fashion starting with the methods that have the most inclusive time).
   The thin lines underneath the first row show the extent (entry to exit) of all the calls to the
-  selected method. The method in this case is <code>LoadListener.nativeFinished()</code> and it was selected in
-  the profile view.</p>
+  selected method.</p>
 
   <img src="{@docRoot}images/traceview_timeline.png"
        alt="Traceview timeline panel"
@@ -94,23 +92,31 @@
   <p>There are two ways to generate trace logs:</p>
   <ul>
     <li>Include the {@link android.os.Debug} class in your code and call its
-  methods to start and stop logging of trace information to disk. This method is very precise because
-  you can specify in your code exactly where to start and stop logging trace data.</li>
-    <li>Use the method profiling feature of DDMS to generate trace logs. This method is less
-    precise since you do not modify code, but rather specify when to start and stop logging with
-    a DDMS. Although you have less control on exactly where the data is logged, this method is useful 
-    if you don't have access to the application's code, or if you do not need the precision of the first method.
+  methods such as {@link android.os.Debug#startMethodTracing()} and {@link
+  android.os.Debug#stopMethodTracing()}, to start and stop logging of trace information to disk.
+  This option is very precise because
+  you can specify exactly where to start and stop logging trace data in your code.</li>
+    <li>Use the method profiling feature of DDMS to generate trace logs. This option is less
+    precise because you do not modify code, but rather specify when to start and stop logging with
+    DDMS. Although you have less control on exactly where logging starts and stops,
+    this option is useful if you don't have access to the application's code, or if you do
+    not need precise log timing.
     </li>
   </ul>
   
   <p>Before you start generating trace logs, be aware of the following restrictions:</p>
   <ul>
-    <li>If you are using the {@link android.os.Debug} class, your device or emulator must have an SD card
-     and your application must have permission to write to the SD card. </li>
-    <li>If you are using DDMS, Android 2.1 and earlier devices must
+    <li>If you are using the {@link android.os.Debug} class,
+     your application must have permission to write to external storage
+     ({@link android.Manifest.permission#READ_EXTERNAL_STORAGE}). </li>
+    <li>If you are using DDMS:
+      <ul>
+        <li>Android 2.1 and earlier devices must
     have an SD card present and your application must have permission to write to the SD card.
-    <li>If you are using DDMS, Android 2.2 and later devices do not need an SD card. The trace log files are 
+        <li>Android 2.2 and later devices do not need an SD card. The trace log files are
     streamed directly to your development machine.</li>
+      </ul>
+    </li>
   </ul>
   
   <p>This document focuses on using the {@link android.os.Debug} class to generate trace data.  For more information on using DDMS
@@ -134,22 +140,22 @@
     Debug.stopMethodTracing();
 </pre>
 
-  <p>When your application calls startMethodTracing(), the system creates a file called
+  <p>When your application calls {@link android.os.Debug#startMethodTracing() startMethodTracing()},
+  the system creates a file called
   <code>&lt;trace-base-name&gt;.trace</code>. This contains the binary method trace data and a
   mapping table with thread and method names.</p>
 
   <p>The system then begins buffering the generated trace data, until your application calls
-  stopMethodTracing(), at which time it writes the buffered data to the output file. If the system
-  reaches the maximum buffer size before stopMethodTracing() is called, the system stops tracing
+  {@link android.os.Debug#stopMethodTracing() stopMethodTracing()}, at which time it writes
+  the buffered data to the output file. If the system
+  reaches the maximum buffer size before you call {@link android.os.Debug#stopMethodTracing()
+  stopMethodTracing()}, the system stops tracing
   and sends a notification to the console.</p>
 
-  <p>Interpreted code will run more slowly when profiling is enabled. Don't try to generate
-  absolute timings from the profiler results (i.e. "function X takes 2.5 seconds to run"). The
+  <p>Interpreted code runs more slowly when profiling is enabled. Don't try to generate
+  absolute timings from the profiler results (such as, "function X takes 2.5 seconds to run"). The
   times are only useful in relation to other profile output, so you can see if changes have made
-  the code faster or slower.</p>
-
-  <p>When using the Android emulator, you must specify an SD card when you create your AVD because the trace files
-  are written to the SD card. Your application must have permission to write to the SD card as well.
+  the code faster or slower relative to a previous profiling run.</p>
 
   <h2 id="copyingfiles">Copying Trace Files to a Host Machine</h2>
 
@@ -189,7 +195,7 @@
       "{@docRoot}images/tracedump.png"
           width="485"
           height="401" />
-       <p class="image-caption"><strong>Figure 3.</strong> Screenshot of dmtracedump</p>
+       <p class="img-caption"><strong>Figure 3.</strong> Screenshot of dmtracedump</p>
 
       <p>For each node, dmtracedump shows <code>&lt;ref&gt;
       <em>callname</em> (&lt;inc-ms&gt;, &lt;exc-ms&gt;,&lt;numcalls&gt;)</code>, where</p>
diff --git a/docs/html/tools/debugging/systrace.jd b/docs/html/tools/debugging/systrace.jd
index 287abe6..6472152 100644
--- a/docs/html/tools/debugging/systrace.jd
+++ b/docs/html/tools/debugging/systrace.jd
@@ -1,4 +1,5 @@
-page.title=Analyzing Display and Performance with Systrace
+page.title=Analyzing Display and Performance
+page.tags=systrace,speed
 parent.title=Debugging
 parent.link=index.html
 @jd:body
@@ -12,10 +13,11 @@
       <li><a href="#generate">Generating Traces</a>
         <ol>
           <li><a href="#limit-trace">Limiting trace data</a></li>
-          <li><a href="#config-categories">Configuring trace data categories</a></li>
-          <li><a href="#running">Running a trace</a></li>
+          <li><a href="#running-4.3">Tracing on Android 4.3 and higher</a>
+          <li><a href="#running-4.2">Tracing on Android 4.2 and lower</a></li>
         </ol>
       </li>
+      <li><a href="#app-trace">Tracing Application Code</a></li>
       <li><a href="#analysis">Analyzing Traces</a>
         <ol>
           <li><a href="#long-processes">Long running processes</a></li>
@@ -25,13 +27,12 @@
     </ol>
     <h2>See also</h2>
     <ol>
-      <li><a href="{@docRoot}tools/help/systrace.html">Systrace</a>
-      </li>
+      <li><a href="{@docRoot}tools/help/systrace.html">Systrace</a></li>
     </ol>
   </div>
 </div>
 
-<p>After building features, eliminating bugs and cleaning up your code, you should spend some
+<p>After building features, eliminating bugs, and cleaning up your code, you should spend some
   time looking at the performance of your application. The speed and smoothness with which your
   application draws pixels and performs operations has an significant impact on your users'
   experience.</p>
@@ -42,21 +43,21 @@
   threaded processes for resources, which can cause performance problems that are hard to diagnose.
 </p>
 
-<p>The {@code systrace} tool allows you to collect and review code execution data for your
+<p>The Systrace tool allows you to collect and review code execution data for your
   application and the Android system. You can use this data to diagnose execution problems and
   improve the performance of your application.</p>
 
 
 <h2 id="overview">Overview</h2>
 
-<p>{@code systrace} helps you analyze how the execution of your application fits into the larger
+<p>Systrace helps you analyze how the execution of your application fits into the larger
   Android environment, letting you see system and applications process execution on a common
   timeline. The tool allows you to generate highly detailed, interactive reports from devices
   running Android 4.1 and higher, such as the report in figure 1.</p>
 
 <img src="{@docRoot}images/systrace/report.png" alt="Systrace example report" id="figure1" />
 <p class="img-caption">
-  <strong>Figure 1.</strong> An example {@code systrace} report on 5 seconds of process execution
+  <strong>Figure 1.</strong> An example Systrace report on 5 seconds of process execution
   for a running application and related Android system processes.
 </p>
 
@@ -64,16 +65,21 @@
 <h2 id="generate">Generating Traces</h2>
 
 <p>In order to create a trace of your application, you must perform a few setup steps. First, you
-  must have a device running Android 4.1 or higher. Setup the device for
+  must have a device running Android 4.1 or higher. Set up the device for
   <a href="{@docRoot}tools/device.html#setting-up">debugging</a>, connect it to your development
-  system and install your application. Some types of trace information, specifically disk activity
-  and kernel work queues, require root access to the device, but most {@code systrace} log data
-  only requires that the device be enabled for developer debugging.</p>
+  system, and install your application. Some types of trace information, specifically disk activity
+  and kernel work queues, require that you have root access to the device. However, most Systrace
+  log data only requires that the device be enabled for developer debugging.</p>
+
+<p>Systrace traces can be run either from a
+  <a href="{@docRoot}tools/help/systrace.html#options">command line</a> or from a
+  <a href="{@docRoot}tools/help/systrace.html#gui">graphical user interface</a>. This guide
+  focuses on using the command line options.</p>
 
 
 <h3 id="limit-trace">Limiting trace data</h3>
 
-<p>The {@code systrace} tool can generate a potentially huge amount of data from applications
+<p>The Systrace tool can generate a potentially huge amount of data from applications
   and system sources. To limit the amount of data the tool collects and make the data more relevant
   to your analysis, use the following options:</p>
 
@@ -81,39 +87,68 @@
   <li>Limit the amount of time covered by the trace with the {@code -t, --time} option. The default
     length of a trace is 5 seconds.</li>
   <li>Limit the size of the data collected by the trace with the {@code -b, --buf-size} option.</li>
-  <li>Specify what types of processes are traced using the {@code --set-tags} option and the
-  {@code --disk}, {@code --cpu-freq}, {@code --cpu-idle}, {@code --cpu-load} options.</li>
+  <li>Specify what types of processes are traced. The types of processes that can be traced depends
+    on the version of Android you are running:
+    <ul>
+      <li>Android 4.2 and lower devices: Use the {@code --set-tags} option and the {@code --disk},
+        {@code --cpu-freq}, {@code --cpu-idle}, {@code --cpu-load} options.</li>
+      <li>Android 4.3 and higher devices: Use the {@code --list-categories} option to see what
+        categories are available on your test device.</li>
+    </ul>
+   </li>
 </ul>
 
 
-<h3 id="config-categories">Configuring trace data categories</h3>
+<h3 id="running-4.3">Tracing on Android 4.3 and higher</h3>
 
-<p>To use {@code systrace} effectively, you must specify the types of processes you want to trace.
+<p>To run a trace on Android 4.3 and higher devices:</p>
+
+<ol>
+  <li>Make sure the device is connected through a USB cable and is
+  <a href="{@docRoot}tools/device.html#setting-up">enabled for debugging</a>.</li>
+  <li>Run the trace with the options you want, for example:
+<pre>
+$ cd android-sdk/platform-tools/systrace
+$ python systrace.py --time=10 -o mynewtrace.html sched gfx view wm
+</pre>
+  </li>
+  <li>On the device, execute any user actions you want be included in the trace.</li>
+</ol>
+
+<p>For more information on the available options for running Systrace, see the
+<a href="{@docRoot}tools/help/systrace.html#options-4.3">Systrace</a> help page.</p>
+
+
+<h3 id="running-4.2">Tracing on Android 4.2 and lower</h3>
+
+<p>To use Systrace effectively with devices running Android 4.2 and lower,
+  you must configure the types of processes you want to trace before running a trace.
   The tool can gather the following types of process information:</p>
 
 <ul>
   <li>General system processes such as graphics, audio and input processes (selected using trace
-    <a href="{@docRoot}tools/help/systrace.html#tags">Tags</a>).</li>
+    <a href="{@docRoot}tools/help/systrace.html#tags">category tags</a>).</li>
   <li>Low level system information such as CPU, kernel and disk activity (selected using
-    <a href="{@docRoot}tools/help/systrace.html#options">Options</a>).</li>
+    <a href="{@docRoot}tools/help/systrace.html#options">options</a>).</li>
 </ul>
 
-<p>To set trace tags for {@code systrace} using the command-line:</p>
+<p>To set trace tags for Systrace using the command-line:</p>
 
 <ol>
   <li>Use the {@code --set-tags} option:
 <pre>
-$> python systrace.py --set-tags=gfx,view,wm
+$ cd android-sdk/platform-tools/systrace
+$ python systrace.py --set-tags=gfx,view,wm
 </pre>
   </li>
   <li>Stop and restart the {@code adb} shell to enable tracing of these processes.
 <pre>
-$> adb shell stop
-$> adb shell start
+$ adb shell stop
+$ adb shell start
 </pre></li>
 </ol>
 
-<p>To set trace tags for {@code systrace} using the device user interface:</p>
+<p>To set trace tags for Systrace using the device user interface:</p>
 
 <ol>
   <li>On the device connected for tracing, navigate to: <strong>Settings &gt;
@@ -126,9 +161,6 @@
   selecting trace tags using this method.
 </p>
 
-
-<h3 id="running">Running a trace</h3>
-
 <p>After you have configured the category tags for your trace, you can start collecting
   information for analysis.</p>
 
@@ -139,21 +171,77 @@
   <a href="{@docRoot}tools/device.html#setting-up">enabled for debugging</a>.</li>
   <li>Run the trace with the low-level system trace options and limits you want, for example:
 <pre>
-$> python systrace.py --cpu-freq --cpu-load --time=10 -o mytracefile.html
+$ python systrace.py --cpu-freq --cpu-load --time=10 -o mytracefile.html
 </pre>
   </li>
   <li>On the device, execute any user actions you want be included in the trace.</li>
 </ol>
 
+<p>For more information on the available options for running Systrace, see the
+<a href="{@docRoot}tools/help/systrace.html#options-pre-4.3">Systrace</a> help page.</p>
+
+
+<h2 id="app-trace">Tracing Application Code</h2>
+
+<p>The Systrace tool can trace the execution of code within your application. In Android
+4.3 (API level 18) and higher, you can use the methods of the {@link android.os.Trace} class to
+add instrumentation to your application code and see the results in a Systrace report.</p>
+
+<p>The following code example shows how to use the {@link android.os.Trace} class to track
+execution of an application method, including two nested code blocks within that method.</p>
+
+<pre>
+public void ProcessPeople() {
+    Trace.beginSection("ProcessPeople");
+    try {
+        Trace.beginSection("Processing Jane");
+        try {
+            // code for Jane task...
+        } finally {
+            Trace.endSection(); // ends "Processing Jane"
+        }
+
+        Trace.beginSection("Processing John");
+        try {
+            // code for John task...
+        } finally {
+            Trace.endSection(); // ends "Processing John"
+        }
+    } finally {
+        Trace.endSection(); // ends "ProcessPeople"
+    }
+}
+</pre>
+<p class="note">
+  <strong>Note:</strong> When you nest trace calls within each other, the
+  {@link android.os.Trace#endSection} method ends the most recently called
+  {@link android.os.Trace#beginSection} method. This means that a trace started within another
+  trace cannot extend beyond the end of the enclosing trace, so make sure your beginning and
+  ending method calls are properly matched to measure your applications processing.
+</p>
+
+<p class="note">
+  <strong>Note:</strong> Traces must begin and end on the same thread. Do not call
+  {@link android.os.Trace#beginSection} on one thread of execution and then attempt to end the
+  trace with a call to {@link android.os.Trace#endSection} on another thread.
+</p>
+
+<p>When using application-level tracing with Systrace, you must specify the package name of your
+application in the user interface or specify the {@code -a} or {@code --app=} options on the
+command line. For more information, see the
+<a href="{@docRoot}tools/help/systrace.html">Systrace</a> help page.</p>
+
+<!-- todo: add ndk coverage -->
+
 
 <h2 id="analysis">Analyzing Traces</h2>
 
-<p>After you have generated a trace using {@code systrace}, it lists the location of the output
+<p>After you have generated a trace using Systrace, it lists the location of the output
   file and you can open the report using a web browser.
   How you use the trace data depends on the performance issues you are investigating. However,
   this section provides some general instructions on how to analyze a trace.</p>
 
-<p>The reports generated by {@code systrace} are interactive, allowing you to zoom into and out of
+<p>The reports generated by Systrace are interactive, allowing you to zoom into and out of
   the process execution details. Use the <em>W</em> key to zoom in, the <em>S</em>
   key to zoom out, the <em>A</em> key to pan left and the <em>D</em> key to pan
   right. Select a task in timeline using your mouse to get more information about the task.
@@ -193,7 +281,7 @@
 
 <h3 id="display-interupts">Interruptions in display execution</h3>
 
-<p>The {@code systrace} tool is particularly useful in analyzing application display slowness,
+<p>The Systrace tool is particularly useful in analyzing application display slowness,
   or pauses in animations, because it shows you the execution of your application across multiple
   system processes. With display execution, drawing screen frames with a regular rhythm is essential
   for good performance. Having a regular rhythm for display ensures that animations and motion are
@@ -201,7 +289,7 @@
   from the users perspective.</p>
 
 <p>If you are analyzing an application for this type of problem, examine the
-  <strong>SurfaceFlinger</strong> process in the {@code systrace} report where your application is
+  <strong>SurfaceFlinger</strong> process in the Systrace report where your application is
   also executing to look for places where it drops out of its regular rhythm.</p>
 
 <img src="{@docRoot}images/systrace/display-rhythm.png" alt="Systrace exerpt of display processing"
@@ -231,9 +319,9 @@
 </p>
 
 <p class="note">
-  <strong>Note:</strong> When using {@code systrace} to analyze display problems, make sure
+  <strong>Note:</strong> When using Systrace to analyze display problems, make sure
   you activate the tracing tags for <strong>Graphics</strong> and <strong>Views</strong>.
 </p>
 
-<p>For more information on the command line options and keyboard controls for {@code systrace},
-see the <a href="{@docRoot}tools/help/systrace.html">Systrace</a> reference page.</p>
\ No newline at end of file
+<p>For more information on the command line options and keyboard controls for Systrace,
+see the <a href="{@docRoot}tools/help/systrace.html">Systrace</a> help page.</p>
\ No newline at end of file
diff --git a/docs/html/tools/help/adb.jd b/docs/html/tools/help/adb.jd
index 3002d60..1850123 100644
--- a/docs/html/tools/help/adb.jd
+++ b/docs/html/tools/help/adb.jd
@@ -1,7 +1,7 @@
 page.title=Android Debug Bridge
 parent.title=Tools
 parent.link=index.html
-page.tags="adb"
+page.tags=adb
 @jd:body
 
 <div id="qv-wrapper">
@@ -1130,10 +1130,11 @@
 
 <h3 id="screenrecord">Recording a device screen</h3>
 
-<p>The {@code screenrecord} command is a shell utility for recording the display of a device as you
-  use it. The utility records screen activity to an MPEG-4 file, which you can then download and use
-  as part of a video presentation. This utility is useful for developers who want to create
-  promotional or training videos without using a separate recording device.</p>
+<p>The {@code screenrecord} command is a shell utility for recording the display of devices
+  running Android 4.4 (API level 19) and higher. The utility records screen activity to an MPEG-4
+  file, which you can then download and use as part of a video presentation. This utility is useful
+  for developers who want to create promotional or training videos without using a separate
+  recording device.</p>
 
 <p>To use the {@code screenrecord} from the command line, type the following:
 
diff --git a/docs/html/tools/help/adt.jd b/docs/html/tools/help/adt.jd
index 4dac574..1bb3015 100644
--- a/docs/html/tools/help/adt.jd
+++ b/docs/html/tools/help/adt.jd
@@ -1,5 +1,5 @@
 page.title=Android Developer Tools
-page.tags="adt"
+page.tags=adt
 @jd:body
 
   <div id="qv-wrapper">
diff --git a/docs/html/tools/help/draw9patch.jd b/docs/html/tools/help/draw9patch.jd
index ebf2c6c..859b1cf 100644
--- a/docs/html/tools/help/draw9patch.jd
+++ b/docs/html/tools/help/draw9patch.jd
@@ -1,5 +1,5 @@
 page.title=Draw 9-patch
-page.tags="NinePatch"
+page.tags=NinePatch
 @jd:body
 
 <p>The Draw 9-patch tool allows you to easily create a 
diff --git a/docs/html/tools/help/monitor.jd b/docs/html/tools/help/monitor.jd
index e1fe772..513eb10 100644
--- a/docs/html/tools/help/monitor.jd
+++ b/docs/html/tools/help/monitor.jd
@@ -15,13 +15,14 @@
 
 <p>Android Device Monitor is a stand-alone tool that provides a graphical user interface for
 several Android application debugging and analysis tools. The Monitor tool does not
-require installation of a integrated development environment, such as Eclipse, and encapsulates the
+require installation of an integrated development environment, such as Eclipse, and encapsulates the
 following tools:</p>
 
 <ul>
   <li><a href="{@docRoot}tools/debugging/ddms.html">DDMS</a></li>
   <li><a href="gltracer.html">Tracer for OpenGL ES</a></li>
   <li><a href="hierarchy-viewer.html">Hierarchy Viewer</a></li>
+  <li><a href="systrace.html">Systrace</a></li>
   <li><a href="traceview.html">Traceview</a></li>
   <li>Pixel Perfect magnification viewer</li>
 </ul>
diff --git a/docs/html/tools/help/proguard.jd b/docs/html/tools/help/proguard.jd
index be0b8dc..3ba7db2 100644
--- a/docs/html/tools/help/proguard.jd
+++ b/docs/html/tools/help/proguard.jd
@@ -61,6 +61,12 @@
   <p>To enable ProGuard so that it runs as part of an Ant or Eclipse build, set the
   <code>proguard.config</code> property in the <code>&lt;project_root&gt;/project.properties</code>
   file. The path can be an absolute path or a path relative to the project's root.</p>
+
+<p class="note"><strong>Note:</strong> When using Android Studio, you must add Proguard
+to your <code>gradle.build</code> file's build types. For more information, see the
+<a href="http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Running-ProGuard"
+>Gradle Plugin User Guide</a>.
+
 <p>If you left the <code>proguard.cfg</code> file in its default location (the project's root directory),
 you can specify its location like this:</p>
 <pre class="no-pretty-print">
diff --git a/docs/html/tools/help/systrace.jd b/docs/html/tools/help/systrace.jd
index 010cc78..d6fc05e 100644
--- a/docs/html/tools/help/systrace.jd
+++ b/docs/html/tools/help/systrace.jd
@@ -4,47 +4,135 @@
 @jd:body
 
 
-<p>The {@code systrace} tool helps analyze the performance of your application by capturing and
+<p>The Systrace tool helps analyze the performance of your application by capturing and
   displaying execution times of your applications processes and other Android system processes. The
-  tool combines data from the Android kernel such as the CPU scheduler, disk activity and
+  tool combines data from the Android kernel such as the CPU scheduler, disk activity, and
   application threads to generate an HTML report that shows an overall picture of an Android
   device’s system processes for a given period of time.</p>
 
-<p>The {@code systrace} tool is particularly useful in diagnosing display problems where an
+<p>The Systrace tool is particularly useful in diagnosing display problems where an
   application is slow to draw or stutters while displaying motion or animation. For more information
-  on how to use {@code systrace}, see <a href="{@docRoot}tools/debugging/systrace.html">Analyzing
-  Display and Performance with Systrace</a>.</p>
+  on how to use Systrace, see <a href="{@docRoot}tools/debugging/systrace.html">Analyzing
+  Display and Performance</a>.</p>
 
 
-<h2 id="usage">Usage</h2>
 
-<p>In order to run {@code systrace}, the {@code adb} tool and
-<a href="http://www.python.org/">Python</a> must be installed and included in your development
+<h2 id="requirements">Requirements</h2>
+
+<p>In order to run Systrace, you must have Android SDK Tools 20 or later installed. You must also
+have <a href="http://www.python.org/">Python</a> installed and included in your development
 computer's execution path. In order to generate a trace, you must connect a device running Android
-4.1 (API Level 16) or higher to your development system using a USB debugging connection.</p>
+4.1 (API Level 16) or higher to your development system using a
+<a href="{@docRoot}tools/device.html#setting-up">USB debugging connection</a>.</p>
 
-<p>The syntax for running {@code systrace} is as follows.</p>
+<p>The Systrace tool can be run either from one of the Android SDK's graphical user interface
+tools, or from the command line. The following sections describe how to run the tool using either
+of these methods.</p>
+
+
+<h2 id="gui">User Interface</h2>
+
+<p>The Systrace tool can be run from the
+<a href="{@docRoot}tools/help/adt.html">Android Developer Tools</a> (ADT) in Eclipse,
+<a href="{@docRoot}sdk/installing/studio.html">Android Studio</a>,
+or the Android <a href="{@docRoot}tools/help/monitor.html">Device Monitor</a>.
+
+<p>To run the Systrace user interface:</p>
+
+<div class="toggle-content closed">
+<p style="margin-top:5px"><a href="#" onclick="return toggleContent(this)">
+  <img src="/assets/images/triangle-closed.png" class="toggle-content-img" alt=""
+  />Using Eclipse</a></p>
+
+  <div class="toggle-content-toggleme">
+  <ol>
+    <li>In Eclipse, open an Android application project.</li>
+    <li>Switch to the DDMS perspective, by selecting <strong>Window &gt; Perspectives &gt;
+      DDMS</strong>.</li>
+    <li>In the <strong>Devices</strong> tab, select the device on which to run a trace. If no
+      devices are listed, make sure your device is connected via USB cable and that debugging is
+      enabled on the device.</li>
+    <li>Click the Systrace icon <img src="{@docRoot}images/systrace/systrace-button.png"
+      style="margin:0"/> at the top of the <strong>Devices</strong> panel to configure tracing.</li>
+    <li>Set the tracing options and click <strong>OK</strong> to start the trace.</li>
+  </ol>
+  </div>
+</div>
+
+<div class="toggle-content closed">
+<p style="margin-top:5px"><a href="#" onclick="return toggleContent(this)">
+  <img src="/assets/images/triangle-closed.png" class="toggle-content-img" alt=""
+  />Using Android Studio</a></p>
+
+  <div class="toggle-content-toggleme">
+  <ol>
+    <li>In <a href="{@docRoot}sdk/installing/studio.html">Android Studio</a>, open an
+      Android application project.</li>
+    <li>Open the Device Monitor by selecting <strong>Tools &gt; Android &gt; Monitor</strong>.</li>
+    <li>In the <strong>Devices</strong> tab, select the device on which to run a trace. If no
+      devices are listed, make sure your device is connected via USB cable and that debugging is
+      enabled on the device.</li>
+    <li>Click the Systrace icon <img src="{@docRoot}images/systrace/systrace-button.png"
+      style="margin:0"/> at the top of the <strong>Devices</strong> panel to configure tracing.</li>
+    <li>Set the tracing options and click <strong>OK</strong> to start the trace.</li>
+  </ol>
+  </div>
+</div>
+
+<div class="toggle-content closed">
+<p style="margin-top:5px"><a href="#" onclick="return toggleContent(this)">
+  <img src="/assets/images/triangle-closed.png" class="toggle-content-img" alt=""
+  />Using Device Monitor</a></p>
+
+  <div class="toggle-content-toggleme">
+  <ol>
+    <li>Navigate to your SDK {@code tools/} directory.</li>
+    <li>Run the {@code monitor} program.</li>
+    <li>In the <strong>Devices</strong> tab, select the device on which to run a trace. If no
+      devices are listed, make sure your device is connected via USB cable and that debugging is
+      enabled on the device.</li>
+    <li>Click the Systrace icon <img src="{@docRoot}images/systrace/systrace-button.png"
+      style="margin:0"/> at the top of the <strong>Devices</strong> panel to configure tracing.</li>
+    <li>Set the tracing options and click <strong>OK</strong> to start the trace.</li>
+  </ol>
+  </div>
+</div>
+
+
+
+<h2 id="options">Command Line Usage</h2>
+
+<p>The Systrace tool has different command line options for devices running Android 4.3 (API
+level 18) and higher versus devices running Android 4.2 (API level 17) and lower. The following
+sections describe the different command line options for each version.</p>
+
+<p>The general syntax for running Systrace from the command line is as follows.</p>
 
 <pre>
-$> python systrace.py [options]
+$ python systrace.py [options] [category1] [category2] ... [categoryN]
 </pre>
 
-<p>Here is an example execution run that sets trace tags and generates a trace from a connected
-Android device.</p>
+<p>See the sections below for example Systrace sessions.</p>
+
+
+<h3 id="options-4.3">Android 4.3 and higher options</h3>
+
+<p>When you use Systrace on devices running Android 4.3 and higher, you must specify at least one
+trace category tag. Here is an example execution run that sets trace tags and generates a trace
+from a connected device.</p>
 
 <pre>
-$> cd <em>android-sdk</em>/tools/systrace
-$> python systrace.py --set-tags gfx,view,wm
-$> adb shell stop
-$> adb shell start
-$> python systrace.py --disk --time=10 -o mynewtrace.html
+$ cd <em>android-sdk</em>/platform-tools/systrace
+$ python systrace.py --time=10 -o mynewtrace.html sched gfx view wm
 </pre>
 
+<p class="note">
+  <strong>Tip:</strong> If you want to see the names of tasks in the trace output, you <em>must</em>
+  include the {@code sched} category in your command parameters.
+</p>
 
-
-<h2 id="options">Options</h2>
-
-<p>The table below lists the command line options for {@code systrace}.</p>
+<p>The table below lists the Systrace command line options for devices running Android 4.3
+(API level 18) and higher.</p>
 
 <table>
   <tr>
@@ -54,6 +142,12 @@
   </tr>
 
   <tr>
+    <td><nobr><code>-h, --help</code></nobr></td>
+
+    <td>Show the help message.</td>
+  </tr>
+
+  <tr>
     <td><code>-o&nbsp;&lt;<em>FILE</em>&gt;</code></td>
 
     <td>Write the HTML trace report to the specified file.</td>
@@ -62,14 +156,155 @@
   <tr>
     <td><code>-t N, --time=N</code></td>
 
-    <td>Trace activity for N seconds. Default value is 5 seconds.</td>
+    <td>Trace activity for <em>N</em> seconds. The default value is 5 seconds.</td>
   </tr>
 
   <tr>
     <td><code>-b N, --buf-size=N</code></td>
 
-    <td>Use a trace buffer size of N kilobytes. This option lets you limit the total size of the
-    data collected during a trace.</td>
+    <td>Use a trace buffer size of <em>N</em> kilobytes. This option lets you limit the total size
+    of the data collected during a trace.</td>
+  </tr>
+
+  <tr>
+    <td><code>-k&nbsp;&lt;<em>KFUNCS</em>&gt;<br>
+        --ktrace=&lt;<em>KFUNCS</em>&gt;</code></td>
+
+    <td>Trace the activity of specific kernel functions, specified in a comma-separated list.</td>
+  </tr>
+
+  <tr>
+    <td><code>-l, --list-categories</code></td>
+
+    <td>List the available tracing category tags. The available tags are:
+
+      <ul>
+        <li><code>gfx</code> - Graphics</li>
+        <li><code>input</code> - Input</li>
+        <li><code>view</code> - View</li>
+        <li><code>webview</code> - WebView</li>
+        <li><code>wm</code> - Window Manager</li>
+        <li><code>am</code> - Activity Manager</li>
+        <li><code>audio</code> - Audio</li>
+        <li><code>video</code> - Video</li>
+        <li><code>camera</code> - Camera</li>
+        <li><code>hal</code> - Hardware Modules</li>
+        <li><code>res</code> - Resource Loading</li>
+        <li><code>dalvik</code> - Dalvik VM</li>
+        <li><code>rs</code> - RenderScript</li>
+        <li><code>sched</code> - CPU Scheduling</li>
+        <li><code>freq</code> - CPU Frequency</li>
+        <li><code>membus</code> - Memory Bus Utilization</li>
+        <li><code>idle</code> - CPU Idle</li>
+        <li><code>disk</code> - Disk input and output</li>
+        <li><code>load</code> - CPU Load</li>
+        <li><code>sync</code> - Synchronization Manager</li>
+        <li><code>workq</code> - Kernel Workqueues</li>
+      </ul>
+
+      <p class="note"><strong>Note:</strong> Some trace categories are not supported on all
+      devices.</p>
+
+      <p class="note"><strong>Tip:</strong> If you want to see the names of tasks in the trace
+      output, you <em>must</em> include the {@code sched} category in your command parameters.</p>
+
+    </td>
+  </tr>
+
+  <tr>
+    <td><code>-a&nbsp;&lt;<em>APP_NAME</em>&gt;<br>
+        --app=&lt;<em>APP_NAME</em>&gt;</code></td>
+
+    <td>Enable tracing for applications, specified as a comma-separated list of
+    <a href="{@docRoot}guide/topics/manifest/manifest-element.html#package">package names</a>.
+    The apps must contain tracing instrumentation calls from the {@link android.os.Trace} class.
+    For more information, see <a href="{@docRoot}tools/debugging/systrace.html#app-trace">Analyzing
+    Display and Performance</a>.
+    </td>
+  </tr>
+
+
+
+  <tr>
+    <td><code>--link-assets</code></td>
+
+    <td>Link to the original CSS or JavaScript resources instead of embedding them in the HTML
+      trace report.</td>
+  </tr>
+
+  <tr>
+    <td><code>--from-file=&lt;<em>FROM_FILE</em>&gt;</code></td>
+
+    <td>Create the interactive Systrace report from a file, instead of running a live trace.</td>
+  </tr>
+
+  <tr>
+    <td><code>--asset-dir=&lt;<em>ASSET_DIR</em>&gt;</code></td>
+
+    <td>Specify a directory for the trace report assets. This option is useful for maintaining a
+      single set of assets for multiple Systrace reports.</td>
+  </tr>
+
+  <tr>
+    <td style="white-space:nowrap">
+    <code>-e &lt;<em>DEVICE_SERIAL</em>&gt;<br>
+    --serial=&lt;<em>DEVICE_SERIAL</em>&gt;</code></td>
+
+    <td>Conduct the trace on a specific connected device, identified by its
+      <a href="{@docRoot}tools/help/adb.html#devicestatus">device serial number</a>.</td>
+  </tr>
+
+</table>
+
+
+<h3 id="options-pre-4.3">Android 4.2 and lower options</h3>
+
+<p>Using Systrace on the command line with devices running Android 4.2 and lower is typically a
+two-step process. You must first set the trace tags you want to capture and then run the trace.
+Here is an example execution run that sets trace tags and generates a trace from a connected
+device.</p>
+
+<pre>
+$ cd <em>android-sdk</em>/platform-tools/systrace
+$ python systrace.py --set-tags gfx,view,wm
+$ adb shell stop
+$ adb shell start
+$ python systrace.py --disk --time=10 -o mynewtrace.html
+</pre>
+
+<p>The table below lists the Systrace command line options for devices running Android 4.2
+(API level 17) and lower.</p>
+
+<table>
+  <tr>
+    <th>Option</th>
+
+    <th>Description</th>
+  </tr>
+
+  <tr>
+    <td><nobr><code>-h, --help</code></nobr></td>
+
+    <td>Show the help message.</td>
+  </tr>
+
+  <tr>
+    <td><code>-o&nbsp;&lt;<em>FILE</em>&gt;</code></td>
+
+    <td>Write the HTML trace report to the specified file.</td>
+  </tr>
+
+  <tr>
+    <td><code>-t N, --time=N</code></td>
+
+    <td>Trace activity for <em>N</em> seconds. The default value is 5 seconds.</td>
+  </tr>
+
+  <tr>
+    <td><code>-b N, --buf-size=N</code></td>
+
+    <td>Use a trace buffer size of <em>N</em> kilobytes. This option lets you limit the total size
+    of the data collected during a trace.</td>
   </tr>
 
   <tr>
@@ -106,6 +341,12 @@
   </tr>
 
   <tr>
+    <td><nobr><code>-u, --bus-utilization</code></nobr></td>
+
+    <td>Trace the bus utilization levels. This option requires root access on the device.</td>
+  </tr>
+
+  <tr>
     <td><code>-w, --workqueue</code></td>
 
     <td>Trace kernel work queues. This option requires root access on the device.</td>
@@ -122,13 +363,13 @@
         <li><code>webview</code> - WebView</li>
         <li><code>wm</code> - Window Manager</li>
         <li><code>am</code> - Activity Manager</li>
-        <li><code>sync</code> - Sync Manager</li>
+        <li><code>sync</code> - Synchronization Manager</li>
         <li><code>audio</code> - Audio</li>
         <li><code>video</code> - Video</li>
         <li><code>camera</code> - Camera</li>
       </ul>
       <p class="note"><strong>Note:</strong> When setting trace tags from the command line, you
-      must stop and restart the framework ({@code $&gt; adb shell stop; adb shell start}) for the
+      must stop and restart the framework ({@code $ adb shell stop; adb shell start}) for the
       tag tracing changes to take effect.</p>
     </td>
   </tr>
@@ -140,22 +381,16 @@
     report.</td>
   </tr>
 
-  <tr>
-    <td><nobr><code>-h, --help</code></nobr></td>
-
-    <td>Show the help message.</td>
-  </tr>
-
 </table>
 
-<p>You can set the trace <a href="#tags">tags</a> for {@code systrace} with your device's user
-interface, by navigating to <strong>Settings &gt; Developer options &gt; Monitoring &gt; Enable
-traces</strong>.</p>
+<p>You can set the trace <a href="#tags">tags</a> for Systrace on
+your Android 4.2 and lower device by navigating to <strong>Settings &gt; Developer options &gt;
+Monitoring &gt; Enable traces</strong>.</p>
 
 
 <h2 id="viewing-options">Trace Viewing Shortcuts</h2>
 
-<p>The table below lists the keyboard shortcuts that are available while viewing a {@code systrace}
+<p>The table below lists the keyboard shortcuts that are available while viewing a Systrace
 trace HTML report.</p>
 
 <table>
diff --git a/docs/html/tools/samples/index.jd b/docs/html/tools/samples/index.jd
index 76ba37a..a0d11e9 100644
--- a/docs/html/tools/samples/index.jd
+++ b/docs/html/tools/samples/index.jd
@@ -1,5 +1,5 @@
 page.title=Samples
-page.tags="example","code"
+page.tags=example,code
 @jd:body
 
 <p>To help you understand some fundamental Android APIs and coding practices, a variety of sample
@@ -29,4 +29,4 @@
   <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API level</a>.</p>
 
 <p>You can easily create new Android projects with the downloaded samples, modify them
-if you'd like, and then run them on an emulator or device.</p>
\ No newline at end of file
+if you'd like, and then run them on an emulator or device.</p>
diff --git a/docs/html/tools/sdk/ndk/index.jd b/docs/html/tools/sdk/ndk/index.jd
index a418f90..87f8a87 100644
--- a/docs/html/tools/sdk/ndk/index.jd
+++ b/docs/html/tools/sdk/ndk/index.jd
@@ -2822,7 +2822,7 @@
   <p>Before you get started make sure that you have downloaded the latest <a href=
   "{@docRoot}sdk/index.html">Android SDK</a> and upgraded your applications and environment as
   needed. The NDK is compatible with older platform versions but not older versions of the SDK tools.
-  Also, take a moment to review the <a href="{@docRoot}tools/sdk/ndk/overview.html#reqs">System and
+  Also, take a moment to review the <a href="#Reqs">System and
 Software Requirements</a>
   for the NDK, if you haven't already.</p>
 
diff --git a/docs/html/tools/sdk/preview/features.jd b/docs/html/tools/sdk/preview/features.jd
index 02897cd..2bdb0f4 100644
--- a/docs/html/tools/sdk/preview/features.jd
+++ b/docs/html/tools/sdk/preview/features.jd
@@ -1,3 +1,4 @@
+excludeFromSuggestions=true
 @jd:body
 
 <script type="text/javascript">
diff --git a/docs/html/tools/sdk/preview/index.jd b/docs/html/tools/sdk/preview/index.jd
index d96df93..713730e 100644
--- a/docs/html/tools/sdk/preview/index.jd
+++ b/docs/html/tools/sdk/preview/index.jd
@@ -1,3 +1,4 @@
 sdk.redirect=true
 page.template=sdk
+excludeFromSuggestions=true
 @jd:body
diff --git a/docs/html/tools/sdk/preview/installing.jd b/docs/html/tools/sdk/preview/installing.jd
index c40e531..d248b67 100644
--- a/docs/html/tools/sdk/preview/installing.jd
+++ b/docs/html/tools/sdk/preview/installing.jd
@@ -1,3 +1,4 @@
+excludeFromSuggestions=true
 @jd:body
 
 <script type="text/javascript">
diff --git a/docs/html/tools/sdk/preview/requirements.jd b/docs/html/tools/sdk/preview/requirements.jd
index b5aed80..b62ee05 100644
--- a/docs/html/tools/sdk/preview/requirements.jd
+++ b/docs/html/tools/sdk/preview/requirements.jd
@@ -1,3 +1,4 @@
+excludeFromSuggestions=true
 @jd:body
 
 <script type="text/javascript">
diff --git a/docs/html/tools/sdk/preview/upgrading.jd b/docs/html/tools/sdk/preview/upgrading.jd
index 1c53bdb..3b90696 100644
--- a/docs/html/tools/sdk/preview/upgrading.jd
+++ b/docs/html/tools/sdk/preview/upgrading.jd
@@ -1,3 +1,4 @@
+excludeFromSuggestions=true
 @jd:body
 
 <script type="text/javascript">
diff --git a/docs/html/tools/support-library/setup.jd b/docs/html/tools/support-library/setup.jd
index 73d9468..2d2065a 100644
--- a/docs/html/tools/support-library/setup.jd
+++ b/docs/html/tools/support-library/setup.jd
@@ -180,8 +180,8 @@
         file and select <strong>Build Path &gt; Add to Build Path</strong>. For example, when
         creating the the v7 appcompat project, add both the {@code android-support-v4.jar} and
         {@code android-support-v7-appcompat.jar} files to the build path.</li>
-      <li>Right-click the project and select <strong>Build Path &gt; Configure Build Path</strong>.
-        </li>
+      <li>Right-click the library project folder and select <strong>Build Path &gt; Configure
+        Build Path</strong>.</li>
       <li>In the <strong>Order and Export</strong> tab, check the <code>.jar</code> files you just
         added to the build path, so they are available to projects that depend on this library
         project. For example, the {@code appcompat} project requires you to export both the
@@ -197,12 +197,13 @@
 
 <p>Add the library to your application project:</p>
   <ol>
-    <li>In the Project Explorer, right-click your project and select <strong>Properties</strong>.
-    <li>In the Library pane, click <strong>Add</strong>.
+    <li>In the Project Explorer, right-click your project and select <strong>Properties</strong>.</li>
+    <li>In the category panel on the left side of the dialog, select <strong>Android</strong>.</li>
+    <li>In the Library pane, click the <strong>Add</strong> button.</li>
     <li>Select the library project and click <strong>OK</strong>. For example, the
       {@code appcompat} project should be listed as <strong>android-support-v7-appcompat</strong>.
       </li>
-    <li>In the properties window, click <strong>OK</strong>.
+    <li>In the properties window, click <strong>OK</strong>.</li>
   </ol>
 
   </div>
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index 39eecf8..1ac10e0 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -138,7 +138,7 @@
       <li><a href="<?cs var:toroot ?>tools/debugging/improving-w-lint.html"><span class="en">Improving Your Code with lint</span></a></li>
       <li><a href="<?cs var:toroot ?>tools/debugging/debugging-ui.html"><span class="en">Optimizing your UI</span></a></li>
       <li><a href="<?cs var:toroot ?>tools/debugging/debugging-tracing.html"><span class="en">Profiling with Traceview and dmtracedump</span></a></li>
-      <li><a href="<?cs var:toroot ?>tools/debugging/systrace.html"><span class="en">Analysing Display and Performance with Systrace</span></a></li>
+      <li><a href="<?cs var:toroot ?>tools/debugging/systrace.html"><span class="en">Analyzing Display and Performance</span></a></li>
       <li><a href="<?cs var:toroot ?>tools/debugging/debugging-memory.html">Investigating Your RAM Usage</a></li>
       <li><a href="<?cs var:toroot ?>tools/debugging/debugging-devtools.html"><span class="en">Using the Dev Tools App</span></a></li>
     </ul>
diff --git a/docs/html/training/accessibility/index.jd b/docs/html/training/accessibility/index.jd
index 0af1d87..ea54dc4 100644
--- a/docs/html/training/accessibility/index.jd
+++ b/docs/html/training/accessibility/index.jd
@@ -1,5 +1,5 @@
 page.title=Implementing Accessibility
-page.tags="navigation","input"
+page.tags=navigation,input
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/activity-testing/index.jd b/docs/html/training/activity-testing/index.jd
index ddede71..b9542b6 100644
--- a/docs/html/training/activity-testing/index.jd
+++ b/docs/html/training/activity-testing/index.jd
@@ -1,5 +1,5 @@
 page.title=Testing Your Android Activity
-page.tags="testing"
+page.tags=testing
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/animation/index.jd b/docs/html/training/animation/index.jd
index b6940f8..4f37788 100644
--- a/docs/html/training/animation/index.jd
+++ b/docs/html/training/animation/index.jd
@@ -1,5 +1,5 @@
 page.title=Adding Animations
-page.tags="Animator","views","layout","user interface"
+page.tags=Animator,views,layout,user interface
 trainingnavtop=true
 startpage=true
 
@@ -84,4 +84,4 @@
       <dd>
         Learn how to enable built-in animations when adding, removing, or updating child views in a layout.
       </dd>
-    </dl>
\ No newline at end of file
+    </dl>
diff --git a/docs/html/training/articles/memory.jd b/docs/html/training/articles/memory.jd
index cdc0cd4..f15af68 100644
--- a/docs/html/training/articles/memory.jd
+++ b/docs/html/training/articles/memory.jd
@@ -1,5 +1,5 @@
 page.title=Managing Your App's Memory
-page.tags="ram","low memory","OutOfMemoryError","onTrimMemory"
+page.tags=ram,low memory,OutOfMemoryError,onTrimMemory
 page.article=true
 @jd:body
 
diff --git a/docs/html/training/articles/perf-anr.jd b/docs/html/training/articles/perf-anr.jd
index 87cfc1c..b32cc4f 100644
--- a/docs/html/training/articles/perf-anr.jd
+++ b/docs/html/training/articles/perf-anr.jd
@@ -1,5 +1,5 @@
 page.title=Keeping Your App Responsive
-page.tags="threads","asynctask"
+page.tags=threads,asynctask
 
 page.article=true
 @jd:body
diff --git a/docs/html/training/articles/perf-jni.jd b/docs/html/training/articles/perf-jni.jd
index 9f880ec..435d231 100644
--- a/docs/html/training/articles/perf-jni.jd
+++ b/docs/html/training/articles/perf-jni.jd
@@ -1,5 +1,5 @@
 page.title=JNI Tips
-page.tags="ndk","native"
+page.tags=ndk,native
 
 page.article=true
 @jd:body
diff --git a/docs/html/training/articles/perf-tips.jd b/docs/html/training/articles/perf-tips.jd
index 7ff6c5c..1660b7f 100644
--- a/docs/html/training/articles/perf-tips.jd
+++ b/docs/html/training/articles/perf-tips.jd
@@ -16,7 +16,6 @@
   <li><a href="#AvoidFloat">Avoid Using Floating-Point</a></li>
   <li><a href="#UseLibraries">Know and Use the Libraries</a></li>
   <li><a href="#NativeMethods">Use Native Methods Carefully</a></li>
-  <li><a href="#library">Know And Use The Libraries</a></li>
   <li><a href="#native_methods">Use Native Methods Judiciously</a></li>
   <li><a href="#closing_notes">Closing Notes</a></li>
 </ol>
diff --git a/docs/html/training/articles/security-ssl.jd b/docs/html/training/articles/security-ssl.jd
index f52865a..0639fb0 100644
--- a/docs/html/training/articles/security-ssl.jd
+++ b/docs/html/training/articles/security-ssl.jd
@@ -1,5 +1,5 @@
 page.title=Security with HTTPS and SSL
-page.tags="network","certificates"
+page.tags=network,certificates
 
 page.article=true
 @jd:body
diff --git a/docs/html/training/articles/smp.jd b/docs/html/training/articles/smp.jd
index 7240eec..0b45987 100644
--- a/docs/html/training/articles/smp.jd
+++ b/docs/html/training/articles/smp.jd
@@ -1,5 +1,5 @@
 page.title=SMP Primer for Android
-page.tags="ndk","native"
+page.tags=ndk,native
 
 page.article=true
 @jd:body
diff --git a/docs/html/training/backward-compatible-ui/index.jd b/docs/html/training/backward-compatible-ui/index.jd
index 4baa55c..c8b6ecc 100644
--- a/docs/html/training/backward-compatible-ui/index.jd
+++ b/docs/html/training/backward-compatible-ui/index.jd
@@ -1,5 +1,5 @@
 page.title=Creating Backward-Compatible UIs
-page.tags="widgets","support"
+page.tags=widgets,support
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/actionbar/index.jd b/docs/html/training/basics/actionbar/index.jd
index f0de758..0303043 100644
--- a/docs/html/training/basics/actionbar/index.jd
+++ b/docs/html/training/basics/actionbar/index.jd
@@ -1,5 +1,5 @@
 page.title=Adding the Action Bar
-page.tags="actionbar"
+page.tags=actionbar
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/data-storage/index.jd b/docs/html/training/basics/data-storage/index.jd
index 4ccad75..fc0c8b5 100644
--- a/docs/html/training/basics/data-storage/index.jd
+++ b/docs/html/training/basics/data-storage/index.jd
@@ -1,5 +1,5 @@
 page.title=Saving Data
-page.tags="data storage","files","sql","database","preferences"
+page.tags=data storage,files,sql,database,preferences
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/fragments/index.jd b/docs/html/training/basics/fragments/index.jd
index 987decf..e78b694 100644
--- a/docs/html/training/basics/fragments/index.jd
+++ b/docs/html/training/basics/fragments/index.jd
@@ -1,5 +1,5 @@
 page.title=Building a Dynamic UI with Fragments
-page.tags="fragments", "user interface", "support library"
+page.tags=fragments,user interface,support library
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/fragments/support-lib.jd b/docs/html/training/basics/fragments/support-lib.jd
index d949267..1d538af 100644
--- a/docs/html/training/basics/fragments/support-lib.jd
+++ b/docs/html/training/basics/fragments/support-lib.jd
@@ -1,5 +1,5 @@
 page.title=Using the Support Library
-page.tags="support library"
+page.tags=support library
 
 trainingnavtop=true
 
diff --git a/docs/html/training/basics/intents/index.jd b/docs/html/training/basics/intents/index.jd
index 59ba11f..aa0232a 100644
--- a/docs/html/training/basics/intents/index.jd
+++ b/docs/html/training/basics/intents/index.jd
@@ -1,5 +1,5 @@
 page.title=Interacting with Other Apps
-page.tags="intents","activity"
+page.tags=intents,activity
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/network-ops/index.jd b/docs/html/training/basics/network-ops/index.jd
index cb3a390..89ab539 100644
--- a/docs/html/training/basics/network-ops/index.jd
+++ b/docs/html/training/basics/network-ops/index.jd
@@ -1,5 +1,5 @@
 page.title=Performing Network Operations
-page.tags="network","wireless"
+page.tags=network,wireless
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/supporting-devices/index.jd b/docs/html/training/basics/supporting-devices/index.jd
index 1e3eb42..6f339f4 100644
--- a/docs/html/training/basics/supporting-devices/index.jd
+++ b/docs/html/training/basics/supporting-devices/index.jd
@@ -1,5 +1,5 @@
 page.title=Supporting Different Devices
-page.tags="resources","screens","versions","localization"
+page.tags=resources,screens,versions,localization
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/supporting-devices/languages.jd b/docs/html/training/basics/supporting-devices/languages.jd
index 130848e..5a1507c 100644
--- a/docs/html/training/basics/supporting-devices/languages.jd
+++ b/docs/html/training/basics/supporting-devices/languages.jd
@@ -1,6 +1,6 @@
 page.title=Supporting Different Languages
 parent.title=Supporting Different Devices
-page.tags="localizing","localization","resources", "formats", "l10n"
+page.tags=localizing,localization,resources,formats,l10n
 parent.link=index.html
 
 trainingnavtop=true
diff --git a/docs/html/training/beam-files/index.jd b/docs/html/training/beam-files/index.jd
index e4bac2e..910fa38 100644
--- a/docs/html/training/beam-files/index.jd
+++ b/docs/html/training/beam-files/index.jd
@@ -1,5 +1,5 @@
 page.title=Sharing Files with NFC
-page.tags="NfcAdapter","Android Beam","share","file transfer"
+page.tags=NfcAdapter,Android Beam,share,file transfer
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/beam-files/send-files.jd b/docs/html/training/beam-files/send-files.jd
index 917b87f..40f706f 100644
--- a/docs/html/training/beam-files/send-files.jd
+++ b/docs/html/training/beam-files/send-files.jd
@@ -139,7 +139,7 @@
 &lt;uses-feature android:name="android.hardware.nfc" android:required="false" /&gt;</pre>
 <p>
     If you set the attribute
-    <code><a href="guide/topics/manifest/uses-feature-element.html#required"
+    <code><a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#required"
     >android:required</a>="false"</code>, you must test for NFC support and Android Beam file
     transfer support in code.
 </p>
diff --git a/docs/html/training/camera/index.jd b/docs/html/training/camera/index.jd
index d6305d6..5560649 100644
--- a/docs/html/training/camera/index.jd
+++ b/docs/html/training/camera/index.jd
@@ -1,5 +1,5 @@
 page.title=Capturing Photos
-page.tags="camera","video","picture"
+page.tags=camera,video,picture
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/cloudsave/conflict-res.jd b/docs/html/training/cloudsave/conflict-res.jd
index 0ff50e2..73e75db 100644
--- a/docs/html/training/cloudsave/conflict-res.jd
+++ b/docs/html/training/cloudsave/conflict-res.jd
@@ -1,5 +1,5 @@
 page.title=Resolving Cloud Save Conflicts
-page.tags="cloud"
+page.tags=cloud
 
 page.article=true
 @jd:body
@@ -594,4 +594,4 @@
 limited. Depending on your implementation, it might make sense to store the
 timestamp for when each entry in the dictionary was modified. When you detect that a
 given entry has not been modified in the last several weeks or months, it is
-probably safe to transfer the coins into another entry and delete the old entry.</p>
\ No newline at end of file
+probably safe to transfer the coins into another entry and delete the old entry.</p>
diff --git a/docs/html/training/cloudsync/index.jd b/docs/html/training/cloudsync/index.jd
index 55b275b..eb7df3d 100644
--- a/docs/html/training/cloudsync/index.jd
+++ b/docs/html/training/cloudsync/index.jd
@@ -1,5 +1,5 @@
 page.title=Syncing to the Cloud
-page.tags="cloud","sync","backup"
+page.tags=cloud,sync,backup
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/connect-devices-wirelessly/index.jd b/docs/html/training/connect-devices-wirelessly/index.jd
index db79abe..3206d7f 100644
--- a/docs/html/training/connect-devices-wirelessly/index.jd
+++ b/docs/html/training/connect-devices-wirelessly/index.jd
@@ -1,5 +1,5 @@
 page.title=Connecting Devices Wirelessly
-page.tags="wifi","network","wireless"
+page.tags=wifi,network,wireless
 
 trainingnavtop=true
 startpage=true
@@ -20,9 +20,15 @@
   <li><a href="{@docRoot}guide/topics/connectivity/wifip2p.html">Wi-Fi P2P</a></li>
 </ul>
 
+</div>
+</div>
 
+<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=oi_ARV_I8Dc">
+<div>
+    <h3>Video</h3>
+    <p>DevBytes: Network Service Discovery</p>
 </div>
-</div>
+</a>
 
 
 <p>Besides enabling communication with the cloud, Android's wireless APIs also
diff --git a/docs/html/training/custom-views/create-view.jd b/docs/html/training/custom-views/create-view.jd
index b849cb3..11be85f 100644
--- a/docs/html/training/custom-views/create-view.jd
+++ b/docs/html/training/custom-views/create-view.jd
@@ -22,7 +22,7 @@
 
         <h2>You should also read</h2>
         <ul>
-            <li><a href="{@docRoot}/guide/topics/ui/custom-components.html">Custom Components</a>
+            <li><a href="{@docRoot}guide/topics/ui/custom-components.html">Custom Components</a>
             </li>
         </ul>
 <h2>Try it out</h2>
diff --git a/docs/html/training/custom-views/index.jd b/docs/html/training/custom-views/index.jd
index 1c09e66..87cd0b0 100644
--- a/docs/html/training/custom-views/index.jd
+++ b/docs/html/training/custom-views/index.jd
@@ -1,5 +1,5 @@
 page.title=Creating Custom Views
-page.tags="widgets","ui","layout"
+page.tags=widgets,ui,layout
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/displaying-bitmaps/index.jd b/docs/html/training/displaying-bitmaps/index.jd
index 1f44fa8..7003585 100644
--- a/docs/html/training/displaying-bitmaps/index.jd
+++ b/docs/html/training/displaying-bitmaps/index.jd
@@ -1,5 +1,5 @@
 page.title=Displaying Bitmaps Efficiently
-page.tags="bitmaps","images","graphics"
+page.tags=bitmaps,images,graphics
 
 trainingnavtop=true
 startpage=true
@@ -25,6 +25,20 @@
 </div>
 </div>
 
+<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=rsQet4nBVi8">
+<div>
+    <h3>Video</h3>
+    <p>DevBytes: Bitmap Allocation</p>
+</div>
+</a>
+
+<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=pMRnGDR6Cu0">
+<div>
+    <h3>Video</h3>
+    <p>DevBytes: Making Apps Beautiful - Part 4 - Performance Tuning</p>
+</div>
+</a>
+
 <p>Learn how to use common techniques to process and load {@link
 android.graphics.Bitmap} objects in a way that keeps your user interface (UI) components responsive
 and avoids exceeding your application memory limit. If you're not careful, bitmaps can quickly
diff --git a/docs/html/training/displaying-bitmaps/manage-memory.jd b/docs/html/training/displaying-bitmaps/manage-memory.jd
index 0e1279e..7f2b4c5 100644
--- a/docs/html/training/displaying-bitmaps/manage-memory.jd
+++ b/docs/html/training/displaying-bitmaps/manage-memory.jd
@@ -160,13 +160,14 @@
 in a {@link java.util.HashSet}, for possible reuse later with
 {@link android.graphics.BitmapFactory.Options#inBitmap}:
 
-<pre>HashSet&lt;SoftReference&lt;Bitmap&gt;&gt; mReusableBitmaps;
+<pre>Set&lt;SoftReference&lt;Bitmap&gt;&gt; mReusableBitmaps;
 private LruCache&lt;String, BitmapDrawable&gt; mMemoryCache;
 
-// If you're running on Honeycomb or newer, create
-// a HashSet of references to reusable bitmaps.
+// If you're running on Honeycomb or newer, create a
+// synchronized HashSet of references to reusable bitmaps.
 if (Utils.hasHoneycomb()) {
-    mReusableBitmaps = new HashSet&lt;SoftReference&lt;Bitmap&gt;&gt;();
+    mReusableBitmaps =
+            Collections.synchronizedSet(new HashSet&lt;SoftReference&lt;Bitmap&gt;&gt;());
 }
 
 mMemoryCache = new LruCache&lt;String, BitmapDrawable&gt;(mCacheParams.memCacheSize) {
@@ -243,25 +244,27 @@
         Bitmap bitmap = null;
 
     if (mReusableBitmaps != null && !mReusableBitmaps.isEmpty()) {
-        final Iterator&lt;SoftReference&lt;Bitmap&gt;&gt; iterator
-                = mReusableBitmaps.iterator();
-        Bitmap item;
+        synchronized (mReusableBitmaps) {
+            final Iterator&lt;SoftReference&lt;Bitmap&gt;&gt; iterator
+                    = mReusableBitmaps.iterator();
+            Bitmap item;
 
-        while (iterator.hasNext()) {
-            item = iterator.next().get();
+            while (iterator.hasNext()) {
+                item = iterator.next().get();
 
-            if (null != item && item.isMutable()) {
-                // Check to see it the item can be used for inBitmap.
-                if (canUseForInBitmap(item, options)) {
-                    bitmap = item;
+                if (null != item && item.isMutable()) {
+                    // Check to see it the item can be used for inBitmap.
+                    if (canUseForInBitmap(item, options)) {
+                        bitmap = item;
 
-                    // Remove from reusable set so it can't be used again.
+                        // Remove from reusable set so it can't be used again.
+                        iterator.remove();
+                        break;
+                    }
+                } else {
+                    // Remove from the set if the reference has been cleared.
                     iterator.remove();
-                    break;
                 }
-            } else {
-                // Remove from the set if the reference has been cleared.
-                iterator.remove();
             }
         }
     }
diff --git a/docs/html/training/efficient-downloads/index.jd b/docs/html/training/efficient-downloads/index.jd
index 2ab93ae..d9d7ef0 100644
--- a/docs/html/training/efficient-downloads/index.jd
+++ b/docs/html/training/efficient-downloads/index.jd
@@ -1,5 +1,5 @@
 page.title=Transferring Data Without Draining the Battery
-page.tags="battery","network","wireless"
+page.tags=battery,network,wireless
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/enterprise/index.jd b/docs/html/training/enterprise/index.jd
index ac1b565..2926f71 100644
--- a/docs/html/training/enterprise/index.jd
+++ b/docs/html/training/enterprise/index.jd
@@ -1,5 +1,5 @@
 page.title=Developing for Enterprise
-page.tags="policy","privacy"
+page.tags=policy,privacy
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/gestures/index.jd b/docs/html/training/gestures/index.jd
index 9d21b08..260cfff 100644
--- a/docs/html/training/gestures/index.jd
+++ b/docs/html/training/gestures/index.jd
@@ -1,5 +1,5 @@
 page.title=Using Touch Gestures
-page.tags="input","navigation","gesturedetector","scroller"
+page.tags=input,navigation,gesturedetector,scroller
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/gestures/scroll.jd b/docs/html/training/gestures/scroll.jd
index 09fcc4e..4b82d69 100644
--- a/docs/html/training/gestures/scroll.jd
+++ b/docs/html/training/gestures/scroll.jd
@@ -95,7 +95,7 @@
 finger across the touch screen. Simple dragging is often implemented by overriding 
 {@link android.view.GestureDetector.OnGestureListener#onScroll onScroll()} in 
 {@link android.view.GestureDetector.OnGestureListener}. For more discussion of dragging, see 
-<a href="dragging.html">Dragging and Scaling</a>.</li>
+<a href="scale.html">Dragging and Scaling</a>.</li>
 
     <li><strong>Flinging</strong> is the type of scrolling that occurs when a user 
 drags and lifts her finger quickly. After the user lifts her finger, you generally 
diff --git a/docs/html/training/graphics/opengl/draw.jd b/docs/html/training/graphics/opengl/draw.jd
index 156ff70..ba00627 100644
--- a/docs/html/training/graphics/opengl/draw.jd
+++ b/docs/html/training/graphics/opengl/draw.jd
@@ -122,7 +122,7 @@
 get created once and then cached for later use.</p>
 
 <pre>
-public Triangle() {
+public class Triangle() {
     ...
 
     int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
diff --git a/docs/html/training/graphics/opengl/environment.jd b/docs/html/training/graphics/opengl/environment.jd
index e1e2c8a..77faabf 100644
--- a/docs/html/training/graphics/opengl/environment.jd
+++ b/docs/html/training/graphics/opengl/environment.jd
@@ -92,7 +92,7 @@
 {@link android.opengl.GLSurfaceView} as its primary view:</p>
 
 <pre>
-public class OpenGLES20 extends Activity {
+public class OpenGLES20Activity extends Activity {
 
     private GLSurfaceView mGLView;
 
@@ -190,11 +190,11 @@
 gray background in the {@link android.opengl.GLSurfaceView}:</p>
 
 <pre>
-public class MyGL20Renderer implements GLSurfaceView.Renderer {
+public class MyGLRenderer implements GLSurfaceView.Renderer {
 
     public void onSurfaceCreated(GL10 unused, EGLConfig config) {
         // Set the background frame color
-        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
     }
 
     public void onDrawFrame(GL10 unused) {
diff --git a/docs/html/training/graphics/opengl/index.jd b/docs/html/training/graphics/opengl/index.jd
index cf33d80..3549f95 100644
--- a/docs/html/training/graphics/opengl/index.jd
+++ b/docs/html/training/graphics/opengl/index.jd
@@ -1,5 +1,5 @@
 page.title=Displaying Graphics with OpenGL ES
-page=tags="open gl","graphics"
+page.tags=open gl,graphics
 trainingnavtop=true
 
 @jd:body
diff --git a/docs/html/training/graphics/opengl/motion.jd b/docs/html/training/graphics/opengl/motion.jd
index af70de0..fbcdd7f 100644
--- a/docs/html/training/graphics/opengl/motion.jd
+++ b/docs/html/training/graphics/opengl/motion.jd
@@ -53,16 +53,20 @@
 private float[] mRotationMatrix = new float[16];
 public void onDrawFrame(GL10 gl) {
     ...
+    float[] scratch = new float[16];
+
     // Create a rotation transformation for the triangle
     long time = SystemClock.uptimeMillis() % 4000L;
     float angle = 0.090f * ((int) time);
     Matrix.setRotateM(mRotationMatrix, 0, angle, 0, 0, -1.0f);
 
     // Combine the rotation matrix with the projection and camera view
-    Matrix.multiplyMM(mMVPMatrix, 0, mRotationMatrix, 0, mMVPMatrix, 0);
+    // Note that the mMVPMatrix factor *must be first* in order
+    // for the matrix multiplication product to be correct.
+    Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);
 
     // Draw triangle
-    mTriangle.draw(mMVPMatrix);
+    mTriangle.draw(scratch);
 }
 </pre>
 
@@ -82,8 +86,9 @@
 <pre>
 public MyGLSurfaceView(Context context) {
     ...
-    // Render the view only when there is a change in the drawing data
-    //setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); // comment out for auto-rotation
+    // Render the view only when there is a change in the drawing data.
+    // To allow the triangle to rotate automatically, this line is commented out:
+    <strong>//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);</strong>
 }
 </pre>
 
diff --git a/docs/html/training/graphics/opengl/projection.jd b/docs/html/training/graphics/opengl/projection.jd
index 2a91093..b09e74c 100644
--- a/docs/html/training/graphics/opengl/projection.jd
+++ b/docs/html/training/graphics/opengl/projection.jd
@@ -79,12 +79,12 @@
 
     // this projection matrix is applied to object coordinates
     // in the onDrawFrame() method
-    Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
+    Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
 }
 </pre>
 
-<p>This code populates a projection matrix, {@code mProjMatrix} which you can then combine with a
-camera view transformation in the {@link android.opengl.GLSurfaceView.Renderer#onDrawFrame
+<p>This code populates a projection matrix, {@code mProjectionMatrix} which you can then combine
+with a camera view transformation in the {@link android.opengl.GLSurfaceView.Renderer#onDrawFrame
 onDrawFrame()} method, which is shown in the next section.</p>
 
 <p class="note"><strong>Note:</strong> Just applying a projection transformation to your
@@ -104,12 +104,11 @@
 &#64;Override
 public void onDrawFrame(GL10 unused) {
     ...
-
     // Set the camera position (View matrix)
-    Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
 
     // Calculate the projection and view transformation
-    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
+    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
 
     // Draw shape
     mTriangle.draw(mMVPMatrix);
@@ -130,7 +129,7 @@
     // get handle to shape's transformation matrix
     mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
 
-    // Apply the projection and view transformation
+    // Pass the projection and view transformation to the shader
     GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
 
     // Draw the triangle
@@ -139,7 +138,7 @@
 }
 </pre>
 
-<p>Once you have correctly calulated and applied the projection and camera view transformations,
+<p>Once you have correctly calculated and applied the projection and camera view transformations,
 your graphic objects are drawn in correct proportions and should look like this:</p>
 
 
diff --git a/docs/html/training/graphics/opengl/shapes.jd b/docs/html/training/graphics/opengl/shapes.jd
index 98381cc..b960bb7 100644
--- a/docs/html/training/graphics/opengl/shapes.jd
+++ b/docs/html/training/graphics/opengl/shapes.jd
@@ -50,16 +50,16 @@
 OpenGL ES graphics pipeline for processing.</p>
 
 <pre>
-class Triangle {
+public class Triangle {
 
     private FloatBuffer vertexBuffer;
 
     // number of coordinates per vertex in this array
     static final int COORDS_PER_VERTEX = 3;
-    static float triangleCoords[] = { // in counterclockwise order:
-         0.0f,  0.622008459f, 0.0f,   // top
-        -0.5f, -0.311004243f, 0.0f,   // bottom left
-         0.5f, -0.311004243f, 0.0f    // bottom right
+    static float triangleCoords[] = {   // in counterclockwise order:
+             0.0f,  0.622008459f, 0.0f, // top
+            -0.5f, -0.311004243f, 0.0f, // bottom left
+             0.5f, -0.311004243f, 0.0f  // bottom right
     };
 
     // Set color with red, green, blue and alpha (opacity) values
@@ -112,17 +112,18 @@
 OpenGL ES graphics pipeline how to draw these vertices. Here’s the code for this shape:</p>
 
 <pre>
-class Square {
+public class Square {
 
     private FloatBuffer vertexBuffer;
     private ShortBuffer drawListBuffer;
 
     // number of coordinates per vertex in this array
     static final int COORDS_PER_VERTEX = 3;
-    static float squareCoords[] = { -0.5f,  0.5f, 0.0f,   // top left
-                                    -0.5f, -0.5f, 0.0f,   // bottom left
-                                     0.5f, -0.5f, 0.0f,   // bottom right
-                                     0.5f,  0.5f, 0.0f }; // top right
+    static float squareCoords[] = {
+            -0.5f,  0.5f, 0.0f,   // top left
+            -0.5f, -0.5f, 0.0f,   // bottom left
+             0.5f, -0.5f, 0.0f,   // bottom right
+             0.5f,  0.5f, 0.0f }; // top right
 
     private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
 
diff --git a/docs/html/training/graphics/opengl/touch.jd b/docs/html/training/graphics/opengl/touch.jd
index c058a59..4c9f0c7 100644
--- a/docs/html/training/graphics/opengl/touch.jd
+++ b/docs/html/training/graphics/opengl/touch.jd
@@ -75,7 +75,9 @@
               dy = dy * -1 ;
             }
 
-            mRenderer.mAngle += (dx + dy) * TOUCH_SCALE_FACTOR;  // = 180.0f / 320
+            mRenderer.setAngle(
+                    mRenderer.getAngle() +
+                    ((dx + dy) * TOUCH_SCALE_FACTOR);  // = 180.0f / 320
             requestRender();
     }
 
@@ -123,16 +125,20 @@
 <pre>
 public void onDrawFrame(GL10 gl) {
     ...
+    float[] scratch = new float[16];
+
     // Create a rotation for the triangle
     // long time = SystemClock.uptimeMillis() % 4000L;
     // float angle = 0.090f * ((int) time);
     <strong>Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);</strong>
 
     // Combine the rotation matrix with the projection and camera view
-    Matrix.multiplyMM(mMVPMatrix, 0, mRotationMatrix, 0, mMVPMatrix, 0);
+    // Note that the mMVPMatrix factor *must be first* in order
+    // for the matrix multiplication product to be correct.
+    Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);
 
     // Draw triangle
-    mTriangle.draw(mMVPMatrix);
+    mTriangle.draw(scratch);
 }
 </pre>
 
diff --git a/docs/html/training/id-auth/index.jd b/docs/html/training/id-auth/index.jd
index 2bae9c4..f15ee29 100644
--- a/docs/html/training/id-auth/index.jd
+++ b/docs/html/training/id-auth/index.jd
@@ -1,5 +1,5 @@
 page.title=Remembering Users
-page.tags="privacy","oauth","accounts"
+page.tags=privacy,oauth,accounts
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/implementing-navigation/ancestral.jd b/docs/html/training/implementing-navigation/ancestral.jd
index 12d5005..57251c1 100644
--- a/docs/html/training/implementing-navigation/ancestral.jd
+++ b/docs/html/training/implementing-navigation/ancestral.jd
@@ -1,5 +1,5 @@
 page.title=Providing Up Navigation
-page.tags="up navigation","NavUtils","TaskStackBuilder"
+page.tags=up navigation,NavUtils,TaskStackBuilder
 
 trainingnavtop=true
 
diff --git a/docs/html/training/implementing-navigation/lateral.jd b/docs/html/training/implementing-navigation/lateral.jd
index bb9d78c..9c83479 100644
--- a/docs/html/training/implementing-navigation/lateral.jd
+++ b/docs/html/training/implementing-navigation/lateral.jd
@@ -1,5 +1,5 @@
 page.title=Creating Swipe Views with Tabs
-page.tags="viewpager","horizontal","paging","swipe view","tabs"
+page.tags=viewpager,horizontal,paging,swipe view,tabs
 
 trainingnavtop=true
 
diff --git a/docs/html/training/implementing-navigation/nav-drawer.jd b/docs/html/training/implementing-navigation/nav-drawer.jd
index 9a94810..b9c4873 100644
--- a/docs/html/training/implementing-navigation/nav-drawer.jd
+++ b/docs/html/training/implementing-navigation/nav-drawer.jd
@@ -1,5 +1,5 @@
 page.title=Creating a Navigation Drawer
-page.tags="DrawerLayout", "navigation"
+page.tags=DrawerLayout,navigation
 
 trainingnavtop=true
 
diff --git a/docs/html/training/implementing-navigation/temporal.jd b/docs/html/training/implementing-navigation/temporal.jd
index 3abab53..e736648 100644
--- a/docs/html/training/implementing-navigation/temporal.jd
+++ b/docs/html/training/implementing-navigation/temporal.jd
@@ -1,5 +1,5 @@
 page.title=Providing Proper Back Navigation
-page.tags="back navigation","NavUtils","TaskStackBuilder"
+page.tags=back navigation,NavUtils,TaskStackBuilder
 
 trainingnavtop=true
 
diff --git a/docs/html/training/improving-layouts/index.jd b/docs/html/training/improving-layouts/index.jd
index af29d3f..a2ab7a1 100644
--- a/docs/html/training/improving-layouts/index.jd
+++ b/docs/html/training/improving-layouts/index.jd
@@ -1,5 +1,5 @@
 page.title=Improving Layout Performance
-page.tags="include","merge","viewstub","listview"
+page.tags=include,merge,viewstub,listview
 
 trainingnavtop=true
 startpage=true
@@ -26,6 +26,13 @@
 </div>
 </div>
 
+<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=-FUw8HMbmBQ">
+<div>
+    <h3>Video</h3>
+    <p>DevBytes: Optimising Layouts with Hierarchy Viewer</p>
+</div>
+</a>
+
 
 
 <p>Layouts are a key part of Android applications that directly affect the user experience. If
@@ -56,4 +63,4 @@
     <dd>If you've built an instance of {@link android.widget.ListView} that contains complex or
 data-heavy content in each list item, the scroll performance of the list might suffer. This
 lesson provides some tips about how you can make your scrolling performance more smooth.</dd>
-</dl>
\ No newline at end of file
+</dl>
diff --git a/docs/html/training/in-app-billing/index.jd b/docs/html/training/in-app-billing/index.jd
index 94708b8..4a446f3 100644
--- a/docs/html/training/in-app-billing/index.jd
+++ b/docs/html/training/in-app-billing/index.jd
@@ -1,5 +1,5 @@
 page.title=Selling In-app Products
-page.tags="billing"
+page.tags=billing
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/keyboard-input/index.jd b/docs/html/training/keyboard-input/index.jd
index 7ac79e6..46795c4 100644
--- a/docs/html/training/keyboard-input/index.jd
+++ b/docs/html/training/keyboard-input/index.jd
@@ -1,5 +1,5 @@
 page.title=Handling Keyboard Input
-page.tags="edittext","accessibility"
+page.tags=edittext,accessibility
 
 trainingnavtop=true
 startpage=true
@@ -52,4 +52,4 @@
     <dd>Learn how to respond directly to keyboard input for user actions.
     </dd>
  
-</dl> 
\ No newline at end of file
+</dl> 
diff --git a/docs/html/training/load-data-background/index.jd b/docs/html/training/load-data-background/index.jd
index 29108e8..e991003 100644
--- a/docs/html/training/load-data-background/index.jd
+++ b/docs/html/training/load-data-background/index.jd
@@ -1,5 +1,5 @@
 page.title=Loading Data in the Background
-page.tags="cursorloader"
+page.tags=cursorloader
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/location/index.jd b/docs/html/training/location/index.jd
index e03eac6..249c42d 100644
--- a/docs/html/training/location/index.jd
+++ b/docs/html/training/location/index.jd
@@ -1,5 +1,5 @@
 page.title=Making Your App Location-Aware
-page.tags="location","geofence", "geofencing", "activity recognition", "activity detection", "gps"
+page.tags=location,geofence,geofencing,activity recognition,activity detection,gps
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/location/location-testing.jd b/docs/html/training/location/location-testing.jd
index e36bac1..5021fc0 100644
--- a/docs/html/training/location/location-testing.jd
+++ b/docs/html/training/location/location-testing.jd
@@ -11,7 +11,7 @@
 <ol>
     <li><a href="#TurnOnMockMode">Turn On Mock Mode</a></li>
     <li><a href="#SendMockLocations">Send Mock Locations</a></li>
-    <li><a href="RunProvider">Run the Mock Location Provider App</a></li>
+    <li><a href="#RunProvider">Run the Mock Location Provider App</a></li>
     <li><a href="#TestingTips">Testing Tips</a>
 </ol>
 
@@ -62,7 +62,7 @@
     The best way to use mock locations is to send them from a separate mock location provider app.
     This lesson includes a provider app that you can download and use to test your own software.
     Modify the provider app as necessary to suit your own needs. Some ideas for providing test data
-    to the app are listed in the section <a href="TestData">Managing test data</a>.
+    to the app are listed in the section <a href="#TestData">Managing test data</a>.
 </p>
 <p>
     The remainder of this lesson shows you how to turn on mock mode and use a location client to
diff --git a/docs/html/training/managing-audio/index.jd b/docs/html/training/managing-audio/index.jd
index 3e3bcf0..9391449 100644
--- a/docs/html/training/managing-audio/index.jd
+++ b/docs/html/training/managing-audio/index.jd
@@ -1,5 +1,5 @@
 page.title=Managing Audio Playback
-page.tags="audio","media"
+page.tags=audio,media
 
 trainingnavtop=true
 startpage=true
@@ -58,4 +58,4 @@
   <dt><b><a href="audio-output.html">Dealing with Audio Output Hardware</a></b></dt>
   <dd>Audio can be played from a number of sources. Learn how to find out where the audio is being
 played and how to handle a headset being disconnected during playback.</dd> 
- </dl> 
\ No newline at end of file
+ </dl> 
diff --git a/docs/html/training/monitoring-device-state/index.jd b/docs/html/training/monitoring-device-state/index.jd
index c3d700a..949c1da 100644
--- a/docs/html/training/monitoring-device-state/index.jd
+++ b/docs/html/training/monitoring-device-state/index.jd
@@ -1,5 +1,5 @@
 page.title=Optimizing Battery Life
-page.tags="network","internet"
+page.tags=network,internet
 
 trainingnavtop=true
 startpage=true
@@ -59,4 +59,4 @@
 those that aren't necessary due to the current device state. Learn to improve
 efficiency by toggling and cascading state change receivers and delay actions until the device is in
 a specific state.</dd>
-</dl> 
\ No newline at end of file
+</dl> 
diff --git a/docs/html/training/multiple-apks/index.jd b/docs/html/training/multiple-apks/index.jd
index 5754da9..40a26b9 100644
--- a/docs/html/training/multiple-apks/index.jd
+++ b/docs/html/training/multiple-apks/index.jd
@@ -1,5 +1,5 @@
 page.title=Maintaining Multiple APKs
-page.tags="support"
+page.tags=support
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/multiple-threads/index.jd b/docs/html/training/multiple-threads/index.jd
index cbd42b4..136f0af 100644
--- a/docs/html/training/multiple-threads/index.jd
+++ b/docs/html/training/multiple-threads/index.jd
@@ -1,5 +1,5 @@
 page.title=Sending Operations to Multiple Threads
-page.tags="threadpool","runnable"
+page.tags=threadpool,runnable
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/multiscreen/index.jd b/docs/html/training/multiscreen/index.jd
index 2d34b28..45b6161 100644
--- a/docs/html/training/multiscreen/index.jd
+++ b/docs/html/training/multiscreen/index.jd
@@ -1,5 +1,5 @@
 page.title=Designing for Multiple Screens
-page.tags="tablet","tv","fragments","support"
+page.tags=tablet,tv,fragments,support
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/notepad/index.jd b/docs/html/training/notepad/index.jd
index 64ba144..d1aa221 100644
--- a/docs/html/training/notepad/index.jd
+++ b/docs/html/training/notepad/index.jd
@@ -1,3 +1,4 @@
+excludeFromSuggestions=true
 page.title=Notepad Tutorial
 parent.title=Tutorials
 @jd:body
diff --git a/docs/html/training/notepad/notepad-ex1.jd b/docs/html/training/notepad/notepad-ex1.jd
index 0decbb2..f680f15 100644
--- a/docs/html/training/notepad/notepad-ex1.jd
+++ b/docs/html/training/notepad/notepad-ex1.jd
@@ -1,3 +1,4 @@
+excludeFromSuggestions=true
 page.title=Notepad Exercise 1
 parent.title=Notepad Tutorial
 parent.link=index.html
diff --git a/docs/html/training/notepad/notepad-ex2.jd b/docs/html/training/notepad/notepad-ex2.jd
index 895a071..d15499b3 100644
--- a/docs/html/training/notepad/notepad-ex2.jd
+++ b/docs/html/training/notepad/notepad-ex2.jd
@@ -1,4 +1,5 @@
-Rpage.title=Notepad Exercise 2
+excludeFromSuggestions=true
+page.title=Notepad Exercise 2
 parent.title=Notepad Tutorial
 parent.link=index.html
 @jd:body
diff --git a/docs/html/training/notepad/notepad-ex3.jd b/docs/html/training/notepad/notepad-ex3.jd
index e31ecda..648f9f2 100644
--- a/docs/html/training/notepad/notepad-ex3.jd
+++ b/docs/html/training/notepad/notepad-ex3.jd
@@ -1,3 +1,4 @@
+excludeFromSuggestions=true
 page.title=Notepad Exercise 3
 parent.title=Notepad Tutorial
 parent.link=index.html
diff --git a/docs/html/training/notepad/notepad-extra-credit.jd b/docs/html/training/notepad/notepad-extra-credit.jd
index d5fd771..8ab2021 100644
--- a/docs/html/training/notepad/notepad-extra-credit.jd
+++ b/docs/html/training/notepad/notepad-extra-credit.jd
@@ -1,3 +1,4 @@
+excludeFromSuggestions=true
 page.title=Notepad Extra Credit
 parent.title=Notepad Tutorial
 parent.link=index.html
diff --git a/docs/html/training/notepad/notepad-index.jd b/docs/html/training/notepad/notepad-index.jd
index 151c50d..fde43fa 100644
--- a/docs/html/training/notepad/notepad-index.jd
+++ b/docs/html/training/notepad/notepad-index.jd
@@ -1,3 +1,4 @@
+excludeFromSuggestions=true
 page.title=Notepad Tutorial
 @jd:body
 
diff --git a/docs/html/training/notify-user/index.jd b/docs/html/training/notify-user/index.jd
index 51f058f..f7d0f87 100644
--- a/docs/html/training/notify-user/index.jd
+++ b/docs/html/training/notify-user/index.jd
@@ -1,5 +1,5 @@
 page.title=Notifying the User
-page.tags="notifications"
+page.tags=notifications
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/printing/index.jd b/docs/html/training/printing/index.jd
index 7b67b74..e33e5e8 100644
--- a/docs/html/training/printing/index.jd
+++ b/docs/html/training/printing/index.jd
@@ -1,5 +1,5 @@
 page.title=Printing Content
-page.tags="print","navigation","gesturedetector","scroller"
+page.tags=print,navigation,gesturedetector,scroller
 
 trainingnavtop=true
 startpage=true
@@ -17,6 +17,13 @@
   </div>
 </div>
 
+<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=Iub67ic87KI">
+<div>
+    <h3>Video</h3>
+    <p>DevBytes: Android 4.4 Printing API</p>
+</div>
+</a>
+
 <p>
   Android users frequently view content solely on their devices, but there are times when
   showing someone a screen is not an adequate way to share information. Being able to print
diff --git a/docs/html/training/run-background-service/index.jd b/docs/html/training/run-background-service/index.jd
index 3360df5..22f3fc8 100644
--- a/docs/html/training/run-background-service/index.jd
+++ b/docs/html/training/run-background-service/index.jd
@@ -1,5 +1,5 @@
 page.title=Running in a Background Service
-page.tags="intentservice"
+page.tags=intentservice
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/scheduling/index.jd b/docs/html/training/scheduling/index.jd
index 9ffbc16..4d2db60 100644
--- a/docs/html/training/scheduling/index.jd
+++ b/docs/html/training/scheduling/index.jd
@@ -1,5 +1,5 @@
 page.title=Managing Device Awake State
-page.tags=""
+page.tags=
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/search/index.jd b/docs/html/training/search/index.jd
index 4070372..612e8e8 100644
--- a/docs/html/training/search/index.jd
+++ b/docs/html/training/search/index.jd
@@ -1,5 +1,5 @@
 page.title=Adding Search Functionality
-page.tags="searchview","database"
+page.tags=searchview,database
 
 trainingnavtop=true
 startpage=true
@@ -50,4 +50,4 @@
     <dt><b><a href="backward-compat.html">Remaining Backward Compatible</a></b></dt>
 
     <dd>Learn how to keep search features backward compatible with older devices by using.</dd>
-  </dl>
\ No newline at end of file
+  </dl>
diff --git a/docs/html/training/secure-file-sharing/index.jd b/docs/html/training/secure-file-sharing/index.jd
index aa009fc..4adc1c0 100644
--- a/docs/html/training/secure-file-sharing/index.jd
+++ b/docs/html/training/secure-file-sharing/index.jd
@@ -1,5 +1,5 @@
 page.title=Sharing Files
-page.tags="FileProvider","share","ContentProvider"
+page.tags=FileProvider,share,ContentProvider
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/sharing/index.jd b/docs/html/training/sharing/index.jd
index 06d42fc..58a69fc 100644
--- a/docs/html/training/sharing/index.jd
+++ b/docs/html/training/sharing/index.jd
@@ -1,5 +1,5 @@
 page.title=Sharing Simple Data
-page.tags="intents","share"
+page.tags=intents,share
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/system-ui/dim.jd b/docs/html/training/system-ui/dim.jd
index 7c365d7..f28c948 100644
--- a/docs/html/training/system-ui/dim.jd
+++ b/docs/html/training/system-ui/dim.jd
@@ -29,6 +29,14 @@
     </li>
 </ul>
 
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}samples/ImmersiveMode/index.html"
+class="button">Get the sample</a>
+ <p class="filename">ImmersiveMode sample</p>
+</div>
+
 
 </div>
 </div>
diff --git a/docs/html/training/system-ui/immersive.jd b/docs/html/training/system-ui/immersive.jd
new file mode 100644
index 0000000..0a1516c
--- /dev/null
+++ b/docs/html/training/system-ui/immersive.jd
@@ -0,0 +1,273 @@
+page.title=Using Immersive Full-Screen Mode
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#compare">Choose an Approach</a></li>
+  <li><a href="#nonsticky">Use Non-Sticky Immersion</a></li>
+  <li><a href="#sticky">Use Sticky Immersion</a></li>
+</ol>
+
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+
+<ul>
+    <li>
+        <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> API Guide
+    </li>
+    <li>
+        <a href="{@docRoot}design/patterns/fullscreen.html">
+        Android Design Guide
+        </a>
+    </li>
+</ul>
+
+
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}samples/ImmersiveMode/index.html"
+class="button">Get the sample</a>
+ <p class="filename">ImmersiveMode sample</p>
+</div>
+
+</div>
+</div>
+
+<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=cBi8fjv90E4">
+<div>
+    <h3>Video</h3>
+    <p>DevBytes: Android 4.4 Immersive Mode</p>
+</div>
+</a>
+
+<p>Android 4.4 (API Level 19) introduces a new
+{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE} flag for
+{@link android.view.View#setSystemUiVisibility setSystemUiVisibility()} that lets your app
+go truly "full screen." This flag, when combined with the
+{@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} and
+{@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} flags, hides the navigation and status
+bars and lets your app capture all touch events on the screen.</p>
+
+<p>When immersive full-screen mode is
+enabled, your activity continues to receive all touch events. The user can reveal the
+system bars with an inward swipe along the region where the system bars normally appear.
+This clears the {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} flag
+(and the {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} flag, if applied) so the
+system bars become visible. This also triggers your
+{@link android.view.View.OnSystemUiVisibilityChangeListener},
+if set. However, if you'd like the system bars to automatically hide
+again after a few moments, you can instead use the
+{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY} flag. Note that the
+"sticky" version of the flag doesn't trigger any listeners, as system bars temporarily
+shown in this mode are in a transient state.
+</p>
+
+<p>Figure 1 illustrates the different "immersive mode" states:</p>
+
+ <img src="{@docRoot}images/training/imm-states.png"
+  alt="system bars">
+<p class="img-caption"><strong>Figure 1.</strong> Immersive mode states.</p>
+
+<p>In figure 1:</p>
+<ol>
+<li><strong>Non-immersive mode</strong>&mdash;This is how the app
+appears before it enters immersive mode. It is also how the app appears if you use the
+{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} flag, and the user swipes to
+display the system bars, thereby clearing the {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} and
+{@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} flags. Once these flags are cleared, the system
+bars reappear and remain visible.</li>
+
+<p>Note that it's best practice to
+ keep all UI controls in sync with the system bars, to minimize the
+ number of states your screen can be in. This provides a more seamless user experience. So
+ here all UI controls are displayed along with the status bars. Once the app enters
+ immersive mode, the UI controls are hidden along with the system bars.
+ To ensure that your UI visibility stays in sync with system bar visibility, make sure to
+ provide an appropriate {@link android.view.View.OnSystemUiVisibilityChangeListener}
+ to watch for changes, as described in
+ <a href="visibility.html">Responding to UI Visibility Changes</a>.</p></li>
+
+<li><strong>Reminder bubble</strong>&mdash;The system displays a reminder bubble
+the first time users enter
+immersive mode in your app. The reminder bubble reminds users how to display
+the system bars.
+<p class="note"><strong>Note:</strong> If you want to force the reminder bubble to appear
+for testing purposes, you can do so by putting the app in immersive mode, turning off the
+screen with the power button, and then turning the screen back on again within 5 seconds.
+</p></li>
+
+<li><strong>Immersive mode</strong>&mdash;This is the app in immersive mode, with the
+system bars and other UI controls hidden. You can achieve this state with either
+{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} or
+ {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY}. </li>
+
+<li><strong>Sticky flag</strong>&mdash;This is the UI you see if you use the
+{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY} flag,
+and the user swipes to display the system bars. Semi-transparent bars temporarily appear and then
+hide again. The act of swiping doesn't clear any flags, nor does it trigger your
+system UI visibility change listeners, because the transient appearance of the system bars isn't
+considered a UI visibility change.</li>
+</ol>
+
+<p class="note"><strong>Note:</strong> Remember that the "immersive" flags only take effect
+if you use them in conjunction with {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION},
+{@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN}, or
+ both. You can just use one or the other, but it's common to hide both the status and the
+ navigation bar when you're implementing "full immersion" mode.</p>
+
+ <h2 id="compare">Choose an Approach</h2>
+
+ <p>The flags  {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE} and
+ {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY} both provide an immersive
+ experience, but with the differences in behavior described above. Here are
+ examples of when you would use one flag vs. the other:</p>
+
+<ul>
+<li>If you're building a book reader, news reader, or a magazine, use
+the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} flag in conjunction
+with {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} and
+{@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION}. Because users may want to access
+the action bar and other UI controls somewhat frequently, but not be bothered with any UI
+elements while flipping through content,
+{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} is a good option for this
+use case.</li>
+
+<li>If you're building a truly immersive app, where you expect users to interact near
+the edges of the screen and you don't expect them to need frequent access to the system
+UI, use the
+{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY} flag
+in conjunction with {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} and
+{@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION}. For example, this approach
+might be suitable for a game or a drawing app.</li>
+
+<li>If you're building a video player or some other app that requires minimal user
+interaction, you can probably get by with the <a href="{@docRoot}design/patterns/fullscreen.html">
+lean back</a> approach, available since
+Android 4.0 (API Level 14). For this type of app, simply using
+{@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN}
+ and {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} should be
+sufficient. Don't use the "immersive" flags in this case.</li>
+</ul>
+
+<h2 id="nonsticky">Use Non-Sticky Immersion</h2>
+
+ <p>When you use the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE} flag, it hides
+ the system bars based on what other UI flags you have set
+ ({@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION},
+ {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN}, or
+ both). When the user swipes inward in a system bars region, the
+system bars reappear and remain visible.</p>
+
+<p>It's good practice to include other system UI flags (such as
+{@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} and
+{@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_STABLE}) to keep the content from resizing
+when the system bars hide and show. You should also make sure that the action bar and other
+UI controls are hidden at the same time. This snippet demonstrates how to hide and show the
+status and navigation bars, without resizing the content:</p>
+
+<pre>
+// This snippet hides the system bars.
+private void hideSystemUI() {
+    // Set the IMMERSIVE flag.
+    // Set the content to appear under the system bars so that the content
+    // doesn't resize when the system bars hide and show.
+    mDecorView.setSystemUiVisibility(
+            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
+            | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
+            | View.SYSTEM_UI_FLAG_IMMERSIVE);
+}
+
+// This snippet shows the system bars. It does this by removing all the flags
+// except for the ones that make the content appear under the system bars.
+private void showSystemUI() {
+    mDecorView.setSystemUiVisibility(
+            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
+}
+</pre>
+
+
+<p>You may also want to implement the following in conjunction with the
+{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} flag to provide a better user
+experience:</p>
+
+<ul>
+<li>Register a listener so that your app can get notified of system UI visibility changes,
+as described in <a href="visibility.html">Responding to UI Visibility Changes</a>.</li>
+
+<li>Implement {@link android.app.Activity#onWindowFocusChanged onWindowFocusChanged()}.
+If you gain window focus, you may want to re-hide the system bars.
+If you lose window focus, for example due to a dialog or pop up menu showing above your app,
+you'll probably want to cancel any pending "hide" operations you previously scheduled
+with {@link android.os.Handler#postDelayed Handler.postDelayed()} or something similar.</li>
+
+<li>Implement a {@link android.view.GestureDetector} that detects
+{@link android.view.GestureDetector.OnGestureListener#onSingleTapUp}, to allow users to
+manually toggle the visibility of the system bars by touching your content.
+Simple click listeners aren't the best solution for this because they get triggered even
+if the user drags a finger across the screen (assuming the click target takes up the whole
+screen).
+</li>
+
+</ul>
+
+<p>
+For more discussion of these topics, watch the video
+<a class ="external-link" href="http://www.youtube.com/embed/cBi8fjv90E4">DevBytes:
+ Android 4.4 Immersive Mode</a>.</p>
+
+<h2 id="sticky">Use Sticky Immersion</h2>
+
+<p>When you use the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY} flag,
+an inward swipe in the system bars areas causes the bars to temporarily appear in a
+semi-transparent state, but no flags are cleared, and your
+system UI visibility change listeners are not triggered. The bars
+automatically hide again after a short delay, or if the user interacts with the middle of the
+screen.</p>
+
+<p>Figure 2 shows the semi-transparent system bars that briefly appear and then hide again
+when you use the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY} flag.</p>
+
+ <img src="{@docRoot}images/training/imm-sticky.png"
+  alt="system bars">
+<p class="img-caption"><strong>Figure 2.</strong> Auto-hiding system bars.</p>
+
+<p>Below is a simple approach to using this flag. Any time the window receives focus, simply
+set the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY} flag, along
+with the other flags discussed in <a href="#nonsticky">Use IMMERSIVE</a>. For example:</p>
+
+<pre>
+&#64;Override
+public void onWindowFocusChanged(boolean hasFocus) {
+        super.onWindowFocusChanged(hasFocus);
+    if (hasFocus) {
+        decorView.setSystemUiVisibility(
+                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+                | View.SYSTEM_UI_FLAG_FULLSCREEN
+                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);}
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> If you like the auto-hiding behavior of
+{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY}
+but need to show your own UI controls as well, just use
+{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} combined with
+{@link android.os.Handler#postDelayed Handler.postDelayed()} or something similar to
+re-enter immersive mode after a few seconds.</p>
diff --git a/docs/html/training/system-ui/index.jd b/docs/html/training/system-ui/index.jd
index 7135a3d..56fa54b 100644
--- a/docs/html/training/system-ui/index.jd
+++ b/docs/html/training/system-ui/index.jd
@@ -1,5 +1,5 @@
 page.title=Managing the System UI
-page.tags=""
+page.tags=
 
 trainingnavtop=true
 startpage=true
@@ -20,7 +20,27 @@
   <li>Android 1.6 (API Level 4) or higher</li>
 </ul>
 
+<h2>You should also read</h2>
 
+<ul>
+    <li>
+        <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> API Guide
+    </li>
+    <li>
+        <a href="{@docRoot}design/patterns/fullscreen.html">
+        Android Design Guide
+        </a>
+    </li>
+
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}samples/ImmersiveMode/index.html"
+class="button">Get the sample</a>
+ <p class="filename">ImmersiveMode sample</p>
+</div>
 
 </div>
 </div>
@@ -32,6 +52,13 @@
 </div>
 </a>
 
+<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=cBi8fjv90E4">
+<div>
+    <h3>Video</h3>
+    <p>DevBytes: Android 4.4 Immersive Mode</p>
+</div>
+</a>
+
 <div class="figure" style="width:278px">
   <img src="{@docRoot}images/training/system-ui.png"
   alt="system bars" />
@@ -78,6 +105,12 @@
     <dd>
         Learn how to hide the navigation bar, in addition to the status bar.
     </dd>
+     <dt>
+        <strong><a href="immersive.html">Using Immersive Full-Screen Mode</a></strong>
+    </dt>
+    <dd>
+        Learn how to create a fully immersive experience in your app.
+    </dd>
 
     <dt>
         <strong><a href="visibility.html">Responding to UI Visibility Changes</a></strong>
@@ -87,4 +120,4 @@
         so that you can adjust your app's UI accordingly.
     </dd>
 
-</dl>
\ No newline at end of file
+</dl>
diff --git a/docs/html/training/system-ui/navigation.jd b/docs/html/training/system-ui/navigation.jd
index 3843da3..3907bb2 100644
--- a/docs/html/training/system-ui/navigation.jd
+++ b/docs/html/training/system-ui/navigation.jd
@@ -10,7 +10,7 @@
 <!-- table of contents -->
 <h2>This lesson teaches you to</h2>
 <ol>
-  <li><a href="#40">Hiding the Navigation Bar on 4.0 and Higher</a></li>
+  <li><a href="#40">Hide the Navigation Bar on 4.0 and Higher</a></li>
   <li><a href="#behind">Make Content Appear Behind the Navigation Bar</a></li>
 </ol>
 
@@ -29,6 +29,13 @@
     </li>
 </ul>
 
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}samples/ImmersiveMode/index.html"
+class="button">Get the sample</a>
+ <p class="filename">ImmersiveMode sample</p>
+</div>
 
 </div>
 </div>
@@ -90,7 +97,7 @@
 <p>On Android 4.1 and higher, you can set your application's content to appear behind
 the navigation bar, so that the content doesn't resize as the navigation bar hides and
 shows. To do this, use
-{@link android.view.View#setSystemUiVisibility setSystemuiVisibility(SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)}.
+{@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION}.
 You may also need to use
 {@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_STABLE} to help your app maintain a
 stable layout.</p>
diff --git a/docs/html/training/system-ui/status.jd b/docs/html/training/system-ui/status.jd
index 25ee253..06b6143 100644
--- a/docs/html/training/system-ui/status.jd
+++ b/docs/html/training/system-ui/status.jd
@@ -12,6 +12,7 @@
 <ol>
   <li><a href="#40">Hide the Status Bar on Android 4.0 and Lower</a></li>
   <li><a href="#41">Hide the Status Bar on Android 4.1 and Higher</a></li>
+  <li><a href="#44">Hide the Status Bar on Android 4.4 and Higher</a></li>
 
   <li><a href="#behind">Make Content Appear Behind the Status Bar</a></li>
   <li><a href="#action-bar">Synchronize the Status Bar with Action Bar Transition</a></li>
@@ -31,6 +32,13 @@
     </li>
 </ul>
 
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}samples/ImmersiveMode/index.html"
+class="button">Get the sample</a>
+ <p class="filename">ImmersiveMode sample</p>
+</div>
 
 </div>
 </div>
@@ -160,15 +168,13 @@
   set with {@link android.view.View#setSystemUiVisibility setSystemUiVisibility()}
   to be cleared.</li>
 </ul>
-
-
  </p>
 
  <h2 id="behind">Make Content Appear Behind the Status Bar</h2>
 <p>On Android 4.1 and higher, you can set your application's content to appear behind
 the status bar, so that the content doesn't resize as the status bar hides and shows.
 To do this, use
-{@link android.view.View#setSystemUiVisibility setSystemuiVisibility(SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)}.
+{@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.
 You may also need to use
 {@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_STABLE} to help your app maintain a
 stable layout.</p>
@@ -209,12 +215,12 @@
 
 
 <p>Then use
-{@link android.view.View#setSystemUiVisibility setSystemuiVisibility(SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)},
+{@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN},
 as described above,
 to set  your activity layout to use the same screen area that's available when you've enabled
 {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN}.
 
-When you want to hide the system UI, call
-{@link android.view.View#setSystemUiVisibility setSystemUiVisibility(SYSTEM_UI_FLAG_FULLSCREEN)}.
+When you want to hide the system UI, use
+{@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN}.
 This also hides the action bar (because {@code windowActionBarOverlay=”true”)} and does
 so with a coordinated animation when both hiding and showing the two.</p>
diff --git a/docs/html/training/system-ui/visibility.jd b/docs/html/training/system-ui/visibility.jd
index c26092c..b562add 100644
--- a/docs/html/training/system-ui/visibility.jd
+++ b/docs/html/training/system-ui/visibility.jd
@@ -28,6 +28,13 @@
     </li>
 </ul>
 
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}samples/ImmersiveMode/index.html"
+class="button">Get the sample</a>
+ <p class="filename">ImmersiveMode sample</p>
+</div>
 
 </div>
 </div>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 547faae..1314c7a 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -990,6 +990,10 @@
             Hiding the Navigation Bar
           </a>
           </li>
+          <li><a href="/training/system-ui/immersive.html">
+            Using Immersive Full-Screen Mode
+          </a>
+          </li>
           <li><a href="<?cs var:toroot ?>training/system-ui/visibility.html">
             Responding to UI Visibility Changes
           </a>
diff --git a/docs/html/training/tv/index.jd b/docs/html/training/tv/index.jd
index 9d15f46..a99e378 100644
--- a/docs/html/training/tv/index.jd
+++ b/docs/html/training/tv/index.jd
@@ -1,5 +1,5 @@
 page.title=Designing for TV
-page.tags="input","screens"
+page.tags=input,screens
 
 trainingnavtop=true
 startpage=true
@@ -17,6 +17,14 @@
 
 </div>
 </div>
+
+<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=zsRnRLh-O34">
+<div>
+    <h3>Video</h3>
+    <p>DevBytes: Design for Large Displays - Part 1</p>
+</div>
+</a>
+
 <p> 
   Smart TVs powered by Android bring your favorite Android apps to the best screen in your house. 
   Thousands of apps in the Google Play Store are already optimized for TVs. This class shows how 
@@ -48,4 +56,4 @@
   <dt><b><a href="unsupported-features-tv.html">Handling features not supported on TV</a></b></dt>
     <dd>Lists the hardware features that are usually not available on TVs. This lesson also shows you how to 
     provide alternatives for missing features or check for missing features and disable code at run time.</dd>
-</dl> 
\ No newline at end of file
+</dl> 
diff --git a/drm/java/android/drm/DrmUtils.java b/drm/java/android/drm/DrmUtils.java
index 4f7cb22..2a86996 100644
--- a/drm/java/android/drm/DrmUtils.java
+++ b/drm/java/android/drm/DrmUtils.java
@@ -19,7 +19,6 @@
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 8c38d25..3c24683 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -995,7 +995,7 @@
     }
 
     /**
-     * Returns true if the bitmap is marked as mutable (i.e. can be drawn into)
+     * Returns true if the bitmap is marked as mutable (i.e.&nbsp;can be drawn into)
      */
     public final boolean isMutable() {
         return mIsMutable;
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index b08ce09..b714fab 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -300,17 +300,22 @@
         public boolean inPreferQualityOverSpeed;
 
         /**
-         * The resulting width of the bitmap, set independent of the state of
-         * inJustDecodeBounds. However, if there is an error trying to decode,
-         * outWidth will be set to -1.
+         * The resulting width of the bitmap. If {@link #inJustDecodeBounds} is
+         * set to false, this will be width of the output bitmap after any
+         * scaling is applied. If true, it will be the width of the input image
+         * without any accounting for scaling.
+         *
+         * <p>outWidth will be set to -1 if there is an error trying to decode.</p>
          */
-
         public int outWidth;
 
         /**
-         * The resulting height of the bitmap, set independent of the state of
-         * inJustDecodeBounds. However, if there is an error trying to decode,
-         * outHeight will be set to -1. 
+         * The resulting height of the bitmap. If {@link #inJustDecodeBounds} is
+         * set to false, this will be height of the output bitmap after any
+         * scaling is applied. If true, it will be the height of the input image
+         * without any accounting for scaling.
+         *
+         * <p>outHeight will be set to -1 if there is an error trying to decode.</p>
          */
         public int outHeight;
 
@@ -469,7 +474,7 @@
      *
      * @param res The resources object containing the image data
      * @param id The resource id of the image data
-     * @return The decoded bitmap, or null if the image could not be decode.
+     * @return The decoded bitmap, or null if the image could not be decoded.
      */
     public static Bitmap decodeResource(Resources res, int id) {
         return decodeResource(res, id, null);
@@ -517,7 +522,7 @@
      * @param offset offset into imageData for where the decoder should begin
      *               parsing.
      * @param length the number of bytes, beginning at offset, to parse
-     * @return The decoded bitmap, or null if the image could not be decode.
+     * @return The decoded bitmap, or null if the image could not be decoded.
      */
     public static Bitmap decodeByteArray(byte[] data, int offset, int length) {
         return decodeByteArray(data, offset, length, null);
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index d46238f..13f4299 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1403,7 +1403,7 @@
             throw new IndexOutOfBoundsException();
         }
         native_drawText(mNativeCanvas, text, index, count, x, y, paint.mBidiFlags,
-                paint.mNativePaint);
+                paint.mNativePaint, paint.mNativeTypeface);
     }
 
     /**
@@ -1417,7 +1417,7 @@
      */
     public void drawText(String text, float x, float y, Paint paint) {
         native_drawText(mNativeCanvas, text, 0, text.length(), x, y, paint.mBidiFlags,
-                paint.mNativePaint);
+                paint.mNativePaint, paint.mNativeTypeface);
     }
 
     /**
@@ -1436,7 +1436,7 @@
             throw new IndexOutOfBoundsException();
         }
         native_drawText(mNativeCanvas, text, start, end, x, y, paint.mBidiFlags,
-                paint.mNativePaint);
+                paint.mNativePaint, paint.mNativeTypeface);
     }
 
     /**
@@ -1456,7 +1456,7 @@
         if (text instanceof String || text instanceof SpannedString ||
             text instanceof SpannableString) {
             native_drawText(mNativeCanvas, text.toString(), start, end, x, y,
-                    paint.mBidiFlags, paint.mNativePaint);
+                    paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
         } else if (text instanceof GraphicsOperations) {
             ((GraphicsOperations) text).drawText(this, start, end, x, y,
                     paint);
@@ -1464,7 +1464,7 @@
             char[] buf = TemporaryBuffer.obtain(end - start);
             TextUtils.getChars(text, start, end, buf, 0);
             native_drawText(mNativeCanvas, buf, 0, end - start, x, y,
-                    paint.mBidiFlags, paint.mNativePaint);
+                    paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
             TemporaryBuffer.recycle(buf);
         }
     }
@@ -1507,7 +1507,7 @@
         }
 
         native_drawTextRun(mNativeCanvas, text, index, count,
-                contextIndex, contextCount, x, y, dir, paint.mNativePaint);
+                contextIndex, contextCount, x, y, dir, paint.mNativePaint, paint.mNativeTypeface);
     }
 
     /**
@@ -1545,7 +1545,7 @@
         if (text instanceof String || text instanceof SpannedString ||
                 text instanceof SpannableString) {
             native_drawTextRun(mNativeCanvas, text.toString(), start, end,
-                    contextStart, contextEnd, x, y, flags, paint.mNativePaint);
+                    contextStart, contextEnd, x, y, flags, paint.mNativePaint, paint.mNativeTypeface);
         } else if (text instanceof GraphicsOperations) {
             ((GraphicsOperations) text).drawTextRun(this, start, end,
                     contextStart, contextEnd, x, y, flags, paint);
@@ -1555,7 +1555,7 @@
             char[] buf = TemporaryBuffer.obtain(contextLen);
             TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
             native_drawTextRun(mNativeCanvas, buf, start - contextStart, len,
-                    0, contextLen, x, y, flags, paint.mNativePaint);
+                    0, contextLen, x, y, flags, paint.mNativePaint, paint.mNativeTypeface);
             TemporaryBuffer.recycle(buf);
         }
     }
@@ -1814,18 +1814,18 @@
     
     private static native void native_drawText(int nativeCanvas, char[] text,
                                                int index, int count, float x,
-                                               float y, int flags, int paint);
+                                               float y, int flags, int paint, int typeface);
     private static native void native_drawText(int nativeCanvas, String text,
                                                int start, int end, float x,
-                                               float y, int flags, int paint);
+                                               float y, int flags, int paint, int typeface);
 
     private static native void native_drawTextRun(int nativeCanvas, String text,
             int start, int end, int contextStart, int contextEnd,
-            float x, float y, int flags, int paint);
+            float x, float y, int flags, int paint, int typeface);
 
     private static native void native_drawTextRun(int nativeCanvas, char[] text,
             int start, int count, int contextStart, int contextCount,
-            float x, float y, int flags, int paint);
+            float x, float y, int flags, int paint, int typeface);
 
     private static native void native_drawPosText(int nativeCanvas,
                                                   char[] text, int index,
diff --git a/graphics/java/android/graphics/ColorFilter.java b/graphics/java/android/graphics/ColorFilter.java
index e5cf830..8e0af77 100644
--- a/graphics/java/android/graphics/ColorFilter.java
+++ b/graphics/java/android/graphics/ColorFilter.java
@@ -21,22 +21,30 @@
 
 package android.graphics;
 
-
+/**
+ * A color filter can be used with a {@link Paint} to modify the color of
+ * each pixel drawn with that paint. This is an abstract class that should
+ * never be used directly.
+ */
 public class ColorFilter {
+    // Holds the pointer to the native SkColorFilter instance
     int native_instance;
 
     /**
+     * Holds the pointer to the native SkiaColorFilter instance, from libhwui.
+     *
      * @hide
      */
     public int nativeColorFilter;
 
+    @Override
     protected void finalize() throws Throwable {
         try {
             super.finalize();
         } finally {
-            finalizer(native_instance, nativeColorFilter);
+            destroyFilter(native_instance, nativeColorFilter);
         }
     }
 
-    private static native void finalizer(int native_instance, int nativeColorFilter);
+    static native void destroyFilter(int native_instance, int nativeColorFilter);
 }
diff --git a/graphics/java/android/graphics/ColorMatrix.java b/graphics/java/android/graphics/ColorMatrix.java
index c22cda1..1242eb5 100644
--- a/graphics/java/android/graphics/ColorMatrix.java
+++ b/graphics/java/android/graphics/ColorMatrix.java
@@ -18,23 +18,29 @@
 
 import android.util.FloatMath;
 
+import java.util.Arrays;
+
 /**
- *  5x4 matrix for transforming the color+alpha components of a Bitmap.
+ *  4x5 matrix for transforming the color+alpha components of a Bitmap.
  *  The matrix is stored in a single array, and its treated as follows:
+ * <pre>
  *  [ a, b, c, d, e,
  *    f, g, h, i, j,
  *    k, l, m, n, o,
  *    p, q, r, s, t ]
+ * </pre>
  *
- * When applied to a color [r, g, b, a], the resulting color is computed as
- * (after clamping)
+ * When applied to a color <code>[r, g, b, a]</code>, the resulting color
+ * is computed as (after clamping):
+ * <pre>
  *   R' = a*R + b*G + c*B + d*A + e;
  *   G' = f*R + g*G + h*B + i*A + j;
  *   B' = k*R + l*G + m*B + n*A + o;
  *   A' = p*R + q*G + r*B + s*A + t;
+ * </pre>
  */
+@SuppressWarnings({ "MismatchedReadAndWriteOfArray", "PointlessArithmeticExpression" })
 public class ColorMatrix {
-
     private final float[] mArray = new float[20];
 
     /**
@@ -66,17 +72,16 @@
     
     /**
      * Set this colormatrix to identity:
+     * <pre>
      * [ 1 0 0 0 0   - red vector
      *   0 1 0 0 0   - green vector
      *   0 0 1 0 0   - blue vector
      *   0 0 0 1 0 ] - alpha vector
+     * </pre>
      */
     public void reset() {
         final float[] a = mArray;
-        
-        for (int i = 19; i > 0; --i) {
-            a[i] = 0;
-        }
+        Arrays.fill(a, 0);
         a[0] = a[6] = a[12] = a[18] = 1;
     }
     
@@ -112,9 +117,9 @@
     
     /**
      * Set the rotation on a color axis by the specified values.
-     * axis=0 correspond to a rotation around the RED color
-     * axis=1 correspond to a rotation around the GREEN color
-     * axis=2 correspond to a rotation around the BLUE color
+     * <code>axis=0</code> correspond to a rotation around the RED color
+     * <code>axis=1</code> correspond to a rotation around the GREEN color
+     * <code>axis=2</code> correspond to a rotation around the BLUE color
      */
     public void setRotate(int axis, float degrees) {
         reset();
@@ -144,7 +149,7 @@
             throw new RuntimeException();
         }
     }
-    
+
     /**
      * Set this colormatrix to the concatenation of the two specified
      * colormatrices, such that the resulting colormatrix has the same effect
@@ -152,12 +157,10 @@
      * matB to be the same colormatrix as this.
      */
     public void setConcat(ColorMatrix matA, ColorMatrix matB) {
-        float[] tmp = null;
-        
+        float[] tmp;
         if (matA == this || matB == this) {
             tmp = new float[20];
-        }
-        else {
+        } else {
             tmp = mArray;
         }
         
@@ -178,7 +181,7 @@
             System.arraycopy(tmp, 0, mArray, 0, 20);
         }
     }
-    
+
     /**
      * Concat this colormatrix with the specified prematrix. This is logically
      * the same as calling setConcat(this, prematrix);
@@ -186,7 +189,7 @@
     public void preConcat(ColorMatrix prematrix) {
         setConcat(this, prematrix);
     }
-    
+
     /**
      * Concat this colormatrix with the specified postmatrix. This is logically
      * the same as calling setConcat(postmatrix, this);
@@ -194,7 +197,7 @@
     public void postConcat(ColorMatrix postmatrix) {
         setConcat(postmatrix, this);
     }
-    
+
     ///////////////////////////////////////////////////////////////////////////
     
     /**
diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java
index 4f32342..8de32ec 100644
--- a/graphics/java/android/graphics/ColorMatrixColorFilter.java
+++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java
@@ -16,24 +16,31 @@
 
 package android.graphics;
 
+/**
+ * A color filter that transforms colors through a 4x5 color matrix. This filter
+ * can be used to change the saturation of pixels, convert from YUV to RGB, etc.
+ *
+ * @see ColorMatrix
+ */
 public class ColorMatrixColorFilter extends ColorFilter {
+    private final ColorMatrix mMatrix = new ColorMatrix();
+
     /**
-     * Create a colorfilter that transforms colors through a 4x5 color matrix.
+     * Create a color filter that transforms colors through a 4x5 color matrix.
      *
      * @param matrix 4x5 matrix used to transform colors. It is copied into
      *               the filter, so changes made to the matrix after the filter
      *               is constructed will not be reflected in the filter.
      */
     public ColorMatrixColorFilter(ColorMatrix matrix) {
-        final float[] colorMatrix = matrix.getArray();
-        native_instance = nativeColorMatrixFilter(colorMatrix);
-        nativeColorFilter = nColorMatrixFilter(native_instance, colorMatrix);
+        mMatrix.set(matrix);
+        update();
     }
 
     /**
-    * Create a colorfilter that transforms colors through a 4x5 color matrix.
+     * Create a color filter that transforms colors through a 4x5 color matrix.
      *
-     * @param array array of floats used to transform colors, treated as a 4x5
+     * @param array Array of floats used to transform colors, treated as a 4x5
      *              matrix. The first 20 entries of the array are copied into
      *              the filter. See ColorMatrix.
      */
@@ -41,8 +48,75 @@
         if (array.length < 20) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        native_instance = nativeColorMatrixFilter(array);
-        nativeColorFilter = nColorMatrixFilter(native_instance, array);
+        mMatrix.set(array);
+        update();
+    }
+
+    /**
+     * Returns the {@link ColorMatrix} used by this filter. The returned
+     * value is never null. Modifying the returned matrix does not have
+     * any effect until you call {@link #setColorMatrix(ColorMatrix)}.
+     *
+     * @see #setColorMatrix(ColorMatrix)
+     */
+    public ColorMatrix getColorMatrix() {
+        return mMatrix;
+    }
+
+    /**
+     * Specifies the color matrix used by this filter. If the specified
+     * color matrix is null, this filter's color matrix will be reset to
+     * the identity matrix.
+     *
+     * @param matrix A {@link ColorMatrix} or null
+     *
+     * @see #getColorMatrix()
+     * @see android.graphics.ColorMatrix#reset()
+     * @see #setColorMatrix(float[])
+     */
+    public void setColorMatrix(ColorMatrix matrix) {
+        if (matrix == null) {
+            mMatrix.reset();
+        } else if (matrix != mMatrix) {
+            mMatrix.set(matrix);
+        }
+        update();
+    }
+
+    /**
+     * Specifies the color matrix used by this filter. If the specified
+     * color matrix is null, this filter's color matrix will be reset to
+     * the identity matrix.
+     *
+     * @param array Array of floats used to transform colors, treated as a 4x5
+     *              matrix. The first 20 entries of the array are copied into
+     *              the filter. See {@link ColorMatrix}.
+     *
+     * @see #getColorMatrix()
+     * @see android.graphics.ColorMatrix#reset()
+     * @see #setColorMatrix(ColorMatrix)
+     *
+     * @throws ArrayIndexOutOfBoundsException if the specified array's
+     *         length is < 20
+     */
+    public void setColorMatrix(float[] array) {
+        if (array == null) {
+            mMatrix.reset();
+        } else {
+            if (array.length < 20) {
+                throw new ArrayIndexOutOfBoundsException();
+            }
+
+            mMatrix.set(array);
+        }
+        update();
+    }
+
+    private void update() {
+        final float[] colorMatrix = mMatrix.getArray();
+        destroyFilter(native_instance, nativeColorFilter);
+        native_instance = nativeColorMatrixFilter(colorMatrix);
+        nativeColorFilter = nColorMatrixFilter(native_instance, colorMatrix);
     }
 
     private static native int nativeColorMatrixFilter(float[] array);
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index 1bcfc18..e08ed50 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -187,6 +187,10 @@
      * == {@link android.media.Image.Plane#getPixelStride() vPlane.getPixelStride()};
      * ).</p>
      *
+     * <p>For example, the {@link android.media.Image} object can provide data
+     * in this format from a {@link android.hardware.camera2.CameraDevice}
+     * through a {@link android.media.ImageReader} object.</p>
+     *
      * @see android.media.Image
      * @see android.media.ImageReader
      * @see android.hardware.camera2.CameraDevice
@@ -203,8 +207,6 @@
      * needed information to interpret a raw sensor image must be queried from
      * the {@link android.hardware.camera2.CameraDevice} which produced the
      * image.</p>
-     *
-     * @hide
      */
     public static final int RAW_SENSOR = 0x20;
 
diff --git a/graphics/java/android/graphics/LargeBitmap.java b/graphics/java/android/graphics/LargeBitmap.java
index 6656b17..c70c709 100644
--- a/graphics/java/android/graphics/LargeBitmap.java
+++ b/graphics/java/android/graphics/LargeBitmap.java
@@ -16,16 +16,6 @@
 
 package android.graphics;
 
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.DisplayMetrics;
-
-import java.io.OutputStream;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-import java.nio.ShortBuffer;
-
 /**
  * LargeBitmap can be used to decode a rectangle region from an image.
  * LargeBimap is particularly useful when an original image is large and
diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java
index c621de6..75f1827 100644
--- a/graphics/java/android/graphics/LightingColorFilter.java
+++ b/graphics/java/android/graphics/LightingColorFilter.java
@@ -21,16 +21,87 @@
 
 package android.graphics;
 
+/**
+ * A color filter that can be used to simulate simple lighting effects.
+ * A <code>LightingColorFilter</code> is defined by two parameters, one
+ * used to multiply the source color (called <code>colorMultiply</code>)
+ * and one used to add to the source color (called <code>colorAdd</code>).
+ * The alpha channel is left untouched by this color filter.
+ *
+ * Given a source color RGB, the resulting R'G'B' color is computed thusly:
+ * <pre>
+ * R' = R * colorMultiply.R + colorAdd.R
+ * G' = G * colorMultiply.G + colorAdd.G
+ * B' = B * colorMultiply.B + colorAdd.B
+ * </pre>
+ * The result is pinned to the <code>[0..255]</code> range for each channel.
+ */
 public class LightingColorFilter extends ColorFilter {
+    private int mMul;
+    private int mAdd;
 
     /**
-     * Create a colorfilter that multiplies the RGB channels by one color, and then adds a second color,
-     * pinning the result for each component to [0..255]. The alpha components of the mul and add arguments
-     * are ignored.
+     * Create a colorfilter that multiplies the RGB channels by one color,
+     * and then adds a second color. The alpha components of the mul and add
+     * arguments are ignored.
+     *
+     * @see #setColorMultiply(int)
+     * @see #setColorAdd(int)
      */
     public LightingColorFilter(int mul, int add) {
-        native_instance = native_CreateLightingFilter(mul, add);
-        nativeColorFilter = nCreateLightingFilter(native_instance, mul, add);
+        mMul = mul;
+        mAdd = add;
+        update();
+    }
+
+    /**
+     * Returns the RGB color used to multiply the source color when the
+     * color filter is applied.
+     *
+     * @see #setColorMultiply(int)
+     */
+    public int getColorMultiply() {
+        return mMul;
+    }
+
+    /**
+     * Specifies the RGB color used to multiply the source color when the
+     * color filter is applied.
+     * The alpha channel of this color is ignored.
+     *
+     * @see #getColorMultiply()
+     */
+    public void setColorMultiply(int mul) {
+        mMul = mul;
+        update();
+    }
+
+    /**
+     * Returns the RGB color that will be added to the source color
+     * when the color filter is applied.
+     *
+     * @see #setColorAdd(int)
+     */
+    public int getColorAdd() {
+        return mAdd;
+    }
+
+    /**
+     * Specifies the RGB that will be added to the source color when
+     * the color filter is applied.
+     * The alpha channel of this color is ignored.
+     *
+     * @see #getColorAdd()
+     */
+    public void setColorAdd(int add) {
+        mAdd = add;
+        update();
+    }
+
+    private void update() {
+        destroyFilter(native_instance, nativeColorFilter);
+        native_instance = native_CreateLightingFilter(mMul, mAdd);
+        nativeColorFilter = nCreateLightingFilter(native_instance, mMul, mAdd);
     }
 
     private static native int native_CreateLightingFilter(int mul, int add);
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 5fc2588..c2d4df2 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -33,6 +33,10 @@
      * @hide
      */
     public int mNativePaint;
+    /**
+     * @hide
+     */
+    public int mNativeTypeface;
 
     private ColorFilter mColorFilter;
     private MaskFilter  mMaskFilter;
@@ -481,6 +485,7 @@
         mRasterizer = null;
         mShader = null;
         mTypeface = null;
+        mNativeTypeface = 0;
         mXfermode = null;
 
         mHasCompatScaling = false;
@@ -525,6 +530,7 @@
             mShader = null;
         }
         mTypeface = paint.mTypeface;
+        mNativeTypeface = paint.mNativeTypeface;
         mXfermode = paint.mXfermode;
 
         mHasCompatScaling = paint.mHasCompatScaling;
@@ -1087,6 +1093,7 @@
         }
         native_setTypeface(mNativePaint, typefaceNative);
         mTypeface = typeface;
+        mNativeTypeface = typefaceNative;
         return typeface;
     }
     
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index 5b04a91..1a7e3ec 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -16,8 +16,6 @@
 
 package android.graphics;
 
-import android.view.HardwareRenderer;
-
 /**
  * The Path class encapsulates compound (multiple contour) geometric paths
  * consisting of straight line segments, quadratic curves, and cubic curves.
@@ -39,7 +37,6 @@
      * @hide
      */
     public Region rects;
-    private boolean mDetectSimplePaths;
     private Direction mLastDirection = null;
 
     /**
@@ -47,7 +44,6 @@
      */
     public Path() {
         mNativePath = init1();
-        mDetectSimplePaths = HardwareRenderer.isAvailable();
     }
 
     /**
@@ -65,7 +61,6 @@
             }
         }
         mNativePath = init2(valNative);
-        mDetectSimplePaths = HardwareRenderer.isAvailable();
     }
     
     /**
@@ -74,10 +69,8 @@
      */
     public void reset() {
         isSimplePath = true;
-        if (mDetectSimplePaths) {
-            mLastDirection = null;
-            if (rects != null) rects.setEmpty();
-        }
+        mLastDirection = null;
+        if (rects != null) rects.setEmpty();
         // We promised not to change this, so preserve it around the native
         // call, which does now reset fill type.
         final FillType fillType = getFillType();
@@ -91,10 +84,8 @@
      */
     public void rewind() {
         isSimplePath = true;
-        if (mDetectSimplePaths) {
-            mLastDirection = null;
-            if (rects != null) rects.setEmpty();
-        }
+        mLastDirection = null;
+        if (rects != null) rects.setEmpty();
         native_rewind(mNativePath);
     }
 
@@ -475,16 +466,14 @@
     }
     
     private void detectSimplePath(float left, float top, float right, float bottom, Direction dir) {
-        if (mDetectSimplePaths) {
-            if (mLastDirection == null) {
-                mLastDirection = dir;
-            }
-            if (mLastDirection != dir) {
-                isSimplePath = false;
-            } else {
-                if (rects == null) rects = new Region();
-                rects.op((int) left, (int) top, (int) right, (int) bottom, Region.Op.UNION);
-            }
+        if (mLastDirection == null) {
+            mLastDirection = dir;
+        }
+        if (mLastDirection != dir) {
+            isSimplePath = false;
+        } else {
+            if (rects == null) rects = new Region();
+            rects.op((int) left, (int) top, (int) right, (int) bottom, Region.Op.UNION);
         }
     }
 
@@ -703,6 +692,28 @@
         return mNativePath;
     }
 
+    /**
+     * Approximate the <code>Path</code> with a series of line segments.
+     * This returns float[] with the array containing point components.
+     * There are three components for each point, in order:
+     * <ul>
+     *     <li>Fraction along the length of the path that the point resides</li>
+     *     <li>The x coordinate of the point</li>
+     *     <li>The y coordinate of the point</li>
+     * </ul>
+     * <p>Two points may share the same fraction along its length when there is
+     * a move action within the Path.</p>
+     *
+     * @param acceptableError The acceptable error for a line on the
+     *                        Path. Typically this would be 0.5 so that
+     *                        the error is less than half a pixel.
+     * @return An array of components for points approximating the Path.
+     * @hide
+     */
+    public float[] approximate(float acceptableError) {
+        return native_approximate(mNativePath, acceptableError);
+    }
+
     private static native int init1();
     private static native int init2(int nPath);
     private static native void native_reset(int nPath);
@@ -749,4 +760,5 @@
     private static native void native_transform(int nPath, int matrix);
     private static native boolean native_op(int path1, int path2, int op, int result);
     private static native void finalizer(int nPath);
+    private static native float[] native_approximate(int nPath, float error);
 }
diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java
index ecc7c24..9870ad2 100644
--- a/graphics/java/android/graphics/PorterDuffColorFilter.java
+++ b/graphics/java/android/graphics/PorterDuffColorFilter.java
@@ -16,17 +16,84 @@
 
 package android.graphics;
 
+/**
+ * A color filter that can be used to tint the source pixels using a single
+ * color and a specific {@link PorterDuff Porter-Duff composite mode}.
+ */
 public class PorterDuffColorFilter extends ColorFilter {
+    private int mColor;
+    private PorterDuff.Mode mMode;
+
     /**
-     * Create a colorfilter that uses the specified color and porter-duff mode.
+     * Create a color filter that uses the specified color and Porter-Duff mode.
      *
-     * @param srcColor       The source color used with the specified
-     *                       porter-duff mode
-     * @param mode           The porter-duff mode that is applied
+     * @param color The ARGB source color used with the specified Porter-Duff mode
+     * @param mode The porter-duff mode that is applied
+     *
+     * @see Color
+     * @see #setColor(int)
+     * @see #setMode(android.graphics.PorterDuff.Mode)
      */
-    public PorterDuffColorFilter(int srcColor, PorterDuff.Mode mode) {
-        native_instance = native_CreatePorterDuffFilter(srcColor, mode.nativeInt);
-        nativeColorFilter = nCreatePorterDuffFilter(native_instance, srcColor, mode.nativeInt);
+    public PorterDuffColorFilter(int color, PorterDuff.Mode mode) {
+        mColor = color;
+        mMode = mode;
+        update();
+    }
+
+    /**
+     * Returns the ARGB color used to tint the source pixels when this filter
+     * is applied.
+     *
+     * @see Color
+     * @see #setColor(int)
+     */
+    public int getColor() {
+        return mColor;
+    }
+
+    /**
+     * Specifies the color to tint the source pixels with when this color
+     * filter is applied.
+     *
+     * @param color An ARGB {@link Color color}
+     *
+     * @see Color
+     * @see #getColor()
+     * @see #getMode()
+     */
+    public void setColor(int color) {
+        mColor = color;
+        update();
+    }
+
+    /**
+     * Returns the Porter-Duff mode used to composite this color filter's
+     * color with the source pixel when this filter is applied.
+     *
+     * @see PorterDuff
+     * @see #setMode(android.graphics.PorterDuff.Mode)
+     */
+    public PorterDuff.Mode getMode() {
+        return mMode;
+    }
+
+    /**
+     * Specifies the Porter-Duff mode to use when compositing this color
+     * filter's color with the source pixel at draw time.
+     *
+     * @see PorterDuff
+     * @see #getMode()
+     * @see #getColor()
+     */
+    public void setMode(PorterDuff.Mode mode) {
+        mMode = mode;
+        update();
+    }
+
+    private void update() {
+        destroyFilter(native_instance, nativeColorFilter);
+        native_instance = native_CreatePorterDuffFilter(mColor, mMode.nativeInt);
+        nativeColorFilter = nCreatePorterDuffFilter(native_instance, mColor, mMode.nativeInt);
     }
 
     private static native int native_CreatePorterDuffFilter(int srcColor, int porterDuffMode);
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index c68c9f7..aea3ee5 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -48,7 +48,10 @@
     private static final SparseArray<SparseArray<Typeface>> sTypefaceCache =
             new SparseArray<SparseArray<Typeface>>(3);
 
-    int native_instance;
+    /**
+     * @hide
+     */
+    public int native_instance;
 
     // Style
     public static final int NORMAL = 0;
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index bde978d..02b2588 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -81,6 +81,7 @@
 public class AnimationDrawable extends DrawableContainer implements Runnable, Animatable {
     private final AnimationState mAnimationState;
     private int mCurFrame = -1;
+    private boolean mAnimating;
     private boolean mMutated;
 
     public AnimationDrawable() {
@@ -137,7 +138,7 @@
      * @return true if the animation is running, false otherwise
      */
     public boolean isRunning() {
-        return mCurFrame > -1;
+        return mAnimating;
     }
 
     /**
@@ -153,6 +154,7 @@
     @Override
     public void unscheduleSelf(Runnable what) {
         mCurFrame = -1;
+        mAnimating = false;
         super.unscheduleSelf(what);
     }
 
@@ -222,12 +224,13 @@
         }
         mCurFrame = frame;
         selectDrawable(frame);
-        if (unschedule) {
+        if (unschedule || animate) {
             unscheduleSelf(this);
         }
         if (animate) {
-            // Unscheduling may have clobbered this value; restore it to record that we're animating
+            // Unscheduling may have clobbered these values; restore them
             mCurFrame = frame;
+            mAnimating = true;
             scheduleSelf(this, SystemClock.uptimeMillis() + mAnimationState.mDurations[frame]);
         }
     }
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 8a3d940..c84cdb0 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -39,6 +39,7 @@
 import android.util.StateSet;
 import android.util.TypedValue;
 import android.util.Xml;
+import android.view.View;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -399,7 +400,7 @@
      *
      * @hide
      */
-    public void setLayoutDirection(int layoutDirection) {
+    public void setLayoutDirection(@View.ResolvedLayoutDir int layoutDirection) {
         if (getLayoutDirection() != layoutDirection) {
             mLayoutDirection = layoutDirection;
         }
@@ -693,8 +694,8 @@
      */
     protected boolean onLevelChange(int level) { return false; }
     /**
-     * Override this in your subclass to change appearance if you recognize the
-     * specified state.
+     * Override this in your subclass to change appearance if you vary based on
+     * the bounds.
      */
     protected void onBoundsChange(Rect bounds) {}
 
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index b340777..d4799e6 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -16,6 +16,7 @@
 
 package android.graphics.drawable;
 
+import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -24,12 +25,12 @@
 import android.graphics.DashPathEffect;
 import android.graphics.LinearGradient;
 import android.graphics.Paint;
+import android.graphics.Path;
 import android.graphics.PixelFormat;
+import android.graphics.RadialGradient;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Shader;
-import android.graphics.Path;
-import android.graphics.RadialGradient;
 import android.graphics.SweepGradient;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -233,6 +234,23 @@
     }
 
     /**
+     * <p>Set the stroke width and color state list for the drawable. If width
+     * is zero, then no stroke is drawn.</p>
+     * <p><strong>Note</strong>: changing this property will affect all instances
+     * of a drawable loaded from a resource. It is recommended to invoke
+     * {@link #mutate()} before changing this property.</p>
+     *
+     * @param width The width in pixels of the stroke
+     * @param colorStateList The color state list of the stroke
+     *
+     * @see #mutate()
+     * @see #setStroke(int, ColorStateList, float, float)
+     */
+    public void setStroke(int width, ColorStateList colorStateList) {
+        setStroke(width, colorStateList, 0, 0);
+    }
+
+    /**
      * <p>Set the stroke width and color for the drawable. If width is zero,
      * then no stroke is drawn. This method can also be used to dash the stroke.</p>
      * <p><strong>Note</strong>: changing this property will affect all instances
@@ -249,7 +267,39 @@
      */
     public void setStroke(int width, int color, float dashWidth, float dashGap) {
         mGradientState.setStroke(width, color, dashWidth, dashGap);
+        setStrokeInternal(width, color, dashWidth, dashGap);
+    }
 
+    /**
+     * <p>Set the stroke width and color state list for the drawable. If width
+     * is zero, then no stroke is drawn. This method can also be used to dash
+     * the stroke.</p>
+     * <p><strong>Note</strong>: changing this property will affect all instances
+     * of a drawable loaded from a resource. It is recommended to invoke
+     * {@link #mutate()} before changing this property.</p>
+     *
+     * @param width The width in pixels of the stroke
+     * @param colorStateList The color state list of the stroke
+     * @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes
+     * @param dashGap The gap in pixels between dashes
+     *
+     * @see #mutate()
+     * @see #setStroke(int, ColorStateList)
+     */
+    public void setStroke(
+            int width, ColorStateList colorStateList, float dashWidth, float dashGap) {
+        if (colorStateList == null) {
+            setStroke(width, Color.TRANSPARENT, dashWidth, dashGap);
+        } else {
+            mGradientState.setStroke(width, colorStateList, dashWidth, dashGap);
+
+            final int[] stateSet = getState();
+            final int color = colorStateList.getColorForState(stateSet, 0);
+            setStrokeInternal(width, color, dashWidth, dashGap);
+        }
+    }
+
+    private void setStrokeInternal(int width, int color, float dashWidth, float dashGap) {
         if (mStrokePaint == null)  {
             mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
             mStrokePaint.setStyle(Paint.Style.STROKE);
@@ -479,7 +529,8 @@
             mFillPaint.setAlpha(currFillAlpha);
             mFillPaint.setDither(mDither);
             mFillPaint.setColorFilter(mColorFilter);
-            if (mColorFilter != null && !mGradientState.mHasSolidColor) {
+            if (mColorFilter != null && !mGradientState.mHasSolidColor
+                    && mGradientState.mColorStateList == null) {
                 mFillPaint.setColor(mAlpha << 24);
             }
             if (haveStroke) {
@@ -610,7 +661,7 @@
     }
 
     /**
-     * <p>Changes this drawbale to use a single color instead of a gradient.</p>
+     * <p>Changes this drawable to use a single color instead of a gradient.</p>
      * <p><strong>Note</strong>: changing color will affect all instances
      * of a drawable loaded from a resource. It is recommended to invoke
      * {@link #mutate()} before changing the color.</p>
@@ -626,6 +677,74 @@
         invalidateSelf();
     }
 
+    /**
+     * Changes this drawable to use a single color state list instead of a
+     * gradient. Calling this method with a null argument will clear the color
+     * and is equivalent to calling {@link #setColor(int)} with the argument
+     * {@link Color#TRANSPARENT}.
+     * <p>
+     * <strong>Note</strong>: changing color will affect all instances of a
+     * drawable loaded from a resource. It is recommended to invoke
+     * {@link #mutate()} before changing the color.</p>
+     *
+     * @param colorStateList The color state list used to fill the shape
+     * @see #mutate()
+     */
+    public void setColor(ColorStateList colorStateList) {
+        if (colorStateList == null) {
+            setColor(Color.TRANSPARENT);
+        } else {
+            final int color = colorStateList.getColorForState(getState(), 0);
+            mGradientState.setColorStateList(colorStateList);
+            mFillPaint.setColor(color);
+            invalidateSelf();
+        }
+    }
+
+    @Override
+    public boolean onStateChange(int[] stateSet) {
+        boolean invalidateSelf = false;
+
+        final GradientState s = mGradientState;
+        final ColorStateList stateList = s.mColorStateList;
+        if (stateList != null) {
+            final int newColor = stateList.getColorForState(stateSet, 0);
+            final int oldColor = mFillPaint.getColor();
+            if (oldColor != newColor) {
+                mFillPaint.setColor(newColor);
+                invalidateSelf = true;
+            }
+        }
+
+        final Paint strokePaint = mStrokePaint;
+        if (strokePaint != null) {
+            final ColorStateList strokeStateList = s.mStrokeColorStateList;
+            if (strokeStateList != null) {
+                final int newStrokeColor = strokeStateList.getColorForState(stateSet, 0);
+                final int oldStrokeColor = strokePaint.getColor();
+                if (oldStrokeColor != newStrokeColor) {
+                    strokePaint.setColor(newStrokeColor);
+                    invalidateSelf = true;
+                }
+            }
+        }
+
+        if (invalidateSelf) {
+            invalidateSelf();
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isStateful() {
+        final GradientState s = mGradientState;
+        return super.isStateful()
+                || (s.mColorStateList != null && s.mColorStateList.isStateful())
+                || (s.mStrokeColorStateList != null && s.mStrokeColorStateList.isStateful());
+    }
+
     @Override
     public int getChangingConfigurations() {
         return super.getChangingConfigurations() | mGradientState.mChangingConfigurations;
@@ -791,7 +910,7 @@
 
                 // If we don't have a solid color, the alpha channel must be
                 // maxed out so that alpha modulation works correctly.
-                if (!st.mHasSolidColor) {
+                if (!st.mHasSolidColor && st.mColorStateList == null) {
                     mFillPaint.setColor(Color.BLACK);
                 }
             }
@@ -967,25 +1086,25 @@
             } else if (name.equals("solid")) {
                 a = r.obtainAttributes(attrs,
                         com.android.internal.R.styleable.GradientDrawableSolid);
-                int argb = a.getColor(
-                        com.android.internal.R.styleable.GradientDrawableSolid_color, 0);
+                final ColorStateList colorStateList = a.getColorStateList(
+                        com.android.internal.R.styleable.GradientDrawableSolid_color);
                 a.recycle();
-                setColor(argb);
+                setColor(colorStateList);
             } else if (name.equals("stroke")) {
                 a = r.obtainAttributes(attrs,
                         com.android.internal.R.styleable.GradientDrawableStroke);
-                int width = a.getDimensionPixelSize(
+                final int width = a.getDimensionPixelSize(
                         com.android.internal.R.styleable.GradientDrawableStroke_width, 0);
-                int color = a.getColor(
-                        com.android.internal.R.styleable.GradientDrawableStroke_color, 0);
-                float dashWidth = a.getDimension(
+                final ColorStateList colorStateList = a.getColorStateList(
+                        com.android.internal.R.styleable.GradientDrawableStroke_color);
+                final float dashWidth = a.getDimension(
                         com.android.internal.R.styleable.GradientDrawableStroke_dashWidth, 0);
                 if (dashWidth != 0.0f) {
-                    float dashGap = a.getDimension(
+                    final float dashGap = a.getDimension(
                             com.android.internal.R.styleable.GradientDrawableStroke_dashGap, 0);
-                    setStroke(width, color, dashWidth, dashGap);
+                    setStroke(width, colorStateList, dashWidth, dashGap);
                 } else {
-                    setStroke(width, color);
+                    setStroke(width, colorStateList);
                 }
                 a.recycle();
             } else if (name.equals("corners")) {
@@ -1077,6 +1196,8 @@
         public int mShape = RECTANGLE;
         public int mGradient = LINEAR_GRADIENT;
         public Orientation mOrientation;
+        public ColorStateList mColorStateList;
+        public ColorStateList mStrokeColorStateList;
         public int[] mColors;
         public int[] mTempColors; // no need to copy
         public float[] mTempPositions; // no need to copy
@@ -1113,6 +1234,7 @@
             mShape = state.mShape;
             mGradient = state.mGradient;
             mOrientation = state.mOrientation;
+            mColorStateList = state.mColorStateList;
             if (state.mColors != null) {
                 mColors = state.mColors.clone();
             }
@@ -1178,13 +1300,22 @@
         public void setColors(int[] colors) {
             mHasSolidColor = false;
             mColors = colors;
+            mColorStateList = null;
             computeOpacity();
         }
         
         public void setSolidColor(int argb) {
-            mHasSolidColor = true;
+            mHasSolidColor = argb != Color.TRANSPARENT;
             mSolidColor = argb;
             mColors = null;
+            mColorStateList = null;
+            computeOpacity();
+        }
+
+        public void setColorStateList(ColorStateList colorStateList) {
+            mHasSolidColor = false;
+            mColors = null;
+            mColorStateList = colorStateList;
             computeOpacity();
         }
 
@@ -1199,11 +1330,23 @@
                 return;
             }
 
-            if (mStrokeWidth > 0 && !isOpaque(mStrokeColor)) {
+            if (mStrokeWidth > 0) {
+                if (mStrokeColorStateList != null) {
+                    if (!mStrokeColorStateList.isOpaque()) {
+                        mOpaque = false;
+                        return;
+                    }
+                } else if (!isOpaque(mStrokeColor)) {
+                    mOpaque = false;
+                    return;
+                }
+            }
+
+            if (mColorStateList != null && !mColorStateList.isOpaque()) {
                 mOpaque = false;
                 return;
             }
-            
+
             if (mHasSolidColor) {
                 mOpaque = isOpaque(mSolidColor);
                 return;
@@ -1228,12 +1371,23 @@
         public void setStroke(int width, int color) {
             mStrokeWidth = width;
             mStrokeColor = color;
+            mStrokeColorStateList = null;
             computeOpacity();
         }
 
         public void setStroke(int width, int color, float dashWidth, float dashGap) {
             mStrokeWidth = width;
             mStrokeColor = color;
+            mStrokeColorStateList = null;
+            mStrokeDashWidth = dashWidth;
+            mStrokeDashGap = dashGap;
+            computeOpacity();
+        }
+
+        public void setStroke(
+                int width, ColorStateList colorStateList, float dashWidth, float dashGap) {
+            mStrokeWidth = width;
+            mStrokeColorStateList = colorStateList;
             mStrokeDashWidth = dashWidth;
             mStrokeDashGap = dashGap;
             computeOpacity();
@@ -1274,6 +1428,10 @@
     private void initializeWithState(GradientState state) {
         if (state.mHasSolidColor) {
             mFillPaint.setColor(state.mSolidColor);
+        } else if (state.mColorStateList != null) {
+            final int[] currentState = getState();
+            final int stateColor = state.mColorStateList.getColorForState(currentState, 0);
+            mFillPaint.setColor(stateColor);
         } else if (state.mColors == null) {
             // If we don't have a solid color and we don't have a gradient,
             // the app is stroking the shape, set the color to the default
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 81cc11b..429ad2f 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -30,7 +30,7 @@
 
 import java.io.IOException;
 
-/** 
+/**
  * A Drawable that manages an array of other Drawables. These are drawn in array
  * order, so the element with the largest index will be drawn on top.
  * <p>
@@ -47,6 +47,15 @@
  * @attr ref android.R.styleable#LayerDrawableItem_id
 */
 public class LayerDrawable extends Drawable implements Drawable.Callback {
+    /**
+     * Padding mode used to nest each layer inside the padding of the previous
+     * layer.
+     */
+    public static final int PADDING_MODE_NEST = 0;
+
+    /** Padding mode used to stack each layer directly atop the previous layer. */
+    public static final int PADDING_MODE_STACK = 1;
+
     LayerState mLayerState;
 
     private int mOpacityOverride = PixelFormat.UNKNOWN;
@@ -55,8 +64,10 @@
     private int[] mPaddingR;
     private int[] mPaddingB;
 
+    private final Rect mCachedPadding = new Rect();
     private final Rect mTmpRect = new Rect();
     private boolean mMutated;
+    private boolean mHasCachedPadding;
 
     /**
      * Create a new layer drawable with the list of specified layers.
@@ -90,7 +101,7 @@
 
         ensurePadding();
     }
-    
+
     LayerDrawable() {
         this((LayerState) null, null);
     }
@@ -122,6 +133,9 @@
         setAutoMirrored(a.getBoolean(com.android.internal.R.styleable.LayerDrawable_autoMirrored,
                 false));
 
+        mLayerState.mPaddingMode = a.getInteger(
+                com.android.internal.R.styleable.LayerDrawableItem_drawable, PADDING_MODE_NEST);
+
         a.recycle();
 
         final int innerDepth = parser.getDepth() + 1;
@@ -187,19 +201,20 @@
      */
     private void addLayer(Drawable layer, int id, int left, int top, int right, int bottom) {
         final LayerState st = mLayerState;
-        int N = st.mChildren != null ? st.mChildren.length : 0;
-        int i = st.mNum;
+        final int N = st.mChildren != null ? st.mChildren.length : 0;
+        final int i = st.mNum;
         if (i >= N) {
-            ChildDrawable[] nu = new ChildDrawable[N + 10];
+            final ChildDrawable[] nu = new ChildDrawable[N + 10];
             if (i > 0) {
                 System.arraycopy(st.mChildren, 0, nu, 0, i);
             }
+
             st.mChildren = nu;
         }
 
         mLayerState.mChildrenChangingConfigurations |= layer.getChangingConfigurations();
-        
-        ChildDrawable childDrawable = new ChildDrawable();
+
+        final ChildDrawable childDrawable = new ChildDrawable();
         st.mChildren[i] = childDrawable;
         childDrawable.mId = id;
         childDrawable.mDrawable = layer;
@@ -221,26 +236,26 @@
      */
     public Drawable findDrawableByLayerId(int id) {
         final ChildDrawable[] layers = mLayerState.mChildren;
-        
-        for (int i = mLayerState.mNum - 1; i >= 0; i--) {
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i--) {
             if (layers[i].mId == id) {
                 return layers[i].mDrawable;
             }
         }
-        
+
         return null;
     }
-    
+
     /**
      * Sets the ID of a layer.
-     * 
-     * @param index The index of the layer which will received the ID. 
+     *
+     * @param index The index of the layer which will received the ID.
      * @param id The ID to assign to the layer.
      */
     public void setId(int index, int id) {
         mLayerState.mChildren[index].mId = id;
     }
-    
+
     /**
      * Returns the number of layers contained within this.
      * @return The number of layers.
@@ -265,15 +280,15 @@
      *
      * @param index The index of the layer.
      *
-     * @return The id of the layer or {@link android.view.View#NO_ID} if the layer has no id. 
+     * @return The id of the layer or {@link android.view.View#NO_ID} if the layer has no id.
      */
     public int getId(int index) {
         return mLayerState.mChildren[index].mId;
     }
-    
+
     /**
      * Sets (or replaces) the {@link Drawable} for the layer with the given id.
-     * 
+     *
      * @param id The layer ID to search for.
      * @param drawable The replacement {@link Drawable}.
      * @return Whether the {@link Drawable} was replaced (could return false if
@@ -281,43 +296,88 @@
      */
     public boolean setDrawableByLayerId(int id, Drawable drawable) {
         final ChildDrawable[] layers = mLayerState.mChildren;
-        
-        for (int i = mLayerState.mNum - 1; i >= 0; i--) {
-            if (layers[i].mId == id) {
-                if (layers[i].mDrawable != null) {
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
+            final ChildDrawable childDrawable = layers[i];
+            if (childDrawable.mId == id) {
+                if (childDrawable.mDrawable != null) {
                     if (drawable != null) {
-                        Rect bounds = layers[i].mDrawable.getBounds();
+                        final Rect bounds = childDrawable.mDrawable.getBounds();
                         drawable.setBounds(bounds);
                     }
-                    layers[i].mDrawable.setCallback(null);
+
+                    childDrawable.mDrawable.setCallback(null);
                 }
+
                 if (drawable != null) {
                     drawable.setCallback(this);
                 }
-                layers[i].mDrawable = drawable;
+
+                childDrawable.mDrawable = drawable;
+
+                if (refreshChildPadding(i, childDrawable)) {
+                    invalidatePadding();
+                }
+
                 return true;
             }
         }
-        
+
         return false;
     }
-    
-    /** Specify modifiers to the bounds for the drawable[index].
-        left += l
-        top += t;
-        right -= r;
-        bottom -= b;
-    */
+
+    /**
+     * Specifies the insets in pixels for the drawable at the specified index.
+     * Insets are used to adjust the drawable bounds.
+     *
+     * @param index the index of the drawable to adjust
+     * @param l number of pixels to add to the left bound
+     * @param t number of pixels to add to the top bound
+     * @param r number of pixels to subtract from the right bound
+     * @param b number of pixels to subtract from the bottom bound
+     */
     public void setLayerInset(int index, int l, int t, int r, int b) {
-        ChildDrawable childDrawable = mLayerState.mChildren[index];
+        final ChildDrawable childDrawable = mLayerState.mChildren[index];
         childDrawable.mInsetL = l;
         childDrawable.mInsetT = t;
         childDrawable.mInsetR = r;
         childDrawable.mInsetB = b;
     }
 
-    // overrides from Drawable.Callback
+    /**
+     * Specifies how layer padding should affect the bounds of subsequent
+     * layers. The default value is {@link #PADDING_MODE_NEST}.
+     *
+     * @param mode padding mode, one of:
+     *            <ul>
+     *            <li>{@link #PADDING_MODE_NEST}
+     *            <li>{@link #PADDING_MODE_STACK}
+     *            </ul>
+     */
+    public void setPaddingMode(int mode) {
+        if (mLayerState.mPaddingMode != mode) {
+            mLayerState.mPaddingMode = mode;
+            invalidatePadding();
+        }
+    }
 
+    /**
+     * @return the current padding mode
+     * @see #setPaddingMode(int)
+     */
+    public int getPaddingMode() {
+      return mLayerState.mPaddingMode;
+    }
+
+    /**
+     * Invalidates cached padding.
+     */
+    private void invalidatePadding() {
+        mHasCachedPadding = false;
+        onBoundsChange(getBounds());
+    }
+
+    @Override
     public void invalidateDrawable(Drawable who) {
         final Callback callback = getCallback();
         if (callback != null) {
@@ -325,6 +385,7 @@
         }
     }
 
+    @Override
     public void scheduleDrawable(Drawable who, Runnable what, long when) {
         final Callback callback = getCallback();
         if (callback != null) {
@@ -332,6 +393,7 @@
         }
     }
 
+    @Override
     public void unscheduleDrawable(Drawable who, Runnable what) {
         final Callback callback = getCallback();
         if (callback != null) {
@@ -339,13 +401,11 @@
         }
     }
 
-    // overrides from Drawable
-
     @Override
     public void draw(Canvas canvas) {
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             array[i].mDrawable.draw(canvas);
         }
     }
@@ -356,36 +416,72 @@
                 | mLayerState.mChangingConfigurations
                 | mLayerState.mChildrenChangingConfigurations;
     }
-    
+
     @Override
     public boolean getPadding(Rect padding) {
-        // Arbitrarily get the padding from the first image.
-        // Technically we should maybe do something more intelligent,
-        // like take the max padding of all the images.
+        final Rect cachedPadding = mCachedPadding;
+        if (!mHasCachedPadding) {
+            if (mLayerState.mPaddingMode == PADDING_MODE_NEST) {
+                computeNestedPadding(cachedPadding);
+            } else {
+                computeStackedPadding(cachedPadding);
+            }
+
+            mHasCachedPadding = true;
+        }
+
+        padding.set(cachedPadding);
+
+        return padding.left != 0 || padding.top != 0 || padding.right != 0 || padding.bottom != 0;
+    }
+
+    private void computeNestedPadding(Rect padding) {
         padding.left = 0;
         padding.top = 0;
         padding.right = 0;
         padding.bottom = 0;
+
+        // Add all the padding.
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
-            reapplyPadding(i, array[i]);
+        for (int i = 0; i < N; i++) {
+            refreshChildPadding(i, array[i]);
+
             padding.left += mPaddingL[i];
             padding.top += mPaddingT[i];
             padding.right += mPaddingR[i];
             padding.bottom += mPaddingB[i];
         }
-        return true;
+    }
+
+    private void computeStackedPadding(Rect padding) {
+        padding.left = 0;
+        padding.top = 0;
+        padding.right = 0;
+        padding.bottom = 0;
+
+        // Take the max padding.
+        final ChildDrawable[] array = mLayerState.mChildren;
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
+            refreshChildPadding(i, array[i]);
+
+            padding.left = Math.max(padding.left, mPaddingL[i]);
+            padding.top = Math.max(padding.top, mPaddingT[i]);
+            padding.right = Math.max(padding.right, mPaddingR[i]);
+            padding.bottom = Math.max(padding.bottom, mPaddingB[i]);
+        }
     }
 
     @Override
     public boolean setVisible(boolean visible, boolean restart) {
-        boolean changed = super.setVisible(visible, restart);
+        final boolean changed = super.setVisible(visible, restart);
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             array[i].mDrawable.setVisible(visible, restart);
         }
+
         return changed;
     }
 
@@ -393,7 +489,7 @@
     public void setDither(boolean dither) {
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             array[i].mDrawable.setDither(dither);
         }
     }
@@ -402,7 +498,7 @@
     public void setAlpha(int alpha) {
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             array[i].mDrawable.setAlpha(alpha);
         }
     }
@@ -422,7 +518,7 @@
     public void setColorFilter(ColorFilter cf) {
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             array[i].mDrawable.setColorFilter(cf);
         }
     }
@@ -442,7 +538,7 @@
     public void setOpacity(int opacity) {
         mOpacityOverride = opacity;
     }
-    
+
     @Override
     public int getOpacity() {
         if (mOpacityOverride != PixelFormat.UNKNOWN) {
@@ -454,9 +550,10 @@
     @Override
     public void setAutoMirrored(boolean mirrored) {
         mLayerState.mAutoMirrored = mirrored;
+
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             array[i].mDrawable.setAutoMirrored(mirrored);
         }
     }
@@ -470,105 +567,137 @@
     public boolean isStateful() {
         return mLayerState.isStateful();
     }
-    
+
     @Override
     protected boolean onStateChange(int[] state) {
-        final ChildDrawable[] array = mLayerState.mChildren;
-        final int N = mLayerState.mNum;
         boolean paddingChanged = false;
         boolean changed = false;
-        for (int i=0; i<N; i++) {
+
+        final ChildDrawable[] array = mLayerState.mChildren;
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
             final ChildDrawable r = array[i];
             if (r.mDrawable.setState(state)) {
                 changed = true;
             }
-            if (reapplyPadding(i, r)) {
+
+            if (refreshChildPadding(i, r)) {
                 paddingChanged = true;
             }
         }
+
         if (paddingChanged) {
-            onBoundsChange(getBounds());
+            invalidatePadding();
         }
+
         return changed;
     }
-    
+
     @Override
     protected boolean onLevelChange(int level) {
-        final ChildDrawable[] array = mLayerState.mChildren;
-        final int N = mLayerState.mNum;
         boolean paddingChanged = false;
         boolean changed = false;
-        for (int i=0; i<N; i++) {
+
+        final ChildDrawable[] array = mLayerState.mChildren;
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
             final ChildDrawable r = array[i];
             if (r.mDrawable.setLevel(level)) {
                 changed = true;
             }
-            if (reapplyPadding(i, r)) {
+
+            if (refreshChildPadding(i, r)) {
                 paddingChanged = true;
             }
         }
+
         if (paddingChanged) {
-            onBoundsChange(getBounds());
+            invalidatePadding();
         }
+
         return changed;
     }
 
     @Override
     protected void onBoundsChange(Rect bounds) {
+        int padL = 0;
+        int padT = 0;
+        int padR = 0;
+        int padB = 0;
+
+        final boolean nest = mLayerState.mPaddingMode == PADDING_MODE_NEST;
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        int padL=0, padT=0, padR=0, padB=0;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             final ChildDrawable r = array[i];
-            r.mDrawable.setBounds(bounds.left + r.mInsetL + padL,
-                                  bounds.top + r.mInsetT + padT,
-                                  bounds.right - r.mInsetR - padR,
-                                  bounds.bottom - r.mInsetB - padB);
-            padL += mPaddingL[i];
-            padR += mPaddingR[i];
-            padT += mPaddingT[i];
-            padB += mPaddingB[i];
+            r.mDrawable.setBounds(bounds.left + r.mInsetL + padL, bounds.top + r.mInsetT + padT,
+                    bounds.right - r.mInsetR - padR, bounds.bottom - r.mInsetB - padB);
+
+            if (nest) {
+                padL += mPaddingL[i];
+                padR += mPaddingR[i];
+                padT += mPaddingT[i];
+                padB += mPaddingB[i];
+            }
         }
     }
 
     @Override
     public int getIntrinsicWidth() {
         int width = -1;
+        int padL = 0;
+        int padR = 0;
+
+        final boolean nest = mLayerState.mPaddingMode == PADDING_MODE_NEST;
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        int padL=0, padR=0;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             final ChildDrawable r = array[i];
-            int w = r.mDrawable.getIntrinsicWidth()
-                  + r.mInsetL + r.mInsetR + padL + padR;
+            final int w = r.mDrawable.getIntrinsicWidth() + r.mInsetL + r.mInsetR + padL + padR;
             if (w > width) {
                 width = w;
             }
-            padL += mPaddingL[i];
-            padR += mPaddingR[i];
+
+            if (nest) {
+                padL += mPaddingL[i];
+                padR += mPaddingR[i];
+            }
         }
+
         return width;
     }
 
     @Override
     public int getIntrinsicHeight() {
         int height = -1;
+        int padT = 0;
+        int padB = 0;
+
+        final boolean nest = mLayerState.mPaddingMode == PADDING_MODE_NEST;
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        int padT=0, padB=0;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             final ChildDrawable r = array[i];
-            int h = r.mDrawable.getIntrinsicHeight() + r.mInsetT + r.mInsetB + + padT + padB;
+            int h = r.mDrawable.getIntrinsicHeight() + r.mInsetT + r.mInsetB + padT + padB;
             if (h > height) {
                 height = h;
             }
-            padT += mPaddingT[i];
-            padB += mPaddingB[i];
+
+            if (nest) {
+                padT += mPaddingT[i];
+                padB += mPaddingB[i];
+            }
         }
+
         return height;
     }
 
-    private boolean reapplyPadding(int i, ChildDrawable r) {
+    /**
+     * Refreshes the cached padding values for the specified child.
+     *
+     * @return true if the child's padding has changed
+     */
+    private boolean refreshChildPadding(int i, ChildDrawable r) {
         final Rect rect = mTmpRect;
         r.mDrawable.getPadding(rect);
         if (rect.left != mPaddingL[i] || rect.top != mPaddingT[i] ||
@@ -582,11 +711,15 @@
         return false;
     }
 
+    /**
+     * Ensures the child padding caches are large enough.
+     */
     private void ensurePadding() {
         final int N = mLayerState.mNum;
         if (mPaddingL != null && mPaddingL.length >= N) {
             return;
         }
+
         mPaddingL = new int[N];
         mPaddingT = new int[N];
         mPaddingR = new int[N];
@@ -639,7 +772,7 @@
 
         int mChangingConfigurations;
         int mChildrenChangingConfigurations;
-        
+
         private boolean mHaveOpacity = false;
         private int mOpacity;
 
@@ -651,6 +784,8 @@
 
         private boolean mAutoMirrored;
 
+        private int mPaddingMode = PADDING_MODE_NEST;
+
         LayerState(LayerState orig, LayerDrawable owner, Resources res) {
             if (orig != null) {
                 final ChildDrawable[] origChildDrawable = orig.mChildren;
@@ -661,7 +796,7 @@
 
                 mChangingConfigurations = orig.mChangingConfigurations;
                 mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations;
-                
+
                 for (int i = 0; i < N; i++) {
                     final ChildDrawable r = mChildren[i] = new ChildDrawable();
                     final ChildDrawable or = origChildDrawable[i];
@@ -685,6 +820,7 @@
                 mStateful = orig.mStateful;
                 mCheckedConstantState = mCanConstantState = true;
                 mAutoMirrored = orig.mAutoMirrored;
+                mPaddingMode = orig.mPaddingMode;
             } else {
                 mNum = 0;
                 mChildren = null;
@@ -695,12 +831,12 @@
         public Drawable newDrawable() {
             return new LayerDrawable(this, null);
         }
-        
+
         @Override
         public Drawable newDrawable(Resources res) {
             return new LayerDrawable(this, res);
         }
-        
+
         @Override
         public int getChangingConfigurations() {
             return mChangingConfigurations;
@@ -720,12 +856,12 @@
             mHaveOpacity = true;
             return op;
         }
-        
+
         public final boolean isStateful() {
             if (mHaveStateful) {
                 return mStateful;
             }
-            
+
             boolean stateful = false;
             final int N = mNum;
             for (int i = 0; i < N; i++) {
@@ -734,7 +870,7 @@
                     break;
                 }
             }
-            
+
             mStateful = stateful;
             mHaveStateful = true;
             return stateful;
@@ -744,7 +880,7 @@
             if (!mCheckedConstantState && mChildren != null) {
                 mCanConstantState = true;
                 final int N = mNum;
-                for (int i=0; i<N; i++) {
+                for (int i = 0; i < N; i++) {
                     if (mChildren[i].mDrawable.getConstantState() == null) {
                         mCanConstantState = false;
                         break;
diff --git a/graphics/java/android/graphics/drawable/PictureDrawable.java b/graphics/java/android/graphics/drawable/PictureDrawable.java
index 1f5d4d8..cb2d8f6 100644
--- a/graphics/java/android/graphics/drawable/PictureDrawable.java
+++ b/graphics/java/android/graphics/drawable/PictureDrawable.java
@@ -16,16 +16,12 @@
 
 package android.graphics.drawable;
 
-import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
-import android.graphics.Matrix;
-import android.graphics.Matrix.ScaleToFit;
 import android.graphics.drawable.Drawable;
 import android.graphics.Picture;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
-import android.view.Gravity;
 
 /**
  * Drawable subclass that wraps a Picture, allowing the picture to be used
diff --git a/graphics/java/android/graphics/drawable/shapes/ArcShape.java b/graphics/java/android/graphics/drawable/shapes/ArcShape.java
index b90e853..84731b0 100644
--- a/graphics/java/android/graphics/drawable/shapes/ArcShape.java
+++ b/graphics/java/android/graphics/drawable/shapes/ArcShape.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Canvas;
 import android.graphics.Paint;
-import android.graphics.RectF;
 
 /**
  * Creates an arc shape. The arc shape starts at a specified
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index dca934f..45dd25a 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -16,17 +16,12 @@
 
 package android.renderscript;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.HashMap;
 import android.content.res.Resources;
-import android.content.res.AssetManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.view.Surface;
-import android.graphics.SurfaceTexture;
 import android.util.Log;
-import android.util.TypedValue;
 import android.graphics.Canvas;
 import android.os.Trace;
 
@@ -78,10 +73,69 @@
     int mCurrentDimY;
     int mCurrentDimZ;
     int mCurrentCount;
-    static HashMap<Integer, Allocation> mAllocationMap =
-            new HashMap<Integer, Allocation>();
+    static HashMap<Long, Allocation> mAllocationMap =
+            new HashMap<Long, Allocation>();
     OnBufferAvailableListener mBufferNotifier;
 
+    private Element.DataType validateObjectIsPrimitiveArray(Object d, boolean checkType) {
+        final Class c = d.getClass();
+        if (!c.isArray()) {
+            throw new RSIllegalArgumentException("Object passed is not an array of primitives.");
+        }
+        final Class cmp = c.getComponentType();
+        if (!cmp.isPrimitive()) {
+            throw new RSIllegalArgumentException("Object passed is not an Array of primitives.");
+        }
+
+        if (cmp == Long.TYPE) {
+            if (checkType) {
+                validateIsInt64();
+                return mType.mElement.mType;
+            }
+            return Element.DataType.SIGNED_64;
+        }
+
+        if (cmp == Integer.TYPE) {
+            if (checkType) {
+                validateIsInt32();
+                return mType.mElement.mType;
+            }
+            return Element.DataType.SIGNED_32;
+        }
+
+        if (cmp == Short.TYPE) {
+            if (checkType) {
+                validateIsInt16();
+                return mType.mElement.mType;
+            }
+            return Element.DataType.SIGNED_16;
+        }
+
+        if (cmp == Byte.TYPE) {
+            if (checkType) {
+                validateIsInt8();
+                return mType.mElement.mType;
+            }
+            return Element.DataType.SIGNED_8;
+        }
+
+        if (cmp == Float.TYPE) {
+            if (checkType) {
+                validateIsFloat32();
+            }
+            return Element.DataType.FLOAT_32;
+        }
+
+        if (cmp == Double.TYPE) {
+            if (checkType) {
+                validateIsFloat64();
+            }
+            return Element.DataType.FLOAT_64;
+        }
+        return null;
+    }
+
+
     /**
      * The usage of the Allocation.  These signal to RenderScript where to place
      * the Allocation in memory.
@@ -127,17 +181,17 @@
     public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
 
     /**
-     * The Allocation will be used as a {@link android.graphics.SurfaceTexture}
-     * consumer.  This usage will cause the Allocation to be created as
-     * read-only.
+     * The Allocation will be used as a {@link android.view.Surface}
+     * consumer.  This usage will cause the Allocation to be created
+     * as read-only.
      *
      */
     public static final int USAGE_IO_INPUT = 0x0020;
 
     /**
-     * The Allocation will be used as a {@link android.graphics.SurfaceTexture}
+     * The Allocation will be used as a {@link android.view.Surface}
      * producer.  The dimensions and format of the {@link
-     * android.graphics.SurfaceTexture} will be forced to those of the
+     * android.view.Surface} will be forced to those of the
      * Allocation.
      *
      */
@@ -188,7 +242,7 @@
     }
 
 
-    private int getIDSafe() {
+    private long getIDSafe() {
         if (mAdaptedAllocation != null) {
             return mAdaptedAllocation.getID(mRS);
         }
@@ -244,7 +298,7 @@
         mBitmap = b;
     }
 
-    Allocation(int id, RenderScript rs, Type t, int usage) {
+    Allocation(long id, RenderScript rs, Type t, int usage) {
         super(id, rs);
         if ((usage & ~(USAGE_SCRIPT |
                        USAGE_GRAPHICS_TEXTURE |
@@ -290,6 +344,15 @@
         super.finalize();
     }
 
+    private void validateIsInt64() {
+        if ((mType.mElement.mType == Element.DataType.SIGNED_64) ||
+            (mType.mElement.mType == Element.DataType.UNSIGNED_64)) {
+            return;
+        }
+        throw new RSIllegalArgumentException(
+            "64 bit integer source does not match allocation type " + mType.mElement.mType);
+    }
+
     private void validateIsInt32() {
         if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
             (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
@@ -325,6 +388,14 @@
             "32 bit float source does not match allocation type " + mType.mElement.mType);
     }
 
+    private void validateIsFloat64() {
+        if (mType.mElement.mType == Element.DataType.FLOAT_64) {
+            return;
+        }
+        throw new RSIllegalArgumentException(
+            "64 bit float source does not match allocation type " + mType.mElement.mType);
+    }
+
     private void validateIsObject() {
         if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
             (mType.mElement.mType == Element.DataType.RS_TYPE) ||
@@ -345,7 +416,7 @@
     @Override
     void updateFromNative() {
         super.updateFromNative();
-        int typeID = mRS.nAllocationGetType(getID(mRS));
+        long typeID = mRS.nAllocationGetType(getID(mRS));
         if(typeID != 0) {
             mType = new Type(typeID, mRS);
             mType.updateFromNative();
@@ -412,14 +483,6 @@
     }
 
     /**
-     * Delete once code is updated.
-     * @hide
-     */
-    public void ioSendOutput() {
-        ioSend();
-    }
-
-    /**
      * Receive the latest input into the Allocation. This operation
      * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation.
      *
@@ -448,9 +511,11 @@
             throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
                                                  mCurrentCount + ", array length = " + d.length);
         }
+        // FIXME: requires 64-bit path
+
         int i[] = new int[d.length];
         for (int ct=0; ct < d.length; ct++) {
-            i[ct] = d[ct].getID(mRS);
+            i[ct] = (int)d[ct].getID(mRS);
         }
         copy1DRangeFromUnchecked(0, mCurrentCount, i);
         Trace.traceEnd(RenderScript.TRACE_TAG);
@@ -511,6 +576,33 @@
         }
     }
 
+    private void copyFromUnchecked(Object array, Element.DataType dt, int arrayLen) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
+        mRS.validate();
+        if (mCurrentDimZ > 0) {
+            copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, array, dt, arrayLen);
+        } else if (mCurrentDimY > 0) {
+            copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, array, dt, arrayLen);
+        } else {
+            copy1DRangeFromUnchecked(0, mCurrentCount, array, dt, arrayLen);
+        }
+        Trace.traceEnd(RenderScript.TRACE_TAG);
+    }
+
+    /**
+     * Copy into this Allocation from an array. This method does not guarantee
+     * that the Allocation is compatible with the input buffer; it copies memory
+     * without reinterpretation.
+     *
+     * @param array The source data array
+     */
+    public void copyFromUnchecked(Object array) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
+        copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, false),
+                          java.lang.reflect.Array.getLength(array));
+        Trace.traceEnd(RenderScript.TRACE_TAG);
+    }
+
     /**
      * Copy into this Allocation from an array. This method does not guarantee
      * that the Allocation is compatible with the input buffer; it copies memory
@@ -519,16 +611,7 @@
      * @param d the source data array
      */
     public void copyFromUnchecked(int[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
-        mRS.validate();
-        if (mCurrentDimZ > 0) {
-            copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
-        } else if (mCurrentDimY > 0) {
-            copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
-        } else {
-            copy1DRangeFromUnchecked(0, mCurrentCount, d);
-        }
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
     }
 
     /**
@@ -539,16 +622,7 @@
      * @param d the source data array
      */
     public void copyFromUnchecked(short[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
-        mRS.validate();
-        if (mCurrentDimZ > 0) {
-            copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
-        } else if (mCurrentDimY > 0) {
-            copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
-        } else {
-            copy1DRangeFromUnchecked(0, mCurrentCount, d);
-        }
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
     }
 
     /**
@@ -559,16 +633,7 @@
      * @param d the source data array
      */
     public void copyFromUnchecked(byte[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
-        mRS.validate();
-        if (mCurrentDimZ > 0) {
-            copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
-        } else if (mCurrentDimY > 0) {
-            copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
-        } else {
-            copy1DRangeFromUnchecked(0, mCurrentCount, d);
-        }
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
     }
 
     /**
@@ -579,37 +644,35 @@
      * @param d the source data array
      */
     public void copyFromUnchecked(float[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
-        mRS.validate();
-        if (mCurrentDimZ > 0) {
-            copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
-        } else if (mCurrentDimY > 0) {
-            copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
-        } else {
-            copy1DRangeFromUnchecked(0, mCurrentCount, d);
-        }
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
     }
 
 
     /**
      * Copy into this Allocation from an array.  This variant is type checked
      * and will generate exceptions if the Allocation's {@link
+     * android.renderscript.Element} does not match the array's
+     * primitive type.
+     *
+     * @param array The source data array
+     */
+    public void copyFrom(Object array) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
+        copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, true),
+                          java.lang.reflect.Array.getLength(array));
+        Trace.traceEnd(RenderScript.TRACE_TAG);
+    }
+
+    /**
+     * Copy into this Allocation from an array.  This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
      * android.renderscript.Element} is not a 32 bit integer type.
      *
      * @param d the source data array
      */
     public void copyFrom(int[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
-        mRS.validate();
-        if (mCurrentDimZ > 0) {
-            copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
-        } else if (mCurrentDimY > 0) {
-            copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
-        } else {
-            copy1DRangeFrom(0, mCurrentCount, d);
-        }
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        validateIsInt32();
+        copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
     }
 
     /**
@@ -620,16 +683,8 @@
      * @param d the source data array
      */
     public void copyFrom(short[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
-        mRS.validate();
-        if (mCurrentDimZ > 0) {
-            copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
-        } else if (mCurrentDimY > 0) {
-            copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
-        } else {
-            copy1DRangeFrom(0, mCurrentCount, d);
-        }
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        validateIsInt16();
+        copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
     }
 
     /**
@@ -640,16 +695,8 @@
      * @param d the source data array
      */
     public void copyFrom(byte[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
-        mRS.validate();
-        if (mCurrentDimZ > 0) {
-            copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
-        } else if (mCurrentDimY > 0) {
-            copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
-        } else {
-            copy1DRangeFrom(0, mCurrentCount, d);
-        }
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        validateIsInt8();
+        copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
     }
 
     /**
@@ -660,16 +707,8 @@
      * @param d the source data array
      */
     public void copyFrom(float[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
-        mRS.validate();
-        if (mCurrentDimZ > 0) {
-            copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
-        } else if (mCurrentDimY > 0) {
-            copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
-        } else {
-            copy1DRangeFrom(0, mCurrentCount, d);
-        }
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        validateIsFloat32();
+        copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
     }
 
     /**
@@ -798,6 +837,29 @@
         mRS.nAllocationGenerateMipmaps(getID(mRS));
     }
 
+    private void copy1DRangeFromUnchecked(int off, int count, Object array,
+                                          Element.DataType dt, int arrayLen) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
+        final int dataSize = mType.mElement.getBytesSize() * count;
+        data1DChecks(off, count, arrayLen * dt.mSize, dataSize);
+        mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
+    }
+
+    /**
+     * Copy an array into part of this Allocation.  This method does not
+     * guarantee that the Allocation is compatible with the input buffer.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param array The source data array
+     */
+    public void copy1DRangeFromUnchecked(int off, int count, Object array) {
+        copy1DRangeFromUnchecked(off, count, array,
+                                 validateObjectIsPrimitiveArray(array, false),
+                                 java.lang.reflect.Array.getLength(array));
+    }
+
     /**
      * Copy an array into part of this Allocation.  This method does not
      * guarantee that the Allocation is compatible with the input buffer.
@@ -807,11 +869,7 @@
      * @param d the source data array
      */
     public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
-        int dataSize = mType.mElement.getBytesSize() * count;
-        data1DChecks(off, count, d.length * 4, dataSize);
-        mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
     }
 
     /**
@@ -823,11 +881,7 @@
      * @param d the source data array
      */
     public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
-        int dataSize = mType.mElement.getBytesSize() * count;
-        data1DChecks(off, count, d.length * 2, dataSize);
-        mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
     }
 
     /**
@@ -839,11 +893,7 @@
      * @param d the source data array
      */
     public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
-        int dataSize = mType.mElement.getBytesSize() * count;
-        data1DChecks(off, count, d.length, dataSize);
-        mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
     }
 
     /**
@@ -855,11 +905,23 @@
      * @param d the source data array
      */
     public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
-        int dataSize = mType.mElement.getBytesSize() * count;
-        data1DChecks(off, count, d.length * 4, dataSize);
-        mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
+    }
+
+
+    /**
+     * Copy an array into part of this Allocation.  This variant is type checked
+     * and will generate exceptions if the Allocation type does not
+     * match the component type of the array passed in.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param array The source data array.
+     */
+    public void copy1DRangeFrom(int off, int count, Object array) {
+        copy1DRangeFromUnchecked(off, count, array,
+                                 validateObjectIsPrimitiveArray(array, true),
+                                 java.lang.reflect.Array.getLength(array));
     }
 
     /**
@@ -872,10 +934,8 @@
      * @param d the source data array
      */
     public void copy1DRangeFrom(int off, int count, int[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
         validateIsInt32();
-        copy1DRangeFromUnchecked(off, count, d);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
     }
 
     /**
@@ -888,10 +948,8 @@
      * @param d the source data array
      */
     public void copy1DRangeFrom(int off, int count, short[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
         validateIsInt16();
-        copy1DRangeFromUnchecked(off, count, d);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
     }
 
     /**
@@ -904,10 +962,8 @@
      * @param d the source data array
      */
     public void copy1DRangeFrom(int off, int count, byte[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
         validateIsInt8();
-        copy1DRangeFromUnchecked(off, count, d);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
     }
 
     /**
@@ -920,11 +976,10 @@
      * @param d the source data array.
      */
     public void copy1DRangeFrom(int off, int count, float[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
         validateIsFloat32();
-        copy1DRangeFromUnchecked(off, count, d);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copy1DRangeFromUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
     }
+
      /**
      * Copy part of an Allocation into this Allocation.
      *
@@ -959,39 +1014,31 @@
         }
     }
 
-    void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, byte[] data) {
+    void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, Object array,
+                                  Element.DataType dt, int arrayLen) {
         Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
-        mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
-                              w, h, data, data.length);
+        mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
+                              array, arrayLen * dt.mSize, dt);
         Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
-    void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, short[] data) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
-        mRS.validate();
-        validate2DRange(xoff, yoff, w, h);
-        mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
-                              w, h, data, data.length * 2);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
-    }
-
-    void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, int[] data) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
-        mRS.validate();
-        validate2DRange(xoff, yoff, w, h);
-        mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
-                              w, h, data, data.length * 4);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
-    }
-
-    void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, float[] data) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
-        mRS.validate();
-        validate2DRange(xoff, yoff, w, h);
-        mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
-                              w, h, data, data.length * 4);
+    /**
+     * Copy from an array into a rectangular region in this Allocation.  The
+     * array is assumed to be tightly packed.
+     *
+     * @param xoff X offset of the region to update in this Allocation
+     * @param yoff Y offset of the region to update in this Allocation
+     * @param w Width of the region to update
+     * @param h Height of the region to update
+     * @param array Data to be placed into the Allocation
+     */
+    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
+        copy2DRangeFromUnchecked(xoff, yoff, w, h, array,
+                                 validateObjectIsPrimitiveArray(array, true),
+                                 java.lang.reflect.Array.getLength(array));
         Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
@@ -1006,10 +1053,9 @@
      * @param data to be placed into the Allocation
      */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
         validateIsInt8();
-        copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
+                                 Element.DataType.SIGNED_8, data.length);
     }
 
     /**
@@ -1023,10 +1069,9 @@
      * @param data to be placed into the Allocation
      */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
         validateIsInt16();
-        copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
+                                 Element.DataType.SIGNED_16, data.length);
     }
 
     /**
@@ -1040,10 +1085,9 @@
      * @param data to be placed into the Allocation
      */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
         validateIsInt32();
-        copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
+                                 Element.DataType.SIGNED_32, data.length);
     }
 
     /**
@@ -1057,10 +1101,9 @@
      * @param data to be placed into the Allocation
      */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
         validateIsFloat32();
-        copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
+                                 Element.DataType.FLOAT_32, data.length);
     }
 
     /**
@@ -1133,49 +1176,18 @@
      * @hide
      *
      */
-    void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, byte[] data) {
+    private void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
+                                          Object array, Element.DataType dt, int arrayLen) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFromUnchecked");
         mRS.validate();
         validate3DRange(xoff, yoff, zoff, w, h, d);
-        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
-                              w, h, d, data, data.length);
+        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
+                              array, arrayLen * dt.mSize, dt);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
      * @hide
-     *
-     */
-    void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, short[] data) {
-        mRS.validate();
-        validate3DRange(xoff, yoff, zoff, w, h, d);
-        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
-                              w, h, d, data, data.length * 2);
-    }
-
-    /**
-     * @hide
-     *
-     */
-    void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, int[] data) {
-        mRS.validate();
-        validate3DRange(xoff, yoff, zoff, w, h, d);
-        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
-                              w, h, d, data, data.length * 4);
-    }
-
-    /**
-     * @hide
-     *
-     */
-    void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, float[] data) {
-        mRS.validate();
-        validate3DRange(xoff, yoff, zoff, w, h, d);
-        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
-                              w, h, d, data, data.length * 4);
-    }
-
-
-    /**
-     * @hide
      * Copy a rectangular region from the array into the allocation.
      * The array is assumed to be tightly packed.
      *
@@ -1187,36 +1199,12 @@
      * @param d Depth of the region to update
      * @param data to be placed into the allocation
      */
-    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, byte[] data) {
-        validateIsInt8();
-        copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data);
-    }
-
-    /**
-     * @hide
-     *
-     */
-    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, short[] data) {
-        validateIsInt16();
-        copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data);
-    }
-
-    /**
-     * @hide
-     *
-     */
-    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, int[] data) {
-        validateIsInt32();
-        copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data);
-    }
-
-    /**
-     * @hide
-     *
-     */
-    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, float[] data) {
-        validateIsFloat32();
-        copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data);
+    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFrom");
+        copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, array,
+                                 validateObjectIsPrimitiveArray(array, true),
+                                 java.lang.reflect.Array.getLength(array));
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -1260,6 +1248,26 @@
         Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
+    private void copyTo(Object array, Element.DataType dt, int arrayLen) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
+        mRS.validate();
+        mRS.nAllocationRead(getID(mRS), array, dt);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
+    }
+
+    /**
+     * Copy from the Allocation into an array.  The array must be at
+     * least as large as the Allocation.  The
+     * {@link android.renderscript.Element} must match the component
+     * type of the array passed in.
+     *
+     * @param array The array to be set from the Allocation.
+     */
+    public void copyTo(Object array) {
+        copyTo(array, validateObjectIsPrimitiveArray(array, true),
+               java.lang.reflect.Array.getLength(array));
+    }
+
     /**
      * Copy from the Allocation into a byte array.  The array must be at least
      * as large as the Allocation.  The allocation must be of an 8 bit integer
@@ -1268,11 +1276,8 @@
      * @param d The array to be set from the Allocation.
      */
     public void copyTo(byte[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
         validateIsInt8();
-        mRS.validate();
-        mRS.nAllocationRead(getID(mRS), d);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copyTo(d, Element.DataType.SIGNED_8, d.length);
     }
 
     /**
@@ -1283,11 +1288,8 @@
      * @param d The array to be set from the Allocation.
      */
     public void copyTo(short[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
         validateIsInt16();
-        mRS.validate();
-        mRS.nAllocationRead(getID(mRS), d);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copyTo(d, Element.DataType.SIGNED_16, d.length);
     }
 
     /**
@@ -1298,11 +1300,8 @@
      * @param d The array to be set from the Allocation.
      */
     public void copyTo(int[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
         validateIsInt32();
-        mRS.validate();
-        mRS.nAllocationRead(getID(mRS), d);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copyTo(d, Element.DataType.SIGNED_32, d.length);
     }
 
     /**
@@ -1313,11 +1312,8 @@
      * @param d The array to be set from the Allocation.
      */
     public void copyTo(float[] d) {
-        Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
         validateIsFloat32();
-        mRS.validate();
-        mRS.nAllocationRead(getID(mRS), d);
-        Trace.traceEnd(RenderScript.TRACE_TAG);
+        copyTo(d, Element.DataType.FLOAT_32, d.length);
     }
 
     /**
@@ -1342,7 +1338,7 @@
         mRS.nAllocationResize1D(getID(mRS), dimX);
         mRS.finish();  // Necessary because resize is fifoed and update is async.
 
-        int typeID = mRS.nAllocationGetType(getID(mRS));
+        long typeID = mRS.nAllocationGetType(getID(mRS));
         mType = new Type(typeID, mRS);
         mType.updateFromNative();
         updateCacheInfo(mType);
@@ -1372,7 +1368,7 @@
         if (type.getID(rs) == 0) {
             throw new RSInvalidStateException("Bad Type");
         }
-        int id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
+        long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
         if (id == 0) {
             throw new RSRuntimeException("Allocation creation failed.");
         }
@@ -1427,7 +1423,7 @@
         b.setX(count);
         Type t = b.create();
 
-        int id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
+        long id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
         if (id == 0) {
             throw new RSRuntimeException("Allocation creation failed.");
         }
@@ -1511,7 +1507,7 @@
         if (mips == MipmapControl.MIPMAP_NONE &&
             t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
             usage == (USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE)) {
-            int id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
+            long id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
             if (id == 0) {
                 throw new RSRuntimeException("Load failed.");
             }
@@ -1523,7 +1519,7 @@
         }
 
 
-        int id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
+        long id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
         if (id == 0) {
             throw new RSRuntimeException("Load failed.");
         }
@@ -1547,13 +1543,6 @@
     }
 
     /**
-     * @hide
-     */
-    public void setSurfaceTexture(SurfaceTexture st) {
-        setSurface(new Surface(st));
-    }
-
-    /**
      * Associate a {@link android.view.Surface} with this Allocation. This
      * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}.
      *
@@ -1633,7 +1622,7 @@
         tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
         Type t = tb.create();
 
-        int id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
+        long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
         if(id == 0) {
             throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
         }
@@ -1858,14 +1847,14 @@
      */
     public void setOnBufferAvailableListener(OnBufferAvailableListener callback) {
         synchronized(mAllocationMap) {
-            mAllocationMap.put(new Integer(getID(mRS)), this);
+            mAllocationMap.put(new Long(getID(mRS)), this);
             mBufferNotifier = callback;
         }
     }
 
     static void sendBufferNotification(int id) {
         synchronized(mAllocationMap) {
-            Allocation a = mAllocationMap.get(new Integer(id));
+            Allocation a = mAllocationMap.get(new Long(id));
 
             if ((a != null) && (a.mBufferNotifier != null)) {
                 a.mBufferNotifier.onBufferAvailable(a);
@@ -1874,4 +1863,3 @@
     }
 
 }
-
diff --git a/graphics/java/android/renderscript/AllocationAdapter.java b/graphics/java/android/renderscript/AllocationAdapter.java
index a6645bb..6c1b1ed 100644
--- a/graphics/java/android/renderscript/AllocationAdapter.java
+++ b/graphics/java/android/renderscript/AllocationAdapter.java
@@ -16,22 +16,17 @@
 
 package android.renderscript;
 
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.util.TypedValue;
-
 /**
  * Only intended for use by generated reflected code.
  *
  **/
 public class AllocationAdapter extends Allocation {
-    AllocationAdapter(int id, RenderScript rs, Allocation alloc) {
+    AllocationAdapter(long id, RenderScript rs, Allocation alloc) {
         super(id, rs, alloc.mType, alloc.mUsage);
         mAdaptedAllocation = alloc;
     }
 
-    int getID(RenderScript rs) {
+    long getID(RenderScript rs) {
         throw new RSInvalidStateException(
             "This operation is not supported with adapters at this time.");
     }
diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java
index e17d79a..1a15ce6 100644
--- a/graphics/java/android/renderscript/BaseObj.java
+++ b/graphics/java/android/renderscript/BaseObj.java
@@ -16,8 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
-
 /**
  * BaseObj is the base class for all RenderScript objects owned by a RS context.
  * It is responsible for lifetime management and resource tracking. This class
@@ -25,7 +23,7 @@
  *
  **/
 public class BaseObj {
-    BaseObj(int id, RenderScript rs) {
+    BaseObj(long id, RenderScript rs) {
         rs.validate();
         mRS = rs;
         mID = id;
@@ -46,9 +44,9 @@
      * @param rs Context to verify against internal context for
      *           match.
      *
-     * @return int
+     * @return long
      */
-    int getID(RenderScript rs) {
+    long getID(RenderScript rs) {
         mRS.validate();
         if (mDestroyed) {
             throw new RSInvalidStateException("using a destroyed object.");
@@ -68,7 +66,7 @@
         }
     }
 
-    private int mID;
+    private long mID;
     private boolean mDestroyed;
     private String mName;
     RenderScript mRS;
@@ -152,7 +150,7 @@
      */
     @Override
     public int hashCode() {
-        return mID;
+        return (int)((mID & 0xfffffff) ^ (mID >> 32));
     }
 
     /**
diff --git a/graphics/java/android/renderscript/Byte2.java b/graphics/java/android/renderscript/Byte2.java
index cf34f3a..3ad79e4 100644
--- a/graphics/java/android/renderscript/Byte2.java
+++ b/graphics/java/android/renderscript/Byte2.java
@@ -16,15 +16,15 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
 
 /**
  * Class for exposing the native RenderScript byte2 type back to the Android system.
  *
  **/
 public class Byte2 {
+    public byte x;
+    public byte y;
+
     public Byte2() {
     }
 
@@ -33,8 +33,357 @@
         y = initY;
     }
 
-    public byte x;
-    public byte y;
+    /** @hide */
+    public Byte2(Byte2 source) {
+        this.x = source.x;
+        this.y = source.y;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     */
+    public void add(Byte2 a) {
+        this.x += a.x;
+        this.y += a.y;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte2 add(Byte2 a, Byte2 b) {
+        Byte2 result = new Byte2();
+        result.x = (byte)(a.x + b.x);
+        result.y = (byte)(a.y + b.y);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(byte value) {
+        x += value;
+        y += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte2 add(Byte2 a, byte b) {
+        Byte2 result = new Byte2();
+        result.x = (byte)(a.x + b);
+        result.y = (byte)(a.y + b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     */
+    public void sub(Byte2 a) {
+        this.x -= a.x;
+        this.y -= a.y;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte2 sub(Byte2 a, Byte2 b) {
+        Byte2 result = new Byte2();
+        result.x = (byte)(a.x - b.x);
+        result.y = (byte)(a.y - b.y);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(byte value) {
+        x -= value;
+        y -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte2 sub(Byte2 a, byte b) {
+        Byte2 result = new Byte2();
+        result.x = (byte)(a.x - b);
+        result.y = (byte)(a.y - b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     */
+    public void mul(Byte2 a) {
+        this.x *= a.x;
+        this.y *= a.y;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte2 mul(Byte2 a, Byte2 b) {
+        Byte2 result = new Byte2();
+        result.x = (byte)(a.x * b.x);
+        result.y = (byte)(a.y * b.y);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(byte value) {
+        x *= value;
+        y *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte2 mul(Byte2 a, byte b) {
+        Byte2 result = new Byte2();
+        result.x = (byte)(a.x * b);
+        result.y = (byte)(a.y * b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     */
+    public void div(Byte2 a) {
+        this.x /= a.x;
+        this.y /= a.y;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte2 div(Byte2 a, Byte2 b) {
+        Byte2 result = new Byte2();
+        result.x = (byte)(a.x / b.x);
+        result.y = (byte)(a.y / b.y);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(byte value) {
+        x /= value;
+        y /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte2 div(Byte2 a, byte b) {
+        Byte2 result = new Byte2();
+        result.x = (byte)(a.x / b);
+        result.y = (byte)(a.y / b);
+
+        return result;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public byte length() {
+        return 2;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        this.x = (byte)(-x);
+        this.y = (byte)(-y);
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public byte dotProduct(Byte2 a) {
+        return (byte)((x * a.x) + (y * a.y));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static byte dotProduct(Byte2 a, Byte2 b) {
+        return (byte)((b.x * a.x) + (b.y * a.y));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Byte2 a, byte factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+    }
+
+    /** @hide
+     * set vector value by Byte2
+     *
+     * @param a
+     */
+    public void set(Byte2 a) {
+        this.x = a.x;
+        this.y = a.y;
+    }
+
+    /** @hide
+     * set the vector field value by Char
+     *
+     * @param a
+     * @param b
+     */
+    public void setValues(byte a, byte b) {
+        this.x = a;
+        this.y = b;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public byte elementSum() {
+        return (byte)(x + y);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public byte get(int i) {
+        switch (i) {
+        case 0:
+            return x;
+        case 1:
+            return y;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, byte value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, byte value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * copy the vector to Char array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(byte[] data, int offset) {
+        data[offset] = x;
+        data[offset + 1] = y;
+    }
+
 }
 
 
diff --git a/graphics/java/android/renderscript/Byte3.java b/graphics/java/android/renderscript/Byte3.java
index 266e94d..a138313 100644
--- a/graphics/java/android/renderscript/Byte3.java
+++ b/graphics/java/android/renderscript/Byte3.java
@@ -16,15 +16,16 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
 
 /**
  * Class for exposing the native RenderScript byte3 type back to the Android system.
  *
  **/
 public class Byte3 {
+    public byte x;
+    public byte y;
+    public byte z;
+
     public Byte3() {
     }
 
@@ -34,9 +35,387 @@
         z = initZ;
     }
 
-    public byte x;
-    public byte y;
-    public byte z;
+    /** @hide */
+    public Byte3(Byte3 source) {
+        this.x = source.x;
+        this.y = source.y;
+        this.z = source.z;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     */
+    public void add(Byte3 a) {
+        this.x += a.x;
+        this.y += a.y;
+        this.z += a.z;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte3 add(Byte3 a, Byte3 b) {
+        Byte3 result = new Byte3();
+        result.x = (byte)(a.x + b.x);
+        result.y = (byte)(a.y + b.y);
+        result.z = (byte)(a.z + b.z);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(byte value) {
+        x += value;
+        y += value;
+        z += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte3 add(Byte3 a, byte b) {
+        Byte3 result = new Byte3();
+        result.x = (byte)(a.x + b);
+        result.y = (byte)(a.y + b);
+        result.z = (byte)(a.z + b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     */
+    public void sub(Byte3 a) {
+        this.x -= a.x;
+        this.y -= a.y;
+        this.z -= a.z;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte3 sub(Byte3 a, Byte3 b) {
+        Byte3 result = new Byte3();
+        result.x = (byte)(a.x - b.x);
+        result.y = (byte)(a.y - b.y);
+        result.z = (byte)(a.z - b.z);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(byte value) {
+        x -= value;
+        y -= value;
+        z -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte3 sub(Byte3 a, byte b) {
+        Byte3 result = new Byte3();
+        result.x = (byte)(a.x - b);
+        result.y = (byte)(a.y - b);
+        result.z = (byte)(a.z - b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     */
+    public void mul(Byte3 a) {
+        this.x *= a.x;
+        this.y *= a.y;
+        this.z *= a.z;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte3 mul(Byte3 a, Byte3 b) {
+        Byte3 result = new Byte3();
+        result.x = (byte)(a.x * b.x);
+        result.y = (byte)(a.y * b.y);
+        result.z = (byte)(a.z * b.z);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(byte value) {
+        x *= value;
+        y *= value;
+        z *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte3 mul(Byte3 a, byte b) {
+        Byte3 result = new Byte3();
+        result.x = (byte)(a.x * b);
+        result.y = (byte)(a.y * b);
+        result.z = (byte)(a.z * b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     */
+    public void div(Byte3 a) {
+        this.x /= a.x;
+        this.y /= a.y;
+        this.z /= a.z;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte3 div(Byte3 a, Byte3 b) {
+        Byte3 result = new Byte3();
+        result.x = (byte)(a.x / b.x);
+        result.y = (byte)(a.y / b.y);
+        result.z = (byte)(a.z / b.z);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(byte value) {
+        x /= value;
+        y /= value;
+        z /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte3 div(Byte3 a, byte b) {
+        Byte3 result = new Byte3();
+        result.x = (byte)(a.x / b);
+        result.y = (byte)(a.y / b);
+        result.z = (byte)(a.z / b);
+
+        return result;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public byte length() {
+        return 3;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        this.x = (byte)(-x);
+        this.y = (byte)(-y);
+        this.z = (byte)(-z);
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public byte dotProduct(Byte3 a) {
+        return (byte)((byte)((byte)(x * a.x) + (byte)(y * a.y)) + (byte)(z * a.z));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static byte dotProduct(Byte3 a, Byte3 b) {
+        return (byte)((byte)((byte)(b.x * a.x) + (byte)(b.y * a.y)) + (byte)(b.z * a.z));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Byte3 a, byte factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+        z += a.z * factor;
+    }
+
+    /** @hide
+     * set vector value by Byte3
+     *
+     * @param a
+     */
+    public void set(Byte3 a) {
+        this.x = a.x;
+        this.y = a.y;
+        this.z = a.z;
+    }
+
+    /** @hide
+     * set the vector field value by Char
+     *
+     * @param a
+     * @param b
+     * @param c
+     */
+    public void setValues(byte a, byte b, byte c) {
+        this.x = a;
+        this.y = b;
+        this.z = c;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public byte elementSum() {
+        return (byte)(x + y + z);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public byte get(int i) {
+        switch (i) {
+        case 0:
+            return x;
+        case 1:
+            return y;
+        case 2:
+            return z;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, byte value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        case 2:
+            z = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, byte value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        case 2:
+            z += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * copy the vector to Char array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(byte[] data, int offset) {
+        data[offset] = x;
+        data[offset + 1] = y;
+        data[offset + 2] = z;
+    }
 }
 
 
diff --git a/graphics/java/android/renderscript/Byte4.java b/graphics/java/android/renderscript/Byte4.java
index 68c8f52..fa4c13d 100644
--- a/graphics/java/android/renderscript/Byte4.java
+++ b/graphics/java/android/renderscript/Byte4.java
@@ -16,15 +16,17 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
 
 /**
  * Class for exposing the native RenderScript byte4 type back to the Android system.
  *
  **/
 public class Byte4 {
+    public byte x;
+    public byte y;
+    public byte z;
+    public byte w;
+
     public Byte4() {
     }
 
@@ -34,11 +36,418 @@
         z = initZ;
         w = initW;
     }
+    /** @hide */
+    public Byte4(Byte4 source) {
+        this.x = source.x;
+        this.y = source.y;
+        this.z = source.z;
+        this.w = source.w;
+    }
 
-    public byte x;
-    public byte y;
-    public byte z;
-    public byte w;
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     */
+    public void add(Byte4 a) {
+        this.x += a.x;
+        this.y += a.y;
+        this.z += a.z;
+        this.w += a.w;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte4 add(Byte4 a, Byte4 b) {
+        Byte4 result = new Byte4();
+        result.x = (byte)(a.x + b.x);
+        result.y = (byte)(a.y + b.y);
+        result.z = (byte)(a.z + b.z);
+        result.w = (byte)(a.w + b.w);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(byte value) {
+        x += value;
+        y += value;
+        z += value;
+        w += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte4 add(Byte4 a, byte b) {
+        Byte4 result = new Byte4();
+        result.x = (byte)(a.x + b);
+        result.y = (byte)(a.y + b);
+        result.z = (byte)(a.z + b);
+        result.w = (byte)(a.w + b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     */
+    public void sub(Byte4 a) {
+        this.x -= a.x;
+        this.y -= a.y;
+        this.z -= a.z;
+        this.w -= a.w;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte4 sub(Byte4 a, Byte4 b) {
+        Byte4 result = new Byte4();
+        result.x = (byte)(a.x - b.x);
+        result.y = (byte)(a.y - b.y);
+        result.z = (byte)(a.z - b.z);
+        result.w = (byte)(a.w - b.w);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(byte value) {
+        x -= value;
+        y -= value;
+        z -= value;
+        w -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte4 sub(Byte4 a, byte b) {
+        Byte4 result = new Byte4();
+        result.x = (byte)(a.x - b);
+        result.y = (byte)(a.y - b);
+        result.z = (byte)(a.z - b);
+        result.w = (byte)(a.w - b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     */
+    public void mul(Byte4 a) {
+        this.x *= a.x;
+        this.y *= a.y;
+        this.z *= a.z;
+        this.w *= a.w;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte4 mul(Byte4 a, Byte4 b) {
+        Byte4 result = new Byte4();
+        result.x = (byte)(a.x * b.x);
+        result.y = (byte)(a.y * b.y);
+        result.z = (byte)(a.z * b.z);
+        result.w = (byte)(a.w * b.w);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(byte value) {
+        x *= value;
+        y *= value;
+        z *= value;
+        w *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte4 mul(Byte4 a, byte b) {
+        Byte4 result = new Byte4();
+        result.x = (byte)(a.x * b);
+        result.y = (byte)(a.y * b);
+        result.z = (byte)(a.z * b);
+        result.w = (byte)(a.w * b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     */
+    public void div(Byte4 a) {
+        this.x /= a.x;
+        this.y /= a.y;
+        this.z /= a.z;
+        this.w /= a.w;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte4 div(Byte4 a, Byte4 b) {
+        Byte4 result = new Byte4();
+        result.x = (byte)(a.x / b.x);
+        result.y = (byte)(a.y / b.y);
+        result.z = (byte)(a.z / b.z);
+        result.w = (byte)(a.w / b.w);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(byte value) {
+        x /= value;
+        y /= value;
+        z /= value;
+        w /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Byte4 div(Byte4 a, byte b) {
+        Byte4 result = new Byte4();
+        result.x = (byte)(a.x / b);
+        result.y = (byte)(a.y / b);
+        result.z = (byte)(a.z / b);
+        result.w = (byte)(a.w / b);
+
+        return result;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public byte length() {
+        return 4;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        this.x = (byte)(-x);
+        this.y = (byte)(-y);
+        this.z = (byte)(-z);
+        this.w = (byte)(-w);
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public byte dotProduct(Byte4 a) {
+        return (byte)((x * a.x) + (y * a.y) + (z * a.z) + (w * a.w));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static byte dotProduct(Byte4 a, Byte4 b) {
+        return (byte)((b.x * a.x) + (b.y * a.y) + (b.z * a.z) + (b.w * a.w));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Byte4 a, byte factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+        z += a.z * factor;
+        w += a.w * factor;
+    }
+
+    /** @hide
+     * set vector value by Byte4
+     *
+     * @param a
+     */
+    public void set(Byte4 a) {
+        this.x = a.x;
+        this.y = a.y;
+        this.z = a.z;
+        this.w = a.w;
+    }
+
+    /** @hide
+     * set the vector field values
+     *
+     * @param a
+     * @param b
+     * @param c
+     * @param d
+     */
+    public void setValues(byte a, byte b, byte c, byte d) {
+        this.x = a;
+        this.y = b;
+        this.z = c;
+        this.w = d;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public byte elementSum() {
+        return (byte)(x + y + z + w);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public byte get(int i) {
+        switch (i) {
+        case 0:
+            return x;
+        case 1:
+            return y;
+        case 2:
+            return z;
+        case 3:
+            return w;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, byte value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        case 2:
+            z = value;
+            return;
+        case 3:
+            w = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, byte value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        case 2:
+            z += value;
+            return;
+        case 3:
+            w += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * copy the vector to Char array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(byte[] data, int offset) {
+        data[offset] = x;
+        data[offset + 1] = y;
+        data[offset + 2] = z;
+        data[offset + 3] = w;
+    }
 }
 
 
diff --git a/graphics/java/android/renderscript/Double2.java b/graphics/java/android/renderscript/Double2.java
index 29fd515..4c7319d 100644
--- a/graphics/java/android/renderscript/Double2.java
+++ b/graphics/java/android/renderscript/Double2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * 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.
@@ -16,28 +16,370 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript double2 type back
- * to the Android system.
- *
- **/
+ * Vector version of the basic double type.
+ * Provides two double fields packed.
+ */
 public class Double2 {
+    public double x;
+    public double y;
+
     public Double2() {
     }
 
-    public Double2(double initX, double initY) {
-        x = initX;
-        y = initY;
+    /** @hide */
+    public Double2(Double2 data) {
+        this.x = data.x;
+        this.y = data.y;
     }
 
-    public double x;
-    public double y;
+    public Double2(double x, double y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double2 add(Double2 a, Double2 b) {
+        Double2 res = new Double2();
+        res.x = a.x + b.x;
+        res.y = a.y + b.y;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(Double2 value) {
+        x += value.x;
+        y += value.y;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(double value) {
+        x += value;
+        y += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double2 add(Double2 a, double b) {
+        Double2 res = new Double2();
+        res.x = a.x + b;
+        res.y = a.y + b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(Double2 value) {
+        x -= value.x;
+        y -= value.y;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double2 sub(Double2 a, Double2 b) {
+        Double2 res = new Double2();
+        res.x = a.x - b.x;
+        res.y = a.y - b.y;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(double value) {
+        x -= value;
+        y -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double2 sub(Double2 a, double b) {
+        Double2 res = new Double2();
+        res.x = a.x - b;
+        res.y = a.y - b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(Double2 value) {
+        x *= value.x;
+        y *= value.y;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double2 mul(Double2 a, Double2 b) {
+        Double2 res = new Double2();
+        res.x = a.x * b.x;
+        res.y = a.y * b.y;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(double value) {
+        x *= value;
+        y *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double2 mul(Double2 a, double b) {
+        Double2 res = new Double2();
+        res.x = a.x * b;
+        res.y = a.y * b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(Double2 value) {
+        x /= value.x;
+        y /= value.y;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double2 div(Double2 a, Double2 b) {
+        Double2 res = new Double2();
+        res.x = a.x / b.x;
+        res.y = a.y / b.y;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(double value) {
+        x /= value;
+        y /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double2 div(Double2 a, double b) {
+        Double2 res = new Double2();
+        res.x = a.x / b;
+        res.y = a.y / b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public double dotProduct(Double2 a) {
+        return (x * a.x) + (y * a.y);
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double dotProduct(Double2 a, Double2 b) {
+        return (b.x * a.x) + (b.y * a.y);
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Double2 a, double factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+    }
+
+    /** @hide
+     * Set vector value by double2
+     *
+     * @param a
+     */
+    public void set(Double2 a) {
+        this.x = a.x;
+        this.y = a.y;
+    }
+
+    /** @hide
+     * Set vector negate
+     */
+    public void negate() {
+        x = -x;
+        y = -y;
+    }
+
+    /** @hide
+     * Get vector length
+     *
+     * @return
+     */
+    public int length() {
+        return 2;
+    }
+
+    /** @hide
+     * Return the element sum of vector
+     *
+     * @return
+     */
+    public double elementSum() {
+        return x + y;
+    }
+
+    /** @hide
+     * Get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public double get(int i) {
+        switch (i) {
+        case 0:
+            return x;
+        case 1:
+            return y;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * Set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, double value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * Add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, double value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * Set the vector field value
+     *
+     * @param x
+     * @param y
+     */
+    public void setValues(double x, double y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /** @hide
+     * Copy the vector to double array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(double[] data, int offset) {
+        data[offset] = x;
+        data[offset + 1] = y;
+    }
 }
-
-
-
-
diff --git a/graphics/java/android/renderscript/Double3.java b/graphics/java/android/renderscript/Double3.java
index 818952e..b819716 100644
--- a/graphics/java/android/renderscript/Double3.java
+++ b/graphics/java/android/renderscript/Double3.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * 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.
@@ -16,30 +16,402 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript double3 type back
- * to the Android system.
- *
- **/
+ * Vector version of the basic double type.
+ * Provides three double fields packed.
+ */
 public class Double3 {
-    public Double3() {
-    }
-
-    public Double3(double initX, double initY, double initZ) {
-        x = initX;
-        y = initY;
-        z = initZ;
-    }
-
     public double x;
     public double y;
     public double z;
+
+    public Double3() {
+    }
+    /** @hide */
+    public Double3(Double3 data) {
+        this.x = data.x;
+        this.y = data.y;
+        this.z = data.z;
+    }
+
+    public Double3(double x, double y, double z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double3 add(Double3 a, Double3 b) {
+        Double3 res = new Double3();
+        res.x = a.x + b.x;
+        res.y = a.y + b.y;
+        res.z = a.z + b.z;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(Double3 value) {
+        x += value.x;
+        y += value.y;
+        z += value.z;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(double value) {
+        x += value;
+        y += value;
+        z += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double3 add(Double3 a, double b) {
+        Double3 res = new Double3();
+        res.x = a.x + b;
+        res.y = a.y + b;
+        res.z = a.z + b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(Double3 value) {
+        x -= value.x;
+        y -= value.y;
+        z -= value.z;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double3 sub(Double3 a, Double3 b) {
+        Double3 res = new Double3();
+        res.x = a.x - b.x;
+        res.y = a.y - b.y;
+        res.z = a.z - b.z;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(double value) {
+        x -= value;
+        y -= value;
+        z -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double3 sub(Double3 a, double b) {
+        Double3 res = new Double3();
+        res.x = a.x - b;
+        res.y = a.y - b;
+        res.z = a.z - b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(Double3 value) {
+        x *= value.x;
+        y *= value.y;
+        z *= value.z;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double3 mul(Double3 a, Double3 b) {
+        Double3 res = new Double3();
+        res.x = a.x * b.x;
+        res.y = a.y * b.y;
+        res.z = a.z * b.z;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(double value) {
+        x *= value;
+        y *= value;
+        z *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double3 mul(Double3 a, double b) {
+        Double3 res = new Double3();
+        res.x = a.x * b;
+        res.y = a.y * b;
+        res.z = a.z * b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(Double3 value) {
+        x /= value.x;
+        y /= value.y;
+        z /= value.z;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double3 div(Double3 a, Double3 b) {
+        Double3 res = new Double3();
+        res.x = a.x / b.x;
+        res.y = a.y / b.y;
+        res.z = a.z / b.z;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(double value) {
+        x /= value;
+        y /= value;
+        z /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double3 div(Double3 a, double b) {
+        Double3 res = new Double3();
+        res.x = a.x / b;
+        res.y = a.y / b;
+        res.z = a.z / b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public double dotProduct(Double3 a) {
+        return (x * a.x) + (y * a.y) + (z * a.z);
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static double dotProduct(Double3 a, Double3 b) {
+        return (b.x * a.x) + (b.y * a.y) + (b.z * a.z);
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Double3 a, double factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+        z += a.z * factor;
+    }
+
+    /** @hide
+     * Set vector value by double3
+     *
+     * @param a
+     */
+    public void set(Double3 a) {
+        this.x = a.x;
+        this.y = a.y;
+        this.z = a.z;
+    }
+
+    /** @hide
+     * Set vector negate
+     */
+    public void negate() {
+        x = -x;
+        y = -y;
+        z = -z;
+    }
+
+    /** @hide
+     * Get vector length
+     *
+     * @return
+     */
+    public int length() {
+        return 3;
+    }
+
+    /** @hide
+     * Return the element sum of vector
+     *
+     * @return
+     */
+    public double elementSum() {
+        return x + y + z;
+    }
+
+    /** @hide
+     * Get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public double get(int i) {
+        switch (i) {
+        case 0:
+            return x;
+        case 1:
+            return y;
+        case 2:
+            return z;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * Set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, double value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        case 2:
+            z = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * Add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, double value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        case 2:
+            z += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * Set the vector field value
+     *
+     * @param x
+     * @param y
+     * @param z
+     */
+    public void setValues(double x, double y, double z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    /** @hide
+     * Copy the vector to double array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(double[] data, int offset) {
+        data[offset] = x;
+        data[offset + 1] = y;
+        data[offset + 2] = z;
+    }
 }
-
-
-
-
diff --git a/graphics/java/android/renderscript/Double4.java b/graphics/java/android/renderscript/Double4.java
index 7775ab7..e4829f7 100644
--- a/graphics/java/android/renderscript/Double4.java
+++ b/graphics/java/android/renderscript/Double4.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * 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.
@@ -16,31 +16,435 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript double4 type back
- * to the Android system.
- *
- **/
+ * Vector version of the basic double type.
+ * Provides four double fields packed.
+ */
 public class Double4 {
-    public Double4() {
-    }
-
-    public Double4(double initX, double initY, double initZ, double initW) {
-        x = initX;
-        y = initY;
-        z = initZ;
-        w = initW;
-    }
-
     public double x;
     public double y;
     public double z;
     public double w;
+
+    public Double4() {
+    }
+    /** @hide */
+    public Double4(Double4 data) {
+        this.x = data.x;
+        this.y = data.y;
+        this.z = data.z;
+        this.w = data.w;
+    }
+
+    public Double4(double x, double y, double z, double w) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        this.w = w;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double4 add(Double4 a, Double4 b) {
+        Double4 res = new Double4();
+        res.x = a.x + b.x;
+        res.y = a.y + b.y;
+        res.z = a.z + b.z;
+        res.w = a.w + b.w;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(Double4 value) {
+        x += value.x;
+        y += value.y;
+        z += value.z;
+        w += value.w;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(double value) {
+        x += value;
+        y += value;
+        z += value;
+        w += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double4 add(Double4 a, double b) {
+        Double4 res = new Double4();
+        res.x = a.x + b;
+        res.y = a.y + b;
+        res.z = a.z + b;
+        res.w = a.w + b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(Double4 value) {
+        x -= value.x;
+        y -= value.y;
+        z -= value.z;
+        w -= value.w;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(double value) {
+        x -= value;
+        y -= value;
+        z -= value;
+        w -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double4 sub(Double4 a, double b) {
+        Double4 res = new Double4();
+        res.x = a.x - b;
+        res.y = a.y - b;
+        res.z = a.z - b;
+        res.w = a.w - b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double4 sub(Double4 a, Double4 b) {
+        Double4 res = new Double4();
+        res.x = a.x - b.x;
+        res.y = a.y - b.y;
+        res.z = a.z - b.z;
+        res.w = a.w - b.w;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(Double4 value) {
+        x *= value.x;
+        y *= value.y;
+        z *= value.z;
+        w *= value.w;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(double value) {
+        x *= value;
+        y *= value;
+        z *= value;
+        w *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double4 mul(Double4 a, Double4 b) {
+        Double4 res = new Double4();
+        res.x = a.x * b.x;
+        res.y = a.y * b.y;
+        res.z = a.z * b.z;
+        res.w = a.w * b.w;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double4 mul(Double4 a, double b) {
+        Double4 res = new Double4();
+        res.x = a.x * b;
+        res.y = a.y * b;
+        res.z = a.z * b;
+        res.w = a.w * b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(Double4 value) {
+        x /= value.x;
+        y /= value.y;
+        z /= value.z;
+        w /= value.w;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(double value) {
+        x /= value;
+        y /= value;
+        z /= value;
+        w /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double4 div(Double4 a, double b) {
+        Double4 res = new Double4();
+        res.x = a.x / b;
+        res.y = a.y / b;
+        res.z = a.z / b;
+        res.w = a.w / b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Double4 div(Double4 a, Double4 b) {
+        Double4 res = new Double4();
+        res.x = a.x / b.x;
+        res.y = a.y / b.y;
+        res.z = a.z / b.z;
+        res.w = a.w / b.w;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public double dotProduct(Double4 a) {
+        return (x * a.x) + (y * a.y) + (z * a.z) + (w * a.w);
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static double dotProduct(Double4 a, Double4 b) {
+        return (b.x * a.x) + (b.y * a.y) + (b.z * a.z) + (b.w * a.w);
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Double4 a, double factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+        z += a.z * factor;
+        w += a.w * factor;
+    }
+
+    /** @hide
+     * Set vector value by double4
+     *
+     * @param a
+     */
+    public void set(Double4 a) {
+        this.x = a.x;
+        this.y = a.y;
+        this.z = a.z;
+        this.w = a.w;
+    }
+
+    /** @hide
+     * Set vector negate
+     */
+    public void negate() {
+        x = -x;
+        y = -y;
+        z = -z;
+        w = -w;
+    }
+
+    /** @hide
+     * Get vector length
+     *
+     * @return
+     */
+    public int length() {
+        return 4;
+    }
+
+    /** @hide
+     * Return the element sum of vector
+     *
+     * @return
+     */
+    public double elementSum() {
+        return x + y + z + w;
+    }
+
+    /** @hide
+     * Get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public double get(int i) {
+        switch (i) {
+        case 0:
+            return x;
+        case 1:
+            return y;
+        case 2:
+            return z;
+        case 3:
+            return w;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * Set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, double value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        case 2:
+            z = value;
+            return;
+        case 3:
+            w = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * Add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, double value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        case 2:
+            z += value;
+            return;
+        case 3:
+            w += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * Set the vector field value
+     *
+     * @param x
+     * @param y
+     * @param z
+     * @param w
+     */
+    public void setValues(double x, double y, double z, double w) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        this.w = w;
+    }
+
+    /** @hide
+     * Copy the vector to double array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(double[] data, int offset) {
+        data[offset] = x;
+        data[offset + 1] = y;
+        data[offset + 2] = z;
+        data[offset + 3] = w;
+    }
 }
-
-
-
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 68badfa..93e839e 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -16,9 +16,6 @@
 
 package android.renderscript;
 
-import java.lang.reflect.Field;
-import android.util.Log;
-
 /**
  * <p>An Element represents one item within an {@link
  * android.renderscript.Allocation}.  An Element is roughly equivalent to a C
@@ -759,7 +756,7 @@
         return rs.mElement_MATRIX_2X2;
     }
 
-    Element(int id, RenderScript rs, Element[] e, String[] n, int[] as) {
+    Element(long id, RenderScript rs, Element[] e, String[] n, int[] as) {
         super(id, rs);
         mSize = 0;
         mVectorSize = 1;
@@ -776,7 +773,7 @@
         updateVisibleSubElements();
     }
 
-    Element(int id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
+    Element(long id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
         super(id, rs);
         if ((dt != DataType.UNSIGNED_5_6_5) &&
             (dt != DataType.UNSIGNED_4_4_4_4) &&
@@ -795,7 +792,7 @@
         mVectorSize = size;
     }
 
-    Element(int id, RenderScript rs) {
+    Element(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -803,6 +800,8 @@
     void updateFromNative() {
         super.updateFromNative();
 
+        // FIXME: updateFromNative is broken in JNI for 64-bit
+
         // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
         int[] dataBuffer = new int[5];
         mRS.nElementGetNativeData(getID(mRS), dataBuffer);
@@ -853,7 +852,7 @@
         DataKind dk = DataKind.USER;
         boolean norm = false;
         int vecSize = 1;
-        int id = rs.nElementCreate(dt.mID, dk.mID, norm, vecSize);
+        long id = rs.nElementCreate(dt.mID, dk.mID, norm, vecSize);
         return new Element(id, rs, dt, dk, norm, vecSize);
     }
 
@@ -890,7 +889,7 @@
         case BOOLEAN: {
             DataKind dk = DataKind.USER;
             boolean norm = false;
-            int id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
+            long id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
             return new Element(id, rs, dt, dk, norm, size);
         }
 
@@ -961,7 +960,7 @@
         }
 
         boolean norm = true;
-        int id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
+        long id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
         return new Element(id, rs, dt, dk, norm, size);
     }
 
@@ -1088,11 +1087,12 @@
             java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount);
             java.lang.System.arraycopy(mArraySizes, 0, asin, 0, mCount);
 
+            // FIXME: broken for 64-bit
             int[] ids = new int[ein.length];
             for (int ct = 0; ct < ein.length; ct++ ) {
-                ids[ct] = ein[ct].getID(mRS);
+                ids[ct] = (int)ein[ct].getID(mRS);
             }
-            int id = mRS.nElementCreate2(ids, sin, asin);
+            long id = mRS.nElementCreate2(ids, sin, asin);
             return new Element(id, mRS, ein, sin, asin);
         }
     }
diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java
index fed97d6..723ab24 100644
--- a/graphics/java/android/renderscript/FieldPacker.java
+++ b/graphics/java/android/renderscript/FieldPacker.java
@@ -16,7 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
 import java.util.BitSet;
 
 /**
@@ -232,7 +231,8 @@
 
     public void addObj(BaseObj obj) {
         if (obj != null) {
-            addI32(obj.getID(null));
+            // FIXME: this is fine for 32-bit but needs a path for 64-bit
+            addI32((int)obj.getID(null));
         } else {
             addI32(0);
         }
diff --git a/graphics/java/android/renderscript/FileA3D.java b/graphics/java/android/renderscript/FileA3D.java
index e41f02d..f0acb56 100644
--- a/graphics/java/android/renderscript/FileA3D.java
+++ b/graphics/java/android/renderscript/FileA3D.java
@@ -17,15 +17,10 @@
 package android.renderscript;
 
 import java.io.File;
-import java.io.IOException;
 import java.io.InputStream;
 
 import android.content.res.AssetManager;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.util.Log;
-import android.util.TypedValue;
 
 /**
  * @hide
@@ -80,7 +75,7 @@
     public static class IndexEntry {
         RenderScript mRS;
         int mIndex;
-        int mID;
+        long mID;
         String mName;
         EntryType mEntryType;
         BaseObj mLoadedObj;
@@ -156,7 +151,7 @@
             return entry.mLoadedObj;
         }
 
-        IndexEntry(RenderScript rs, int index, int id, String name, EntryType type) {
+        IndexEntry(RenderScript rs, int index, long id, String name, EntryType type) {
             mRS = rs;
             mIndex = index;
             mID = id;
@@ -169,7 +164,7 @@
     IndexEntry[] mFileEntries;
     InputStream mInputStream;
 
-    FileA3D(int id, RenderScript rs, InputStream stream) {
+    FileA3D(long id, RenderScript rs, InputStream stream) {
         super(id, rs);
         mInputStream = stream;
     }
@@ -232,7 +227,7 @@
     */
     static public FileA3D createFromAsset(RenderScript rs, AssetManager mgr, String path) {
         rs.validate();
-        int fileId = rs.nFileA3DCreateFromAsset(mgr, path);
+        long fileId = rs.nFileA3DCreateFromAsset(mgr, path);
 
         if(fileId == 0) {
             throw new RSRuntimeException("Unable to create a3d file from asset " + path);
@@ -252,7 +247,7 @@
     * @return a3d file containing renderscript objects
     */
     static public FileA3D createFromFile(RenderScript rs, String path) {
-        int fileId = rs.nFileA3DCreateFromFile(path);
+        long fileId = rs.nFileA3DCreateFromFile(path);
 
         if(fileId == 0) {
             throw new RSRuntimeException("Unable to create a3d file from " + path);
@@ -295,7 +290,7 @@
             throw new RSRuntimeException("Unable to open resource " + id);
         }
 
-        int fileId = 0;
+        long fileId = 0;
         if (is instanceof AssetManager.AssetInputStream) {
             int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
             fileId = rs.nFileA3DCreateFromAssetStream(asset);
diff --git a/graphics/java/android/renderscript/Float2.java b/graphics/java/android/renderscript/Float2.java
index 0f730fe..e9f8ca7 100644
--- a/graphics/java/android/renderscript/Float2.java
+++ b/graphics/java/android/renderscript/Float2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -16,27 +16,369 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript float2 type back to the Android system.
- *
- **/
-public class Float2 {
-    public Float2() {
-    }
-
-    public Float2(float initX, float initY) {
-        x = initX;
-        y = initY;
-    }
-
+ * Vector version of the basic float type.
+ * Provides two float fields packed.
+ */
+public  class Float2 {
     public float x;
     public float y;
+
+    public Float2() {
+    }
+    /** @hide */
+    public Float2(Float2 data) {
+        this.x = data.x;
+        this.y = data.y;
+    }
+
+    public Float2(float x, float y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float2 add(Float2 a, Float2 b) {
+        Float2 res = new Float2();
+        res.x = a.x + b.x;
+        res.y = a.y + b.y;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(Float2 value) {
+        x += value.x;
+        y += value.y;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(float value) {
+        x += value;
+        y += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float2 add(Float2 a, float b) {
+        Float2 res = new Float2();
+        res.x = a.x + b;
+        res.y = a.y + b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(Float2 value) {
+        x -= value.x;
+        y -= value.y;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float2 sub(Float2 a, Float2 b) {
+        Float2 res = new Float2();
+        res.x = a.x - b.x;
+        res.y = a.y - b.y;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(float value) {
+        x -= value;
+        y -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float2 sub(Float2 a, float b) {
+        Float2 res = new Float2();
+        res.x = a.x - b;
+        res.y = a.y - b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(Float2 value) {
+        x *= value.x;
+        y *= value.y;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float2 mul(Float2 a, Float2 b) {
+        Float2 res = new Float2();
+        res.x = a.x * b.x;
+        res.y = a.y * b.y;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(float value) {
+        x *= value;
+        y *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float2 mul(Float2 a, float b) {
+        Float2 res = new Float2();
+        res.x = a.x * b;
+        res.y = a.y * b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(Float2 value) {
+        x /= value.x;
+        y /= value.y;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float2 div(Float2 a, Float2 b) {
+        Float2 res = new Float2();
+        res.x = a.x / b.x;
+        res.y = a.y / b.y;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(float value) {
+        x /= value;
+        y /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float2 div(Float2 a, float b) {
+        Float2 res = new Float2();
+        res.x = a.x / b;
+        res.y = a.y / b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public float dotProduct(Float2 a) {
+        return (x * a.x) + (y * a.y);
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static float dotProduct(Float2 a, Float2 b) {
+        return (b.x * a.x) + (b.y * a.y);
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Float2 a, float factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+    }
+
+    /** @hide
+     * set vector value by float2
+     *
+     * @param a
+     */
+    public void set(Float2 a) {
+        this.x = a.x;
+        this.y = a.y;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        x = -x;
+        y = -y;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public int length() {
+        return 2;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public float elementSum() {
+        return x + y;
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public float get(int i) {
+        switch (i) {
+        case 0:
+            return x;
+        case 1:
+            return y;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, float value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, float value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value
+     *
+     * @param x
+     * @param y
+     */
+    public void setValues(float x, float y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /** @hide
+     * copy the vector to float array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(float[] data, int offset) {
+        data[offset] = x;
+        data[offset + 1] = y;
+    }
 }
-
-
-
-
diff --git a/graphics/java/android/renderscript/Float3.java b/graphics/java/android/renderscript/Float3.java
index 749865f1..555bdf6 100644
--- a/graphics/java/android/renderscript/Float3.java
+++ b/graphics/java/android/renderscript/Float3.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -16,28 +16,402 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript float2 type back to the Android system.
- *
- **/
+ * Vector version of the basic float type.
+ * Provides three float fields packed.
+ */
 public class Float3 {
-    public Float3() {
-    }
-    public Float3(float initX, float initY, float initZ) {
-        x = initX;
-        y = initY;
-        z = initZ;
-    }
-
     public float x;
     public float y;
     public float z;
+
+    public Float3() {
+    }
+    /** @hide */
+    public Float3(Float3 data) {
+        this.x = data.x;
+        this.y = data.y;
+        this.z = data.z;
+    }
+
+    public Float3(float x, float y, float z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float3 add(Float3 a, Float3 b) {
+        Float3 res = new Float3();
+        res.x = a.x + b.x;
+        res.y = a.y + b.y;
+        res.z = a.z + b.z;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(Float3 value) {
+        x += value.x;
+        y += value.y;
+        z += value.z;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(float value) {
+        x += value;
+        y += value;
+        z += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float3 add(Float3 a, float b) {
+        Float3 res = new Float3();
+        res.x = a.x + b;
+        res.y = a.y + b;
+        res.z = a.z + b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(Float3 value) {
+        x -= value.x;
+        y -= value.y;
+        z -= value.z;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float3 sub(Float3 a, Float3 b) {
+        Float3 res = new Float3();
+        res.x = a.x - b.x;
+        res.y = a.y - b.y;
+        res.z = a.z - b.z;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(float value) {
+        x -= value;
+        y -= value;
+        z -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float3 sub(Float3 a, float b) {
+        Float3 res = new Float3();
+        res.x = a.x - b;
+        res.y = a.y - b;
+        res.z = a.z - b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(Float3 value) {
+        x *= value.x;
+        y *= value.y;
+        z *= value.z;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float3 mul(Float3 a, Float3 b) {
+        Float3 res = new Float3();
+        res.x = a.x * b.x;
+        res.y = a.y * b.y;
+        res.z = a.z * b.z;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(float value) {
+        x *= value;
+        y *= value;
+        z *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float3 mul(Float3 a, float b) {
+        Float3 res = new Float3();
+        res.x = a.x * b;
+        res.y = a.y * b;
+        res.z = a.z * b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(Float3 value) {
+        x /= value.x;
+        y /= value.y;
+        z /= value.z;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float3 div(Float3 a, Float3 b) {
+        Float3 res = new Float3();
+        res.x = a.x / b.x;
+        res.y = a.y / b.y;
+        res.z = a.z / b.z;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(float value) {
+        x /= value;
+        y /= value;
+        z /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float3 div(Float3 a, float b) {
+        Float3 res = new Float3();
+        res.x = a.x / b;
+        res.y = a.y / b;
+        res.z = a.z / b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public Float dotProduct(Float3 a) {
+        return new Float((x * a.x) + (y * a.y) + (z * a.z));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float dotProduct(Float3 a, Float3 b) {
+        return new Float((b.x * a.x) + (b.y * a.y) + (b.z * a.z));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Float3 a, float factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+        z += a.z * factor;
+    }
+
+    /** @hide
+     * set vector value by float3
+     *
+     * @param a
+     */
+    public void set(Float3 a) {
+        this.x = a.x;
+        this.y = a.y;
+        this.z = a.z;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        x = -x;
+        y = -y;
+        z = -z;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public int length() {
+        return 3;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public Float elementSum() {
+        return new Float(x + y + z);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public float get(int i) {
+        switch (i) {
+        case 0:
+            return x;
+        case 1:
+            return y;
+        case 2:
+            return z;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, float value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        case 2:
+            z = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, float value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        case 2:
+            z += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value
+     *
+     * @param x
+     * @param y
+     * @param z
+     */
+    public void setValues(float x, float y, float z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    /** @hide
+     * copy the vector to float array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(float[] data, int offset) {
+        data[offset] = x;
+        data[offset + 1] = y;
+        data[offset + 2] = z;
+    }
 }
-
-
-
-
diff --git a/graphics/java/android/renderscript/Float4.java b/graphics/java/android/renderscript/Float4.java
index 7ddf6aa..6541b2e 100644
--- a/graphics/java/android/renderscript/Float4.java
+++ b/graphics/java/android/renderscript/Float4.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -16,30 +16,435 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript float2 type back to the Android system.
- *
- **/
+ * Vector version of the basic float type.
+ * Provides four float fields packed.
+ */
 public class Float4 {
-    public Float4() {
-    }
-
-    public Float4(float initX, float initY, float initZ, float initW) {
-        x = initX;
-        y = initY;
-        z = initZ;
-        w = initW;
-    }
-
     public float x;
     public float y;
     public float z;
     public float w;
+
+    public Float4() {
+    }
+    /** @hide */
+    public Float4(Float4 data) {
+        this.x = data.x;
+        this.y = data.y;
+        this.z = data.z;
+        this.w = data.w;
+    }
+
+    public Float4(float x, float y, float z, float w) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        this.w = w;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float4 add(Float4 a, Float4 b) {
+        Float4 res = new Float4();
+        res.x = a.x + b.x;
+        res.y = a.y + b.y;
+        res.z = a.z + b.z;
+        res.w = a.w + b.w;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(Float4 value) {
+        x += value.x;
+        y += value.y;
+        z += value.z;
+        w += value.w;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(float value) {
+        x += value;
+        y += value;
+        z += value;
+        w += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float4 add(Float4 a, float b) {
+        Float4 res = new Float4();
+        res.x = a.x + b;
+        res.y = a.y + b;
+        res.z = a.z + b;
+        res.w = a.w + b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(Float4 value) {
+        x -= value.x;
+        y -= value.y;
+        z -= value.z;
+        w -= value.w;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(float value) {
+        x -= value;
+        y -= value;
+        z -= value;
+        w -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float4 sub(Float4 a, float b) {
+        Float4 res = new Float4();
+        res.x = a.x - b;
+        res.y = a.y - b;
+        res.z = a.z - b;
+        res.w = a.w - b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float4 sub(Float4 a, Float4 b) {
+        Float4 res = new Float4();
+        res.x = a.x - b.x;
+        res.y = a.y - b.y;
+        res.z = a.z - b.z;
+        res.w = a.w - b.w;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(Float4 value) {
+        x *= value.x;
+        y *= value.y;
+        z *= value.z;
+        w *= value.w;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(float value) {
+        x *= value;
+        y *= value;
+        z *= value;
+        w *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float4 mul(Float4 a, Float4 b) {
+        Float4 res = new Float4();
+        res.x = a.x * b.x;
+        res.y = a.y * b.y;
+        res.z = a.z * b.z;
+        res.w = a.w * b.w;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float4 mul(Float4 a, float b) {
+        Float4 res = new Float4();
+        res.x = a.x * b;
+        res.y = a.y * b;
+        res.z = a.z * b;
+        res.w = a.w * b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(Float4 value) {
+        x /= value.x;
+        y /= value.y;
+        z /= value.z;
+        w /= value.w;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(float value) {
+        x /= value;
+        y /= value;
+        z /= value;
+        w /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float4 div(Float4 a, float b) {
+        Float4 res = new Float4();
+        res.x = a.x / b;
+        res.y = a.y / b;
+        res.z = a.z / b;
+        res.w = a.w / b;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Float4 div(Float4 a, Float4 b) {
+        Float4 res = new Float4();
+        res.x = a.x / b.x;
+        res.y = a.y / b.y;
+        res.z = a.z / b.z;
+        res.w = a.w / b.w;
+
+        return res;
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public float dotProduct(Float4 a) {
+        return (x * a.x) + (y * a.y) + (z * a.z) + (w * a.w);
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static float dotProduct(Float4 a, Float4 b) {
+        return (b.x * a.x) + (b.y * a.y) + (b.z * a.z) + (b.w * a.w);
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Float4 a, float factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+        z += a.z * factor;
+        w += a.w * factor;
+    }
+
+    /** @hide
+     * set vector value by float4
+     *
+     * @param a
+     */
+    public void set(Float4 a) {
+        this.x = a.x;
+        this.y = a.y;
+        this.z = a.z;
+        this.w = a.w;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        x = -x;
+        y = -y;
+        z = -z;
+        w = -w;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public int length() {
+        return 4;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public float elementSum() {
+        return x + y + z + w;
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public float get(int i) {
+        switch (i) {
+        case 0:
+            return x;
+        case 1:
+            return y;
+        case 2:
+            return z;
+        case 3:
+            return w;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, float value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        case 2:
+            z = value;
+            return;
+        case 3:
+            w = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, float value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        case 2:
+            z += value;
+            return;
+        case 3:
+            w += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value
+     *
+     * @param x
+     * @param y
+     * @param z
+     * @param w
+     */
+    public void setValues(float x, float y, float z, float w) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        this.w = w;
+    }
+
+    /** @hide
+     * copy the vector to float array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(float[] data, int offset) {
+        data[offset] = x;
+        data[offset + 1] = y;
+        data[offset + 2] = z;
+        data[offset + 3] = w;
+    }
 }
-
-
-
diff --git a/graphics/java/android/renderscript/Font.java b/graphics/java/android/renderscript/Font.java
index 0375d2b..4cd89db 100644
--- a/graphics/java/android/renderscript/Font.java
+++ b/graphics/java/android/renderscript/Font.java
@@ -17,7 +17,6 @@
 package android.renderscript;
 
 import java.io.File;
-import java.io.IOException;
 import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
@@ -26,8 +25,6 @@
 
 import android.content.res.AssetManager;
 import android.content.res.Resources;
-import android.util.Log;
-import android.util.TypedValue;
 
 /**
  * @hide
diff --git a/graphics/java/android/renderscript/Int2.java b/graphics/java/android/renderscript/Int2.java
index 71b5dd5..120957b 100644
--- a/graphics/java/android/renderscript/Int2.java
+++ b/graphics/java/android/renderscript/Int2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -16,27 +16,425 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript int2 type back to the Android system.
- *
- **/
+ * Vector version of the basic int type.
+ * Provides two int fields packed.
+ */
 public class Int2 {
+    public int x;
+    public int y;
+
     public Int2() {
     }
 
-    public Int2(int initX, int initY) {
-        x = initX;
-        y = initY;
+    /** @hide */
+    public Int2(int i) {
+        this.x = this.y = i;
     }
 
-    public int x;
-    public int y;
+    public Int2(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /** @hide */
+    public Int2(Int2 source) {
+        this.x = source.x;
+        this.y = source.y;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     */
+    public void add(Int2 a) {
+        this.x += a.x;
+        this.y += a.y;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int2 add(Int2 a, Int2 b) {
+        Int2 result = new Int2();
+        result.x = a.x + b.x;
+        result.y = a.y + b.y;
+
+        return result;
+    }
+
+    /**  @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(int value) {
+        x += value;
+        y += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int2 add(Int2 a, int b) {
+        Int2 result = new Int2();
+        result.x = a.x + b;
+        result.y = a.y + b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     */
+    public void sub(Int2 a) {
+        this.x -= a.x;
+        this.y -= a.y;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int2 sub(Int2 a, Int2 b) {
+        Int2 result = new Int2();
+        result.x = a.x - b.x;
+        result.y = a.y - b.y;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(int value) {
+        x -= value;
+        y -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int2 sub(Int2 a, int b) {
+        Int2 result = new Int2();
+        result.x = a.x - b;
+        result.y = a.y - b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     */
+    public void mul(Int2 a) {
+        this.x *= a.x;
+        this.y *= a.y;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int2 mul(Int2 a, Int2 b) {
+        Int2 result = new Int2();
+        result.x = a.x * b.x;
+        result.y = a.y * b.y;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(int value) {
+        x *= value;
+        y *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int2 mul(Int2 a, int b) {
+        Int2 result = new Int2();
+        result.x = a.x * b;
+        result.y = a.y * b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     */
+    public void div(Int2 a) {
+        this.x /= a.x;
+        this.y /= a.y;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int2 div(Int2 a, Int2 b) {
+        Int2 result = new Int2();
+        result.x = a.x / b.x;
+        result.y = a.y / b.y;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(int value) {
+        x /= value;
+        y /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int2 div(Int2 a, int b) {
+        Int2 result = new Int2();
+        result.x = a.x / b;
+        result.y = a.y / b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     */
+    public void mod(Int2 a) {
+        this.x %= a.x;
+        this.y %= a.y;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int2 mod(Int2 a, Int2 b) {
+        Int2 result = new Int2();
+        result.x = a.x % b.x;
+        result.y = a.y % b.y;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param value
+     */
+    public void mod(int value) {
+        x %= value;
+        y %= value;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int2 mod(Int2 a, int b) {
+        Int2 result = new Int2();
+        result.x = a.x % b;
+        result.y = a.y % b;
+
+        return result;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public int length() {
+        return 2;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        this.x = -x;
+        this.y = -y;
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public int dotProduct(Int2 a) {
+        return (int)((x * a.x) + (y * a.y));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static int dotProduct(Int2 a, Int2 b) {
+        return (int)((b.x * a.x) + (b.y * a.y));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Int2 a, int factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+    }
+
+    /** @hide
+     * set vector value by Int2
+     *
+     * @param a
+     */
+    public void set(Int2 a) {
+        this.x = a.x;
+        this.y = a.y;
+    }
+
+    /** @hide
+     * set the vector field value by Int
+     *
+     * @param a
+     * @param b
+     */
+    public void setValues(int a, int b) {
+        this.x = a;
+        this.y = b;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public int elementSum() {
+        return (int)(x + y);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public int get(int i) {
+        switch (i) {
+        case 0:
+            return (int)(x);
+        case 1:
+            return (int)(y);
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, int value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, int value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * copy the vector to int array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(int[] data, int offset) {
+        data[offset] = (int)(x);
+        data[offset + 1] = (int)(y);
+    }
 }
-
-
-
-
diff --git a/graphics/java/android/renderscript/Int3.java b/graphics/java/android/renderscript/Int3.java
index 719c908..5431b9a7 100644
--- a/graphics/java/android/renderscript/Int3.java
+++ b/graphics/java/android/renderscript/Int3.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -16,29 +16,462 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript int3 type back to the Android system.
- *
- **/
+ * Vector version of the basic int type.
+ * Provides three int fields packed.
+ */
 public class Int3 {
-    public Int3() {
-    }
-
-    public Int3(int initX, int initY, int initZ) {
-        x = initX;
-        y = initY;
-        z = initZ;
-    }
-
     public int x;
     public int y;
     public int z;
+
+    public Int3() {
+    }
+
+    /** @hide */
+    public Int3(int i) {
+        this.x = this.y = this.z = i;
+    }
+
+    public Int3(int x, int y, int z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    /** @hide */
+    public Int3(Int3 source) {
+        this.x = source.x;
+        this.y = source.y;
+        this.z = source.z;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     */
+    public void add(Int3 a) {
+        this.x += a.x;
+        this.y += a.y;
+        this.z += a.z;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int3 add(Int3 a, Int3 b) {
+        Int3 result = new Int3();
+        result.x = a.x + b.x;
+        result.y = a.y + b.y;
+        result.z = a.z + b.z;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(int value) {
+        x += value;
+        y += value;
+        z += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int3 add(Int3 a, int b) {
+        Int3 result = new Int3();
+        result.x = a.x + b;
+        result.y = a.y + b;
+        result.z = a.z + b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     */
+    public void sub(Int3 a) {
+        this.x -= a.x;
+        this.y -= a.y;
+        this.z -= a.z;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int3 sub(Int3 a, Int3 b) {
+        Int3 result = new Int3();
+        result.x = a.x - b.x;
+        result.y = a.y - b.y;
+        result.z = a.z - b.z;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(int value) {
+        x -= value;
+        y -= value;
+        z -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int3 sub(Int3 a, int b) {
+        Int3 result = new Int3();
+        result.x = a.x - b;
+        result.y = a.y - b;
+        result.z = a.z - b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     */
+    public void mul(Int3 a) {
+        this.x *= a.x;
+        this.y *= a.y;
+        this.z *= a.z;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int3 mul(Int3 a, Int3 b) {
+        Int3 result = new Int3();
+        result.x = a.x * b.x;
+        result.y = a.y * b.y;
+        result.z = a.z * b.z;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(int value) {
+        x *= value;
+        y *= value;
+        z *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int3 mul(Int3 a, int b) {
+        Int3 result = new Int3();
+        result.x = a.x * b;
+        result.y = a.y * b;
+        result.z = a.z * b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     */
+    public void div(Int3 a) {
+        this.x /= a.x;
+        this.y /= a.y;
+        this.z /= a.z;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int3 div(Int3 a, Int3 b) {
+        Int3 result = new Int3();
+        result.x = a.x / b.x;
+        result.y = a.y / b.y;
+        result.z = a.z / b.z;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(int value) {
+        x /= value;
+        y /= value;
+        z /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int3 div(Int3 a, int b) {
+        Int3 result = new Int3();
+        result.x = a.x / b;
+        result.y = a.y / b;
+        result.z = a.z / b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     */
+    public void mod(Int3 a) {
+        this.x %= a.x;
+        this.y %= a.y;
+        this.z %= a.z;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int3 mod(Int3 a, Int3 b) {
+        Int3 result = new Int3();
+        result.x = a.x % b.x;
+        result.y = a.y % b.y;
+        result.z = a.z % b.z;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param value
+     */
+    public void mod(int value) {
+        x %= value;
+        y %= value;
+        z %= value;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int3 mod(Int3 a, int b) {
+        Int3 result = new Int3();
+        result.x = a.x % b;
+        result.y = a.y % b;
+        result.z = a.z % b;
+
+        return result;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public int length() {
+        return 3;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        this.x = -x;
+        this.y = -y;
+        this.z = -z;
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public int dotProduct(Int3 a) {
+        return (int)((x * a.x) + (y * a.y) + (z * a.z));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static int dotProduct(Int3 a, Int3 b) {
+        return (int)((b.x * a.x) + (b.y * a.y) + (b.z * a.z));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Int3 a, int factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+        z += a.z * factor;
+    }
+
+    /** @hide
+     * set vector value by Int3
+     *
+     * @param a
+     */
+    public void set(Int3 a) {
+        this.x = a.x;
+        this.y = a.y;
+        this.z = a.z;
+    }
+
+    /** @hide
+     * set the vector field value by Int
+     *
+     * @param a
+     * @param b
+     * @param c
+     */
+    public void setValues(int a, int b, int c) {
+        this.x = a;
+        this.y = b;
+        this.z = c;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public int elementSum() {
+        return (int)(x + y + z);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public int get(int i) {
+        switch (i) {
+        case 0:
+            return (int)(x);
+        case 1:
+            return (int)(y);
+        case 2:
+            return (int)(z);
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, int value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        case 2:
+            z = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, int value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        case 2:
+            z += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * copy the vector to int array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(int[] data, int offset) {
+        data[offset] = (int)(x);
+        data[offset + 1] = (int)(y);
+        data[offset + 2] = (int)(z);
+    }
 }
-
-
-
-
diff --git a/graphics/java/android/renderscript/Int4.java b/graphics/java/android/renderscript/Int4.java
index eefb349..1c0e2e2 100644
--- a/graphics/java/android/renderscript/Int4.java
+++ b/graphics/java/android/renderscript/Int4.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -16,30 +16,499 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript int4 type back to the Android system.
- *
- **/
+ * Vector version of the basic int type.
+ * Provides four int fields packed.
+ */
 public class Int4 {
-    public Int4() {
-    }
-
-    public Int4(int initX, int initY, int initZ, int initW) {
-        x = initX;
-        y = initY;
-        z = initZ;
-        w = initW;
-    }
-
     public int x;
     public int y;
     public int z;
     public int w;
+
+    public Int4() {
+    }
+
+    /** @hide */
+    public Int4(int i) {
+        this.x = this.y = this.z = this.w = i;
+    }
+
+    public Int4(int x, int y, int z, int w) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        this.w = w;
+    }
+
+    /** @hide */
+    public Int4(Int4 source) {
+        this.x = source.x;
+        this.y = source.y;
+        this.z = source.z;
+        this.w = source.w;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     */
+    public void add(Int4 a) {
+        this.x += a.x;
+        this.y += a.y;
+        this.z += a.z;
+        this.w += a.w;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int4 add(Int4 a, Int4 b) {
+        Int4 result = new Int4();
+        result.x = a.x + b.x;
+        result.y = a.y + b.y;
+        result.z = a.z + b.z;
+        result.w = a.w + b.w;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(int value) {
+        x += value;
+        y += value;
+        z += value;
+        w += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int4 add(Int4 a, int b) {
+        Int4 result = new Int4();
+        result.x = a.x + b;
+        result.y = a.y + b;
+        result.z = a.z + b;
+        result.w = a.w + b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     */
+    public void sub(Int4 a) {
+        this.x -= a.x;
+        this.y -= a.y;
+        this.z -= a.z;
+        this.w -= a.w;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int4 sub(Int4 a, Int4 b) {
+        Int4 result = new Int4();
+        result.x = a.x - b.x;
+        result.y = a.y - b.y;
+        result.z = a.z - b.z;
+        result.w = a.w - b.w;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(int value) {
+        x -= value;
+        y -= value;
+        z -= value;
+        w -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int4 sub(Int4 a, int b) {
+        Int4 result = new Int4();
+        result.x = a.x - b;
+        result.y = a.y - b;
+        result.z = a.z - b;
+        result.w = a.w - b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     */
+    public void mul(Int4 a) {
+        this.x *= a.x;
+        this.y *= a.y;
+        this.z *= a.z;
+        this.w *= a.w;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int4 mul(Int4 a, Int4 b) {
+        Int4 result = new Int4();
+        result.x = a.x * b.x;
+        result.y = a.y * b.y;
+        result.z = a.z * b.z;
+        result.w = a.w * b.w;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(int value) {
+        x *= value;
+        y *= value;
+        z *= value;
+        w *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int4 mul(Int4 a, int b) {
+        Int4 result = new Int4();
+        result.x = a.x * b;
+        result.y = a.y * b;
+        result.z = a.z * b;
+        result.w = a.w * b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     */
+    public void div(Int4 a) {
+        this.x /= a.x;
+        this.y /= a.y;
+        this.z /= a.z;
+        this.w /= a.w;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int4 div(Int4 a, Int4 b) {
+        Int4 result = new Int4();
+        result.x = a.x / b.x;
+        result.y = a.y / b.y;
+        result.z = a.z / b.z;
+        result.w = a.w / b.w;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(int value) {
+        x /= value;
+        y /= value;
+        z /= value;
+        w /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int4 div(Int4 a, int b) {
+        Int4 result = new Int4();
+        result.x = a.x / b;
+        result.y = a.y / b;
+        result.z = a.z / b;
+        result.w = a.w / b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     */
+    public void mod(Int4 a) {
+        this.x %= a.x;
+        this.y %= a.y;
+        this.z %= a.z;
+        this.w %= a.w;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int4 mod(Int4 a, Int4 b) {
+        Int4 result = new Int4();
+        result.x = a.x % b.x;
+        result.y = a.y % b.y;
+        result.z = a.z % b.z;
+        result.w = a.w % b.w;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param value
+     */
+    public void mod(int value) {
+        x %= value;
+        y %= value;
+        z %= value;
+        w %= value;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Int4 mod(Int4 a, int b) {
+        Int4 result = new Int4();
+        result.x = a.x % b;
+        result.y = a.y % b;
+        result.z = a.z % b;
+        result.w = a.w % b;
+
+        return result;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public int length() {
+        return 4;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        this.x = -x;
+        this.y = -y;
+        this.z = -z;
+        this.w = -w;
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public int dotProduct(Int4 a) {
+        return (int)((x * a.x) + (y * a.y) + (z * a.z) + (w * a.w));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static int dotProduct(Int4 a, Int4 b) {
+        return (int)((b.x * a.x) + (b.y * a.y) + (b.z * a.z) + (b.w * a.w));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Int4 a, int factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+        z += a.z * factor;
+        w += a.w * factor;
+    }
+
+    /** @hide
+     * set vector value by Int4
+     *
+     * @param a
+     */
+    public void set(Int4 a) {
+        this.x = a.x;
+        this.y = a.y;
+        this.z = a.z;
+        this.w = a.w;
+    }
+
+    /** @hide
+     * set the vector field value by Int
+     *
+     * @param a
+     * @param b
+     * @param c
+     * @param d
+     */
+    public void setValues(int a, int b, int c, int d) {
+        this.x = a;
+        this.y = b;
+        this.z = c;
+        this.w = d;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public int elementSum() {
+        return (int)(x + y + z + w);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public int get(int i) {
+        switch (i) {
+        case 0:
+            return (int)(x);
+        case 1:
+            return (int)(y);
+        case 2:
+            return (int)(z);
+        case 3:
+            return (int)(w);
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, int value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        case 2:
+            z = value;
+            return;
+        case 3:
+            w = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, int value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        case 2:
+            z += value;
+            return;
+        case 3:
+            w += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * copy the vector to int array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(int[] data, int offset) {
+        data[offset] = (int)(x);
+        data[offset + 1] = (int)(y);
+        data[offset + 2] = (int)(z);
+        data[offset + 3] = (int)(w);
+    }
 }
-
-
-
diff --git a/graphics/java/android/renderscript/Long2.java b/graphics/java/android/renderscript/Long2.java
index bd8382d..fabf204 100644
--- a/graphics/java/android/renderscript/Long2.java
+++ b/graphics/java/android/renderscript/Long2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -16,26 +16,425 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript long2 type back to the Android system.
- **/
+ * Vector version of the basic long type.
+ * Provides two long fields packed.
+ */
 public class Long2 {
+    public long x;
+    public long y;
+
     public Long2() {
     }
 
-    public Long2(long initX, long initY) {
-        x = initX;
-        y = initY;
+    /** @hide */
+    public Long2(long i) {
+        this.x = this.y = i;
     }
 
-    public long x;
-    public long y;
+    public Long2(long x, long y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /** @hide */
+    public Long2(Long2 source) {
+        this.x = source.x;
+        this.y = source.y;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     */
+    public void add(Long2 a) {
+        this.x += a.x;
+        this.y += a.y;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long2 add(Long2 a, Long2 b) {
+        Long2 result = new Long2();
+        result.x = a.x + b.x;
+        result.y = a.y + b.y;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(long value) {
+        x += value;
+        y += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long2 add(Long2 a, long b) {
+        Long2 result = new Long2();
+        result.x = a.x + b;
+        result.y = a.y + b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     */
+    public void sub(Long2 a) {
+        this.x -= a.x;
+        this.y -= a.y;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long2 sub(Long2 a, Long2 b) {
+        Long2 result = new Long2();
+        result.x = a.x - b.x;
+        result.y = a.y - b.y;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(long value) {
+        x -= value;
+        y -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long2 sub(Long2 a, long b) {
+        Long2 result = new Long2();
+        result.x = a.x - b;
+        result.y = a.y - b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     */
+    public void mul(Long2 a) {
+        this.x *= a.x;
+        this.y *= a.y;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long2 mul(Long2 a, Long2 b) {
+        Long2 result = new Long2();
+        result.x = a.x * b.x;
+        result.y = a.y * b.y;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(long value) {
+        x *= value;
+        y *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long2 mul(Long2 a, long b) {
+        Long2 result = new Long2();
+        result.x = a.x * b;
+        result.y = a.y * b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     */
+    public void div(Long2 a) {
+        this.x /= a.x;
+        this.y /= a.y;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long2 div(Long2 a, Long2 b) {
+        Long2 result = new Long2();
+        result.x = a.x / b.x;
+        result.y = a.y / b.y;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(long value) {
+        x /= value;
+        y /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long2 div(Long2 a, long b) {
+        Long2 result = new Long2();
+        result.x = a.x / b;
+        result.y = a.y / b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     */
+    public void mod(Long2 a) {
+        this.x %= a.x;
+        this.y %= a.y;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long2 mod(Long2 a, Long2 b) {
+        Long2 result = new Long2();
+        result.x = a.x % b.x;
+        result.y = a.y % b.y;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param value
+     */
+    public void mod(long value) {
+        x %= value;
+        y %= value;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long2 mod(Long2 a, long b) {
+        Long2 result = new Long2();
+        result.x = a.x % b;
+        result.y = a.y % b;
+
+        return result;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public long length() {
+        return 2;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        this.x = -x;
+        this.y = -y;
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public long dotProduct(Long2 a) {
+        return (long)((x * a.x) + (y * a.y));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static long dotProduct(Long2 a, Long2 b) {
+        return (long)((b.x * a.x) + (b.y * a.y));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Long2 a, long factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+    }
+
+    /** @hide
+     * set vector value by Long2
+     *
+     * @param a
+     */
+    public void set(Long2 a) {
+        this.x = a.x;
+        this.y = a.y;
+    }
+
+    /** @hide
+     * set the vector field value by Long
+     *
+     * @param a
+     * @param b
+     */
+    public void setValues(long a, long b) {
+        this.x = a;
+        this.y = b;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public long elementSum() {
+        return (long)(x + y);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public long get(int i) {
+        switch (i) {
+        case 0:
+            return (long)(x);
+        case 1:
+            return (long)(y);
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, long value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, long value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * copy the vector to long array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(long[] data, int offset) {
+        data[offset] = (long)(x);
+        data[offset + 1] = (long)(y);
+    }
 }
-
-
-
-
diff --git a/graphics/java/android/renderscript/Long3.java b/graphics/java/android/renderscript/Long3.java
index 3e94942..8e243cc 100644
--- a/graphics/java/android/renderscript/Long3.java
+++ b/graphics/java/android/renderscript/Long3.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -16,28 +16,462 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript long3 type back to the Android system.
- **/
+ * Vector version of the basic long type.
+ * Provides three long fields packed.
+ */
 public class Long3 {
-    public Long3() {
-    }
-
-    public Long3(long initX, long initY, long initZ) {
-        x = initX;
-        y = initY;
-        z = initZ;
-    }
-
     public long x;
     public long y;
     public long z;
+
+    public Long3() {
+    }
+
+    /** @hide */
+    public Long3(long i) {
+        this.x = this.y = this.z = i;
+    }
+
+    public Long3(long x, long y, long z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    /** @hide */
+    public Long3(Long3 source) {
+        this.x = source.x;
+        this.y = source.y;
+        this.z = source.z;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     */
+    public void add(Long3 a) {
+        this.x += a.x;
+        this.y += a.y;
+        this.z += a.z;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long3 add(Long3 a, Long3 b) {
+        Long3 result = new Long3();
+        result.x = a.x + b.x;
+        result.y = a.y + b.y;
+        result.z = a.z + b.z;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(long value) {
+        x += value;
+        y += value;
+        z += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long3 add(Long3 a, long b) {
+        Long3 result = new Long3();
+        result.x = a.x + b;
+        result.y = a.y + b;
+        result.z = a.z + b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     */
+    public void sub(Long3 a) {
+        this.x -= a.x;
+        this.y -= a.y;
+        this.z -= a.z;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long3 sub(Long3 a, Long3 b) {
+        Long3 result = new Long3();
+        result.x = a.x - b.x;
+        result.y = a.y - b.y;
+        result.z = a.z - b.z;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(long value) {
+        x -= value;
+        y -= value;
+        z -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long3 sub(Long3 a, long b) {
+        Long3 result = new Long3();
+        result.x = a.x - b;
+        result.y = a.y - b;
+        result.z = a.z - b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     */
+    public void mul(Long3 a) {
+        this.x *= a.x;
+        this.y *= a.y;
+        this.z *= a.z;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long3 mul(Long3 a, Long3 b) {
+        Long3 result = new Long3();
+        result.x = a.x * b.x;
+        result.y = a.y * b.y;
+        result.z = a.z * b.z;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(long value) {
+        x *= value;
+        y *= value;
+        z *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long3 mul(Long3 a, long b) {
+        Long3 result = new Long3();
+        result.x = a.x * b;
+        result.y = a.y * b;
+        result.z = a.z * b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     */
+    public void div(Long3 a) {
+        this.x /= a.x;
+        this.y /= a.y;
+        this.z /= a.z;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long3 div(Long3 a, Long3 b) {
+        Long3 result = new Long3();
+        result.x = a.x / b.x;
+        result.y = a.y / b.y;
+        result.z = a.z / b.z;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(long value) {
+        x /= value;
+        y /= value;
+        z /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long3 div(Long3 a, long b) {
+        Long3 result = new Long3();
+        result.x = a.x / b;
+        result.y = a.y / b;
+        result.z = a.z / b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     */
+    public void mod(Long3 a) {
+        this.x %= a.x;
+        this.y %= a.y;
+        this.z %= a.z;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long3 mod(Long3 a, Long3 b) {
+        Long3 result = new Long3();
+        result.x = a.x % b.x;
+        result.y = a.y % b.y;
+        result.z = a.z % b.z;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param value
+     */
+    public void mod(long value) {
+        x %= value;
+        y %= value;
+        z %= value;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long3 mod(Long3 a, long b) {
+        Long3 result = new Long3();
+        result.x = a.x % b;
+        result.y = a.y % b;
+        result.z = a.z % b;
+
+        return result;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public long length() {
+        return 3;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        this.x = -x;
+        this.y = -y;
+        this.z = -z;
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public long dotProduct(Long3 a) {
+        return (long)((x * a.x) + (y * a.y) + (z * a.z));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static long dotProduct(Long3 a, Long3 b) {
+        return (long)((b.x * a.x) + (b.y * a.y) + (b.z * a.z));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Long3 a, long factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+        z += a.z * factor;
+    }
+
+    /** @hide
+     * set vector value by Long3
+     *
+     * @param a
+     */
+    public void set(Long3 a) {
+        this.x = a.x;
+        this.y = a.y;
+        this.z = a.z;
+    }
+
+    /** @hide
+     * set the vector field value by Long
+     *
+     * @param a
+     * @param b
+     * @param c
+     */
+    public void setValues(long a, long b, long c) {
+        this.x = a;
+        this.y = b;
+        this.z = c;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public long elementSum() {
+        return (long)(x + y + z);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public long get(int i) {
+        switch (i) {
+        case 0:
+            return (long)(x);
+        case 1:
+            return (long)(y);
+        case 2:
+            return (long)(z);
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, long value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        case 2:
+            z = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, long value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        case 2:
+            z += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * copy the vector to long array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(long[] data, int offset) {
+        data[offset] = (long)(x);
+        data[offset + 1] = (long)(y);
+        data[offset + 2] = (long)(z);
+    }
 }
-
-
-
-
diff --git a/graphics/java/android/renderscript/Long4.java b/graphics/java/android/renderscript/Long4.java
index 00fb7e6..757b910 100644
--- a/graphics/java/android/renderscript/Long4.java
+++ b/graphics/java/android/renderscript/Long4.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -16,29 +16,499 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript long4 type back to the Android system.
- **/
+ * Vector version of the basic long type.
+ * Provides four long fields packed.
+ */
 public class Long4 {
-    public Long4() {
-    }
-
-    public Long4(long initX, long initY, long initZ, long initW) {
-        x = initX;
-        y = initY;
-        z = initZ;
-        w = initW;
-    }
-
     public long x;
     public long y;
     public long z;
     public long w;
+
+    public Long4() {
+    }
+
+    /** @hide */
+    public Long4(long i) {
+        this.x = this.y = this.z = this.w = i;
+    }
+
+    public Long4(long x, long y, long z, long w) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        this.w = w;
+    }
+
+    /** @hide */
+    public Long4(Long4 source) {
+        this.x = source.x;
+        this.y = source.y;
+        this.z = source.z;
+        this.w = source.w;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     */
+    public void add(Long4 a) {
+        this.x += a.x;
+        this.y += a.y;
+        this.z += a.z;
+        this.w += a.w;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long4 add(Long4 a, Long4 b) {
+        Long4 result = new Long4();
+        result.x = a.x + b.x;
+        result.y = a.y + b.y;
+        result.z = a.z + b.z;
+        result.w = a.w + b.w;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(long value) {
+        x += value;
+        y += value;
+        z += value;
+        w += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long4 add(Long4 a, long b) {
+        Long4 result = new Long4();
+        result.x = a.x + b;
+        result.y = a.y + b;
+        result.z = a.z + b;
+        result.w = a.w + b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     */
+    public void sub(Long4 a) {
+        this.x -= a.x;
+        this.y -= a.y;
+        this.z -= a.z;
+        this.w -= a.w;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long4 sub(Long4 a, Long4 b) {
+        Long4 result = new Long4();
+        result.x = a.x - b.x;
+        result.y = a.y - b.y;
+        result.z = a.z - b.z;
+        result.w = a.w - b.w;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(long value) {
+        x -= value;
+        y -= value;
+        z -= value;
+        w -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long4 sub(Long4 a, long b) {
+        Long4 result = new Long4();
+        result.x = a.x - b;
+        result.y = a.y - b;
+        result.z = a.z - b;
+        result.w = a.w - b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     */
+    public void mul(Long4 a) {
+        this.x *= a.x;
+        this.y *= a.y;
+        this.z *= a.z;
+        this.w *= a.w;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long4 mul(Long4 a, Long4 b) {
+        Long4 result = new Long4();
+        result.x = a.x * b.x;
+        result.y = a.y * b.y;
+        result.z = a.z * b.z;
+        result.w = a.w * b.w;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(long value) {
+        x *= value;
+        y *= value;
+        z *= value;
+        w *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long4 mul(Long4 a, long b) {
+        Long4 result = new Long4();
+        result.x = a.x * b;
+        result.y = a.y * b;
+        result.z = a.z * b;
+        result.w = a.w * b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     */
+    public void div(Long4 a) {
+        this.x /= a.x;
+        this.y /= a.y;
+        this.z /= a.z;
+        this.w /= a.w;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long4 div(Long4 a, Long4 b) {
+        Long4 result = new Long4();
+        result.x = a.x / b.x;
+        result.y = a.y / b.y;
+        result.z = a.z / b.z;
+        result.w = a.w / b.w;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(long value) {
+        x /= value;
+        y /= value;
+        z /= value;
+        w /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long4 div(Long4 a, long b) {
+        Long4 result = new Long4();
+        result.x = a.x / b;
+        result.y = a.y / b;
+        result.z = a.z / b;
+        result.w = a.w / b;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     */
+    public void mod(Long4 a) {
+        this.x %= a.x;
+        this.y %= a.y;
+        this.z %= a.z;
+        this.w %= a.w;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long4 mod(Long4 a, Long4 b) {
+        Long4 result = new Long4();
+        result.x = a.x % b.x;
+        result.y = a.y % b.y;
+        result.z = a.z % b.z;
+        result.w = a.w % b.w;
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param value
+     */
+    public void mod(long value) {
+        x %= value;
+        y %= value;
+        z %= value;
+        w %= value;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Long4 mod(Long4 a, long b) {
+        Long4 result = new Long4();
+        result.x = a.x % b;
+        result.y = a.y % b;
+        result.z = a.z % b;
+        result.w = a.w % b;
+
+        return result;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public long length() {
+        return 4;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        this.x = -x;
+        this.y = -y;
+        this.z = -z;
+        this.w = -w;
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public long dotProduct(Long4 a) {
+        return (long)((x * a.x) + (y * a.y) + (z * a.z) + (w * a.w));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static long dotProduct(Long4 a, Long4 b) {
+        return (long)((b.x * a.x) + (b.y * a.y) + (b.z * a.z) + (b.w * a.w));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Long4 a, long factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+        z += a.z * factor;
+        w += a.w * factor;
+    }
+
+    /** @hide
+     * set vector value by Long4
+     *
+     * @param a
+     */
+    public void set(Long4 a) {
+        this.x = a.x;
+        this.y = a.y;
+        this.z = a.z;
+        this.w = a.w;
+    }
+
+    /** @hide
+     * set the vector field value by Long
+     *
+     * @param a
+     * @param b
+     * @param c
+     * @param d
+     */
+    public void setValues(long a, long b, long c, long d) {
+        this.x = a;
+        this.y = b;
+        this.z = c;
+        this.w = d;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public long elementSum() {
+        return (long)(x + y + z + w);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public long get(int i) {
+        switch (i) {
+        case 0:
+            return (long)(x);
+        case 1:
+            return (long)(y);
+        case 2:
+            return (long)(z);
+        case 3:
+            return (long)(w);
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, long value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        case 2:
+            z = value;
+            return;
+        case 3:
+            w = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, long value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        case 2:
+            z += value;
+            return;
+        case 3:
+            w += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * copy the vector to long array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(Long[] data, int offset) {
+        data[offset] = (long)(x);
+        data[offset + 1] = (long)(y);
+        data[offset + 2] = (long)(z);
+        data[offset + 3] = (long)(w);
+    }
 }
-
-
-
diff --git a/graphics/java/android/renderscript/Matrix2f.java b/graphics/java/android/renderscript/Matrix2f.java
index d3621fa..048262d 100644
--- a/graphics/java/android/renderscript/Matrix2f.java
+++ b/graphics/java/android/renderscript/Matrix2f.java
@@ -16,9 +16,6 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
 
 /**
  * Class for exposing the native RenderScript rs_matrix2x2 type back to the Android system.
diff --git a/graphics/java/android/renderscript/Matrix3f.java b/graphics/java/android/renderscript/Matrix3f.java
index 8c3c330..9a4af77 100644
--- a/graphics/java/android/renderscript/Matrix3f.java
+++ b/graphics/java/android/renderscript/Matrix3f.java
@@ -16,9 +16,6 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
 
 /**
  * Class for exposing the native RenderScript rs_matrix3x3 type back to the Android system.
diff --git a/graphics/java/android/renderscript/Matrix4f.java b/graphics/java/android/renderscript/Matrix4f.java
index cd18e30..5d5bf5f 100644
--- a/graphics/java/android/renderscript/Matrix4f.java
+++ b/graphics/java/android/renderscript/Matrix4f.java
@@ -17,7 +17,6 @@
 package android.renderscript;
 
 import java.lang.Math;
-import android.util.Log;
 
 
 /**
diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java
index bca4aa3..a4ecc38 100644
--- a/graphics/java/android/renderscript/Mesh.java
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -18,8 +18,6 @@
 
 import java.util.Vector;
 
-import android.util.Log;
-
 /**
  * @hide
  * @deprecated in API 16
@@ -91,7 +89,7 @@
     Allocation[] mIndexBuffers;
     Primitive[] mPrimitives;
 
-    Mesh(int id, RenderScript rs) {
+    Mesh(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -367,7 +365,7 @@
                     alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
                 }
                 vertexBuffers[ct] = alloc;
-                vtx[ct] = alloc.getID(mRS);
+                vtx[ct] = (int)alloc.getID(mRS);
             }
 
             for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
@@ -378,15 +376,15 @@
                 } else if(entry.e != null) {
                     alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
                 }
-                int allocID = (alloc == null) ? 0 : alloc.getID(mRS);
+                long allocID = (alloc == null) ? 0 : alloc.getID(mRS);
                 indexBuffers[ct] = alloc;
                 primitives[ct] = entry.prim;
 
-                idx[ct] = allocID;
+                idx[ct] = (int)allocID;
                 prim[ct] = entry.prim.mID;
             }
 
-            int id = mRS.nMeshCreate(vtx, idx, prim);
+            long id = mRS.nMeshCreate(vtx, idx, prim);
             Mesh newMesh = new Mesh(id, mRS);
             newMesh.mVertexBuffers = vertexBuffers;
             newMesh.mIndexBuffers = indexBuffers;
@@ -517,20 +515,20 @@
             for(int ct = 0; ct < mVertexTypeCount; ct ++) {
                 Entry entry = mVertexTypes[ct];
                 vertexBuffers[ct] = entry.a;
-                vtx[ct] = entry.a.getID(mRS);
+                vtx[ct] = (int)entry.a.getID(mRS);
             }
 
             for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
                 Entry entry = (Entry)mIndexTypes.elementAt(ct);
-                int allocID = (entry.a == null) ? 0 : entry.a.getID(mRS);
+                long allocID = (entry.a == null) ? 0 : entry.a.getID(mRS);
                 indexBuffers[ct] = entry.a;
                 primitives[ct] = entry.prim;
 
-                idx[ct] = allocID;
+                idx[ct] = (int)allocID;
                 prim[ct] = entry.prim.mID;
             }
 
-            int id = mRS.nMeshCreate(vtx, idx, prim);
+            long id = mRS.nMeshCreate(vtx, idx, prim);
             Mesh newMesh = new Mesh(id, mRS);
             newMesh.mVertexBuffers = vertexBuffers;
             newMesh.mIndexBuffers = indexBuffers;
diff --git a/graphics/java/android/renderscript/Path.java b/graphics/java/android/renderscript/Path.java
index 9c4d41b..f3502aa 100644
--- a/graphics/java/android/renderscript/Path.java
+++ b/graphics/java/android/renderscript/Path.java
@@ -16,9 +16,6 @@
 
 package android.renderscript;
 
-import java.util.Vector;
-import android.util.Log;
-
 /**
  * @hide
  *
@@ -41,7 +38,7 @@
     float mQuality;
     boolean mCoverageToAlpha;
 
-    Path(int id, RenderScript rs, Primitive p, Allocation vtx, Allocation loop, float q) {
+    Path(long id, RenderScript rs, Primitive p, Allocation vtx, Allocation loop, float q) {
         super(id, rs);
         mVertexBuffer = vtx;
         mLoopBuffer = loop;
@@ -67,7 +64,7 @@
 
 
     public static Path createStaticPath(RenderScript rs, Primitive p, float quality, Allocation vtx) {
-        int id = rs.nPathCreate(p.mID, false, vtx.getID(rs), 0, quality);
+        long id = rs.nPathCreate(p.mID, false, vtx.getID(rs), 0, quality);
         Path newPath = new Path(id, rs, p, null, null, quality);
         return newPath;
     }
diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java
index bc2ca35..3eb9b75 100644
--- a/graphics/java/android/renderscript/Program.java
+++ b/graphics/java/android/renderscript/Program.java
@@ -74,7 +74,7 @@
     int mTextureCount;
     String mShader;
 
-    Program(int id, RenderScript rs) {
+    Program(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -150,7 +150,7 @@
             a.getType().getID(mRS) != mConstants[slot].getID(mRS)) {
             throw new IllegalArgumentException("Allocation type does not match slot type.");
         }
-        int id = a != null ? a.getID(mRS) : 0;
+        long id = a != null ? a.getID(mRS) : 0;
         mRS.nProgramBindConstants(getID(mRS), slot, id);
     }
 
@@ -172,7 +172,7 @@
             throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
         }
 
-        int id = va != null ? va.getID(mRS) : 0;
+        long id = va != null ? va.getID(mRS) : 0;
         mRS.nProgramBindTexture(getID(mRS), slot, id);
     }
 
@@ -192,7 +192,7 @@
             throw new IllegalArgumentException("Slot ID out of range.");
         }
 
-        int id = vs != null ? vs.getID(mRS) : 0;
+        long id = vs != null ? vs.getID(mRS) : 0;
         mRS.nProgramBindSampler(getID(mRS), slot, id);
     }
 
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index b9ba3fd..2704130 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -17,9 +17,6 @@
 package android.renderscript;
 
 
-import android.util.Log;
-
-
 /**
  * @hide
  * @deprecated in API 16
@@ -39,7 +36,7 @@
  *
  **/
 public class ProgramFragment extends Program {
-    ProgramFragment(int id, RenderScript rs) {
+    ProgramFragment(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -71,23 +68,23 @@
 
             for (int i=0; i < mInputCount; i++) {
                 tmp[idx++] = ProgramParam.INPUT.mID;
-                tmp[idx++] = mInputs[i].getID(mRS);
+                tmp[idx++] = (int)mInputs[i].getID(mRS);
             }
             for (int i=0; i < mOutputCount; i++) {
                 tmp[idx++] = ProgramParam.OUTPUT.mID;
-                tmp[idx++] = mOutputs[i].getID(mRS);
+                tmp[idx++] = (int)mOutputs[i].getID(mRS);
             }
             for (int i=0; i < mConstantCount; i++) {
                 tmp[idx++] = ProgramParam.CONSTANT.mID;
-                tmp[idx++] = mConstants[i].getID(mRS);
+                tmp[idx++] = (int)mConstants[i].getID(mRS);
             }
             for (int i=0; i < mTextureCount; i++) {
                 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
-                tmp[idx++] = mTextureTypes[i].mID;
+                tmp[idx++] = (int)mTextureTypes[i].mID;
                 texNames[i] = mTextureNames[i];
             }
 
-            int id = mRS.nProgramFragmentCreate(mShader, texNames, tmp);
+            long id = mRS.nProgramFragmentCreate(mShader, texNames, tmp);
             ProgramFragment pf = new ProgramFragment(id, mRS);
             initProgram(pf);
             return pf;
diff --git a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
index 8ae1777..e1c35c5 100644
--- a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
+++ b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
@@ -17,9 +17,6 @@
 package android.renderscript;
 
 
-import android.util.Log;
-
-
 /**
  * @hide
  * @deprecated in API 16
@@ -31,7 +28,7 @@
  *
  **/
 public class ProgramFragmentFixedFunction extends ProgramFragment {
-    ProgramFragmentFixedFunction(int id, RenderScript rs) {
+    ProgramFragmentFixedFunction(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -58,23 +55,23 @@
 
             for (int i=0; i < mInputCount; i++) {
                 tmp[idx++] = ProgramParam.INPUT.mID;
-                tmp[idx++] = mInputs[i].getID(mRS);
+                tmp[idx++] = (int)mInputs[i].getID(mRS);
             }
             for (int i=0; i < mOutputCount; i++) {
                 tmp[idx++] = ProgramParam.OUTPUT.mID;
-                tmp[idx++] = mOutputs[i].getID(mRS);
+                tmp[idx++] = (int)mOutputs[i].getID(mRS);
             }
             for (int i=0; i < mConstantCount; i++) {
                 tmp[idx++] = ProgramParam.CONSTANT.mID;
-                tmp[idx++] = mConstants[i].getID(mRS);
+                tmp[idx++] = (int)mConstants[i].getID(mRS);
             }
             for (int i=0; i < mTextureCount; i++) {
                 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
-                tmp[idx++] = mTextureTypes[i].mID;
+                tmp[idx++] = (int)mTextureTypes[i].mID;
                 texNames[i] = mTextureNames[i];
             }
 
-            int id = mRS.nProgramFragmentCreate(mShader, texNames, tmp);
+            long id = mRS.nProgramFragmentCreate(mShader, texNames, tmp);
             ProgramFragmentFixedFunction pf = new ProgramFragmentFixedFunction(id, mRS);
             initProgram(pf);
             return pf;
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index 216cb4e..8c7c9aa 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -17,9 +17,6 @@
 package android.renderscript;
 
 
-import android.util.Log;
-
-
 /**
  * @hide
  * @deprecated in API 16
@@ -54,7 +51,7 @@
     boolean mPointSprite;
     CullMode mCullMode;
 
-    ProgramRaster(int id, RenderScript rs) {
+    ProgramRaster(long id, RenderScript rs) {
         super(id, rs);
 
         mPointSprite = false;
@@ -154,7 +151,7 @@
          */
         public ProgramRaster create() {
             mRS.validate();
-            int id = mRS.nProgramRasterCreate(mPointSprite, mCullMode.mID);
+            long id = mRS.nProgramRasterCreate(mPointSprite, mCullMode.mID);
             ProgramRaster programRaster = new ProgramRaster(id, mRS);
             programRaster.mPointSprite = mPointSprite;
             programRaster.mCullMode = mCullMode;
diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java
index dac9e76..730c51b 100644
--- a/graphics/java/android/renderscript/ProgramStore.java
+++ b/graphics/java/android/renderscript/ProgramStore.java
@@ -17,9 +17,6 @@
 package android.renderscript;
 
 
-import android.util.Log;
-
-
 /**
  * @hide
  * <p>ProgramStore contains a set of parameters that control how
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index 1c5a191..d194ba9 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -39,10 +39,6 @@
 package android.renderscript;
 
 
-import android.graphics.Matrix;
-import android.util.Log;
-
-
 /**
  * @hide
  * @deprecated in API 16
@@ -53,7 +49,7 @@
  **/
 public class ProgramVertex extends Program {
 
-    ProgramVertex(int id, RenderScript rs) {
+    ProgramVertex(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -132,23 +128,23 @@
 
             for (int i=0; i < mInputCount; i++) {
                 tmp[idx++] = ProgramParam.INPUT.mID;
-                tmp[idx++] = mInputs[i].getID(mRS);
+                tmp[idx++] = (int)mInputs[i].getID(mRS);
             }
             for (int i=0; i < mOutputCount; i++) {
                 tmp[idx++] = ProgramParam.OUTPUT.mID;
-                tmp[idx++] = mOutputs[i].getID(mRS);
+                tmp[idx++] = (int)mOutputs[i].getID(mRS);
             }
             for (int i=0; i < mConstantCount; i++) {
                 tmp[idx++] = ProgramParam.CONSTANT.mID;
-                tmp[idx++] = mConstants[i].getID(mRS);
+                tmp[idx++] = (int)mConstants[i].getID(mRS);
             }
             for (int i=0; i < mTextureCount; i++) {
                 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
-                tmp[idx++] = mTextureTypes[i].mID;
+                tmp[idx++] = (int)mTextureTypes[i].mID;
                 texNames[i] = mTextureNames[i];
             }
 
-            int id = mRS.nProgramVertexCreate(mShader, texNames, tmp);
+            long id = mRS.nProgramVertexCreate(mShader, texNames, tmp);
             ProgramVertex pv = new ProgramVertex(id, mRS);
             initProgram(pv);
             return pv;
diff --git a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
index ad486f3..2d281b8 100644
--- a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
+++ b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
@@ -17,10 +17,6 @@
 package android.renderscript;
 
 
-import android.graphics.Matrix;
-import android.util.Log;
-
-
 /**
  * @hide
  * @deprecated in API 16
@@ -31,7 +27,7 @@
  **/
 public class ProgramVertexFixedFunction extends ProgramVertex {
 
-    ProgramVertexFixedFunction(int id, RenderScript rs) {
+    ProgramVertexFixedFunction(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -85,23 +81,23 @@
 
             for (int i=0; i < mInputCount; i++) {
                 tmp[idx++] = ProgramParam.INPUT.mID;
-                tmp[idx++] = mInputs[i].getID(mRS);
+                tmp[idx++] = (int)mInputs[i].getID(mRS);
             }
             for (int i=0; i < mOutputCount; i++) {
                 tmp[idx++] = ProgramParam.OUTPUT.mID;
-                tmp[idx++] = mOutputs[i].getID(mRS);
+                tmp[idx++] = (int)mOutputs[i].getID(mRS);
             }
             for (int i=0; i < mConstantCount; i++) {
                 tmp[idx++] = ProgramParam.CONSTANT.mID;
-                tmp[idx++] = mConstants[i].getID(mRS);
+                tmp[idx++] = (int)mConstants[i].getID(mRS);
             }
             for (int i=0; i < mTextureCount; i++) {
                 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
-                tmp[idx++] = mTextureTypes[i].mID;
+                tmp[idx++] = (int)mTextureTypes[i].mID;
                 texNames[i] = mTextureNames[i];
             }
 
-            int id = mRS.nProgramVertexCreate(mShader, texNames, tmp);
+            long id = mRS.nProgramVertexCreate(mShader, texNames, tmp);
             ProgramVertexFixedFunction pv = new ProgramVertexFixedFunction(id, mRS);
             initProgram(pv);
             return pv;
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index 308d97a..5db72d9 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -16,16 +16,8 @@
 
 package android.renderscript;
 
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
 import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
diff --git a/graphics/java/android/renderscript/RSTextureView.java b/graphics/java/android/renderscript/RSTextureView.java
index 7eeeeae..af3258a 100644
--- a/graphics/java/android/renderscript/RSTextureView.java
+++ b/graphics/java/android/renderscript/RSTextureView.java
@@ -16,16 +16,9 @@
 
 package android.renderscript;
 
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
 import android.content.Context;
 import android.graphics.SurfaceTexture;
-import android.os.Handler;
-import android.os.Message;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.TextureView;
 
 /**
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 7d4a5c4..d2c7456 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -17,15 +17,11 @@
 package android.renderscript;
 
 import java.io.File;
-import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 
 import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
 import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.graphics.SurfaceTexture;
 import android.os.Process;
 import android.util.Log;
@@ -91,14 +87,14 @@
     }
 
     // Non-threadsafe functions.
-    native int  nDeviceCreate();
-    native void nDeviceDestroy(int dev);
-    native void nDeviceSetConfig(int dev, int param, int value);
-    native int nContextGetUserMessage(int con, int[] data);
-    native String nContextGetErrorMessage(int con);
-    native int  nContextPeekMessage(int con, int[] subID);
-    native void nContextInitToClient(int con);
-    native void nContextDeinitToClient(int con);
+    native long  nDeviceCreate();
+    native void nDeviceDestroy(long dev);
+    native void nDeviceSetConfig(long dev, int param, int value);
+    native int nContextGetUserMessage(long con, int[] data);
+    native String nContextGetErrorMessage(long con);
+    native int  nContextPeekMessage(long con, int[] subID);
+    native void nContextInitToClient(long con);
+    native void nContextDeinitToClient(long con);
 
     static File mCacheDir;
 
@@ -154,13 +150,13 @@
 
     // Methods below are wrapped to protect the non-threadsafe
     // lockless fifo.
-    native int  rsnContextCreateGL(int dev, int ver, int sdkVer,
+    native long  rsnContextCreateGL(long dev, int ver, int sdkVer,
                  int colorMin, int colorPref,
                  int alphaMin, int alphaPref,
                  int depthMin, int depthPref,
                  int stencilMin, int stencilPref,
                  int samplesMin, int samplesPref, float samplesQ, int dpi);
-    synchronized int nContextCreateGL(int dev, int ver, int sdkVer,
+    synchronized long nContextCreateGL(long dev, int ver, int sdkVer,
                  int colorMin, int colorPref,
                  int alphaMin, int alphaPref,
                  int depthMin, int depthPref,
@@ -171,100 +167,100 @@
                                   stencilMin, stencilPref,
                                   samplesMin, samplesPref, samplesQ, dpi);
     }
-    native int  rsnContextCreate(int dev, int ver, int sdkVer, int contextType);
-    synchronized int nContextCreate(int dev, int ver, int sdkVer, int contextType) {
+    native long  rsnContextCreate(long dev, int ver, int sdkVer, int contextType);
+    synchronized long nContextCreate(long dev, int ver, int sdkVer, int contextType) {
         return rsnContextCreate(dev, ver, sdkVer, contextType);
     }
-    native void rsnContextDestroy(int con);
+    native void rsnContextDestroy(long con);
     synchronized void nContextDestroy() {
         validate();
         rsnContextDestroy(mContext);
     }
-    native void rsnContextSetSurface(int con, int w, int h, Surface sur);
+    native void rsnContextSetSurface(long con, int w, int h, Surface sur);
     synchronized void nContextSetSurface(int w, int h, Surface sur) {
         validate();
         rsnContextSetSurface(mContext, w, h, sur);
     }
-    native void rsnContextSetSurfaceTexture(int con, int w, int h, SurfaceTexture sur);
+    native void rsnContextSetSurfaceTexture(long con, int w, int h, SurfaceTexture sur);
     synchronized void nContextSetSurfaceTexture(int w, int h, SurfaceTexture sur) {
         validate();
         rsnContextSetSurfaceTexture(mContext, w, h, sur);
     }
-    native void rsnContextSetPriority(int con, int p);
+    native void rsnContextSetPriority(long con, int p);
     synchronized void nContextSetPriority(int p) {
         validate();
         rsnContextSetPriority(mContext, p);
     }
-    native void rsnContextDump(int con, int bits);
+    native void rsnContextDump(long con, int bits);
     synchronized void nContextDump(int bits) {
         validate();
         rsnContextDump(mContext, bits);
     }
-    native void rsnContextFinish(int con);
+    native void rsnContextFinish(long con);
     synchronized void nContextFinish() {
         validate();
         rsnContextFinish(mContext);
     }
 
-    native void rsnContextSendMessage(int con, int id, int[] data);
+    native void rsnContextSendMessage(long con, int id, int[] data);
     synchronized void nContextSendMessage(int id, int[] data) {
         validate();
         rsnContextSendMessage(mContext, id, data);
     }
 
-    native void rsnContextBindRootScript(int con, int script);
+    native void rsnContextBindRootScript(long con, int script);
     synchronized void nContextBindRootScript(int script) {
         validate();
         rsnContextBindRootScript(mContext, script);
     }
-    native void rsnContextBindSampler(int con, int sampler, int slot);
+    native void rsnContextBindSampler(long con, int sampler, int slot);
     synchronized void nContextBindSampler(int sampler, int slot) {
         validate();
         rsnContextBindSampler(mContext, sampler, slot);
     }
-    native void rsnContextBindProgramStore(int con, int pfs);
+    native void rsnContextBindProgramStore(long con, int pfs);
     synchronized void nContextBindProgramStore(int pfs) {
         validate();
         rsnContextBindProgramStore(mContext, pfs);
     }
-    native void rsnContextBindProgramFragment(int con, int pf);
+    native void rsnContextBindProgramFragment(long con, int pf);
     synchronized void nContextBindProgramFragment(int pf) {
         validate();
         rsnContextBindProgramFragment(mContext, pf);
     }
-    native void rsnContextBindProgramVertex(int con, int pv);
+    native void rsnContextBindProgramVertex(long con, int pv);
     synchronized void nContextBindProgramVertex(int pv) {
         validate();
         rsnContextBindProgramVertex(mContext, pv);
     }
-    native void rsnContextBindProgramRaster(int con, int pr);
+    native void rsnContextBindProgramRaster(long con, int pr);
     synchronized void nContextBindProgramRaster(int pr) {
         validate();
         rsnContextBindProgramRaster(mContext, pr);
     }
-    native void rsnContextPause(int con);
+    native void rsnContextPause(long con);
     synchronized void nContextPause() {
         validate();
         rsnContextPause(mContext);
     }
-    native void rsnContextResume(int con);
+    native void rsnContextResume(long con);
     synchronized void nContextResume() {
         validate();
         rsnContextResume(mContext);
     }
 
-    native void rsnAssignName(int con, int obj, byte[] name);
-    synchronized void nAssignName(int obj, byte[] name) {
+    native void rsnAssignName(long con, long obj, byte[] name);
+    synchronized void nAssignName(long obj, byte[] name) {
         validate();
         rsnAssignName(mContext, obj, name);
     }
-    native String rsnGetName(int con, int obj);
-    synchronized String nGetName(int obj) {
+    native String rsnGetName(long con, long obj);
+    synchronized String nGetName(long obj) {
         validate();
         return rsnGetName(mContext, obj);
     }
-    native void rsnObjDestroy(int con, int id);
-    synchronized void nObjDestroy(int id) {
+    native void rsnObjDestroy(long con, long id);
+    synchronized void nObjDestroy(long id) {
         // There is a race condition here.  The calling code may be run
         // by the gc while teardown is occuring.  This protects againts
         // deleting dead objects.
@@ -273,156 +269,140 @@
         }
     }
 
-    native int  rsnElementCreate(int con, int type, int kind, boolean norm, int vecSize);
-    synchronized int nElementCreate(int type, int kind, boolean norm, int vecSize) {
+    native long rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize);
+    synchronized long nElementCreate(long type, int kind, boolean norm, int vecSize) {
         validate();
         return rsnElementCreate(mContext, type, kind, norm, vecSize);
     }
-    native int  rsnElementCreate2(int con, int[] elements, String[] names, int[] arraySizes);
-    synchronized int nElementCreate2(int[] elements, String[] names, int[] arraySizes) {
+    native long rsnElementCreate2(long con, int[]elements, String[] names, int[] arraySizes);
+    synchronized long nElementCreate2(int[] elements, String[] names, int[] arraySizes) {
         validate();
         return rsnElementCreate2(mContext, elements, names, arraySizes);
     }
-    native void rsnElementGetNativeData(int con, int id, int[] elementData);
-    synchronized void nElementGetNativeData(int id, int[] elementData) {
+    native void rsnElementGetNativeData(long con, long id, int[] elementData);
+    synchronized void nElementGetNativeData(long id, int[] elementData) {
         validate();
         rsnElementGetNativeData(mContext, id, elementData);
     }
-    native void rsnElementGetSubElements(int con, int id,
+    native void rsnElementGetSubElements(long con, long id,
                                          int[] IDs, String[] names, int[] arraySizes);
-    synchronized void nElementGetSubElements(int id, int[] IDs, String[] names, int[] arraySizes) {
+    synchronized void nElementGetSubElements(long id, int[] IDs, String[] names, int[] arraySizes) {
         validate();
         rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
     }
 
-    native int rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
-    synchronized int nTypeCreate(int eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
+    native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
+    synchronized long nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
         validate();
         return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
     }
-    native void rsnTypeGetNativeData(int con, int id, int[] typeData);
-    synchronized void nTypeGetNativeData(int id, int[] typeData) {
+    native void rsnTypeGetNativeData(long con, long id, int[] typeData);
+    synchronized void nTypeGetNativeData(long id, int[] typeData) {
         validate();
         rsnTypeGetNativeData(mContext, id, typeData);
     }
 
-    native int  rsnAllocationCreateTyped(int con, int type, int mip, int usage, int pointer);
-    synchronized int nAllocationCreateTyped(int type, int mip, int usage, int pointer) {
+    native long rsnAllocationCreateTyped(long con, long type, int mip, int usage, int pointer);
+    synchronized long nAllocationCreateTyped(long type, int mip, int usage, int pointer) {
         validate();
         return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
     }
-    native int  rsnAllocationCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
-    synchronized int nAllocationCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
+    native long rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
+    synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
         validate();
         return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
     }
 
-    native int  rsnAllocationCreateBitmapBackedAllocation(int con, int type, int mip, Bitmap bmp, int usage);
-    synchronized int nAllocationCreateBitmapBackedAllocation(int type, int mip, Bitmap bmp, int usage) {
+    native long rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage);
+    synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) {
         validate();
         return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
     }
 
-
-    native int  rsnAllocationCubeCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
-    synchronized int nAllocationCubeCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
+    native long rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
+    synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
         validate();
         return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
     }
-    native int  rsnAllocationCreateBitmapRef(int con, int type, Bitmap bmp);
-    synchronized int nAllocationCreateBitmapRef(int type, Bitmap bmp) {
+    native long  rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp);
+    synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) {
         validate();
         return rsnAllocationCreateBitmapRef(mContext, type, bmp);
     }
-    native int  rsnAllocationCreateFromAssetStream(int con, int mips, int assetStream, int usage);
-    synchronized int nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
+    native long  rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage);
+    synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
         validate();
         return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
     }
 
-    native void  rsnAllocationCopyToBitmap(int con, int alloc, Bitmap bmp);
-    synchronized void nAllocationCopyToBitmap(int alloc, Bitmap bmp) {
+    native void  rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp);
+    synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) {
         validate();
         rsnAllocationCopyToBitmap(mContext, alloc, bmp);
     }
 
 
-    native void rsnAllocationSyncAll(int con, int alloc, int src);
-    synchronized void nAllocationSyncAll(int alloc, int src) {
+    native void rsnAllocationSyncAll(long con, long alloc, int src);
+    synchronized void nAllocationSyncAll(long alloc, int src) {
         validate();
         rsnAllocationSyncAll(mContext, alloc, src);
     }
-    native Surface rsnAllocationGetSurface(int con, int alloc);
-    synchronized Surface nAllocationGetSurface(int alloc) {
+    native Surface rsnAllocationGetSurface(long con, long alloc);
+    synchronized Surface nAllocationGetSurface(long alloc) {
         validate();
         return rsnAllocationGetSurface(mContext, alloc);
     }
-    native void rsnAllocationSetSurface(int con, int alloc, Surface sur);
-    synchronized void nAllocationSetSurface(int alloc, Surface sur) {
+    native void rsnAllocationSetSurface(long con, long alloc, Surface sur);
+    synchronized void nAllocationSetSurface(long alloc, Surface sur) {
         validate();
         rsnAllocationSetSurface(mContext, alloc, sur);
     }
-    native void rsnAllocationIoSend(int con, int alloc);
-    synchronized void nAllocationIoSend(int alloc) {
+    native void rsnAllocationIoSend(long con, long alloc);
+    synchronized void nAllocationIoSend(long alloc) {
         validate();
         rsnAllocationIoSend(mContext, alloc);
     }
-    native void rsnAllocationIoReceive(int con, int alloc);
-    synchronized void nAllocationIoReceive(int alloc) {
+    native void rsnAllocationIoReceive(long con, long alloc);
+    synchronized void nAllocationIoReceive(long alloc) {
         validate();
         rsnAllocationIoReceive(mContext, alloc);
     }
 
 
-    native void rsnAllocationGenerateMipmaps(int con, int alloc);
-    synchronized void nAllocationGenerateMipmaps(int alloc) {
+    native void rsnAllocationGenerateMipmaps(long con, long alloc);
+    synchronized void nAllocationGenerateMipmaps(long alloc) {
         validate();
         rsnAllocationGenerateMipmaps(mContext, alloc);
     }
-    native void  rsnAllocationCopyFromBitmap(int con, int alloc, Bitmap bmp);
-    synchronized void nAllocationCopyFromBitmap(int alloc, Bitmap bmp) {
+    native void  rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp);
+    synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) {
         validate();
         rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
     }
 
 
-    native void rsnAllocationData1D(int con, int id, int off, int mip, int count, int[] d, int sizeBytes);
-    synchronized void nAllocationData1D(int id, int off, int mip, int count, int[] d, int sizeBytes) {
+    native void rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt);
+    synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt) {
         validate();
-        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
-    }
-    native void rsnAllocationData1D(int con, int id, int off, int mip, int count, short[] d, int sizeBytes);
-    synchronized void nAllocationData1D(int id, int off, int mip, int count, short[] d, int sizeBytes) {
-        validate();
-        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
-    }
-    native void rsnAllocationData1D(int con, int id, int off, int mip, int count, byte[] d, int sizeBytes);
-    synchronized void nAllocationData1D(int id, int off, int mip, int count, byte[] d, int sizeBytes) {
-        validate();
-        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
-    }
-    native void rsnAllocationData1D(int con, int id, int off, int mip, int count, float[] d, int sizeBytes);
-    synchronized void nAllocationData1D(int id, int off, int mip, int count, float[] d, int sizeBytes) {
-        validate();
-        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
+        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID);
     }
 
-    native void rsnAllocationElementData1D(int con, int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
-    synchronized void nAllocationElementData1D(int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
+    native void rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
+    synchronized void nAllocationElementData1D(long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
         validate();
         rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
     }
 
-    native void rsnAllocationData2D(int con,
-                                    int dstAlloc, int dstXoff, int dstYoff,
+    native void rsnAllocationData2D(long con,
+                                    long dstAlloc, int dstXoff, int dstYoff,
                                     int dstMip, int dstFace,
                                     int width, int height,
-                                    int srcAlloc, int srcXoff, int srcYoff,
+                                    long srcAlloc, int srcXoff, int srcYoff,
                                     int srcMip, int srcFace);
-    synchronized void nAllocationData2D(int dstAlloc, int dstXoff, int dstYoff,
+    synchronized void nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff,
                                         int dstMip, int dstFace,
                                         int width, int height,
-                                        int srcAlloc, int srcXoff, int srcYoff,
+                                        long srcAlloc, int srcXoff, int srcYoff,
                                         int srcMip, int srcFace) {
         validate();
         rsnAllocationData2D(mContext,
@@ -433,42 +413,30 @@
                             srcMip, srcFace);
     }
 
-    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes);
-    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes) {
+    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face,
+                                    int w, int h, Object d, int sizeBytes, int dt);
+    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face,
+                                        int w, int h, Object d, int sizeBytes, Element.DataType dt) {
         validate();
-        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
+        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID);
     }
-    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes);
-    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes) {
-        validate();
-        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
-    }
-    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes);
-    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes) {
-        validate();
-        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
-    }
-    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes);
-    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes) {
-        validate();
-        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
-    }
-    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, Bitmap b);
-    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, Bitmap b) {
+
+    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b);
+    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b) {
         validate();
         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
     }
 
-    native void rsnAllocationData3D(int con,
-                                    int dstAlloc, int dstXoff, int dstYoff, int dstZoff,
+    native void rsnAllocationData3D(long con,
+                                    long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
                                     int dstMip,
                                     int width, int height, int depth,
-                                    int srcAlloc, int srcXoff, int srcYoff, int srcZoff,
+                                    long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
                                     int srcMip);
-    synchronized void nAllocationData3D(int dstAlloc, int dstXoff, int dstYoff, int dstZoff,
+    synchronized void nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
                                         int dstMip,
                                         int width, int height, int depth,
-                                        int srcAlloc, int srcXoff, int srcYoff, int srcZoff,
+                                        long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
                                         int srcMip) {
         validate();
         rsnAllocationData3D(mContext,
@@ -477,130 +445,118 @@
                             srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
     }
 
-    native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes);
-    synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes) {
+    native void rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip,
+                                    int w, int h, int depth, Object d, int sizeBytes, int dt);
+    synchronized void nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip,
+                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt) {
         validate();
-        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
-    }
-    native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes);
-    synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes) {
-        validate();
-        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
-    }
-    native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes);
-    synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes) {
-        validate();
-        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
-    }
-    native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes);
-    synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes) {
-        validate();
-        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
+        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID);
     }
 
+    native void rsnAllocationRead(long con, long id, Object d, int dt);
+    synchronized void nAllocationRead(long id, Object d, Element.DataType dt) {
+        validate();
+        rsnAllocationRead(mContext, id, d, dt.mID);
+    }
 
-    native void rsnAllocationRead(int con, int id, byte[] d);
-    synchronized void nAllocationRead(int id, byte[] d) {
+    native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d,
+                                    int sizeBytes, int dt);
+    synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d,
+                                        int sizeBytes, Element.DataType dt) {
         validate();
-        rsnAllocationRead(mContext, id, d);
+        rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID);
     }
-    native void rsnAllocationRead(int con, int id, short[] d);
-    synchronized void nAllocationRead(int id, short[] d) {
+
+    native void rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face,
+                                    int w, int h, Object d, int sizeBytes, int dt);
+    synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face,
+                                        int w, int h, Object d, int sizeBytes, Element.DataType dt) {
         validate();
-        rsnAllocationRead(mContext, id, d);
+        rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID);
     }
-    native void rsnAllocationRead(int con, int id, int[] d);
-    synchronized void nAllocationRead(int id, int[] d) {
-        validate();
-        rsnAllocationRead(mContext, id, d);
-    }
-    native void rsnAllocationRead(int con, int id, float[] d);
-    synchronized void nAllocationRead(int id, float[] d) {
-        validate();
-        rsnAllocationRead(mContext, id, d);
-    }
-    native int  rsnAllocationGetType(int con, int id);
-    synchronized int nAllocationGetType(int id) {
+
+    native long  rsnAllocationGetType(long con, long id);
+    synchronized long nAllocationGetType(long id) {
         validate();
         return rsnAllocationGetType(mContext, id);
     }
 
-    native void rsnAllocationResize1D(int con, int id, int dimX);
-    synchronized void nAllocationResize1D(int id, int dimX) {
+    native void rsnAllocationResize1D(long con, long id, int dimX);
+    synchronized void nAllocationResize1D(long id, int dimX) {
         validate();
         rsnAllocationResize1D(mContext, id, dimX);
     }
 
-    native int  rsnFileA3DCreateFromAssetStream(int con, int assetStream);
-    synchronized int nFileA3DCreateFromAssetStream(int assetStream) {
+    native long rsnFileA3DCreateFromAssetStream(long con, int assetStream);
+    synchronized long nFileA3DCreateFromAssetStream(int assetStream) {
         validate();
         return rsnFileA3DCreateFromAssetStream(mContext, assetStream);
     }
-    native int  rsnFileA3DCreateFromFile(int con, String path);
-    synchronized int nFileA3DCreateFromFile(String path) {
+    native long rsnFileA3DCreateFromFile(long con, String path);
+    synchronized long nFileA3DCreateFromFile(String path) {
         validate();
         return rsnFileA3DCreateFromFile(mContext, path);
     }
-    native int  rsnFileA3DCreateFromAsset(int con, AssetManager mgr, String path);
-    synchronized int nFileA3DCreateFromAsset(AssetManager mgr, String path) {
+    native long rsnFileA3DCreateFromAsset(long con, AssetManager mgr, String path);
+    synchronized long nFileA3DCreateFromAsset(AssetManager mgr, String path) {
         validate();
         return rsnFileA3DCreateFromAsset(mContext, mgr, path);
     }
-    native int  rsnFileA3DGetNumIndexEntries(int con, int fileA3D);
-    synchronized int nFileA3DGetNumIndexEntries(int fileA3D) {
+    native int  rsnFileA3DGetNumIndexEntries(long con, long fileA3D);
+    synchronized int nFileA3DGetNumIndexEntries(long fileA3D) {
         validate();
         return rsnFileA3DGetNumIndexEntries(mContext, fileA3D);
     }
-    native void rsnFileA3DGetIndexEntries(int con, int fileA3D, int numEntries, int[] IDs, String[] names);
-    synchronized void nFileA3DGetIndexEntries(int fileA3D, int numEntries, int[] IDs, String[] names) {
+    native void rsnFileA3DGetIndexEntries(long con, long fileA3D, int numEntries, int[] IDs, String[] names);
+    synchronized void nFileA3DGetIndexEntries(long fileA3D, int numEntries, int[] IDs, String[] names) {
         validate();
         rsnFileA3DGetIndexEntries(mContext, fileA3D, numEntries, IDs, names);
     }
-    native int  rsnFileA3DGetEntryByIndex(int con, int fileA3D, int index);
-    synchronized int nFileA3DGetEntryByIndex(int fileA3D, int index) {
+    native int  rsnFileA3DGetEntryByIndex(long con, long fileA3D, int index);
+    synchronized int nFileA3DGetEntryByIndex(long fileA3D, int index) {
         validate();
         return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index);
     }
 
-    native int  rsnFontCreateFromFile(int con, String fileName, float size, int dpi);
+    native int  rsnFontCreateFromFile(long con, String fileName, float size, int dpi);
     synchronized int nFontCreateFromFile(String fileName, float size, int dpi) {
         validate();
         return rsnFontCreateFromFile(mContext, fileName, size, dpi);
     }
-    native int  rsnFontCreateFromAssetStream(int con, String name, float size, int dpi, int assetStream);
+    native int  rsnFontCreateFromAssetStream(long con, String name, float size, int dpi, int assetStream);
     synchronized int nFontCreateFromAssetStream(String name, float size, int dpi, int assetStream) {
         validate();
         return rsnFontCreateFromAssetStream(mContext, name, size, dpi, assetStream);
     }
-    native int  rsnFontCreateFromAsset(int con, AssetManager mgr, String path, float size, int dpi);
+    native int  rsnFontCreateFromAsset(long con, AssetManager mgr, String path, float size, int dpi);
     synchronized int nFontCreateFromAsset(AssetManager mgr, String path, float size, int dpi) {
         validate();
         return rsnFontCreateFromAsset(mContext, mgr, path, size, dpi);
     }
 
 
-    native void rsnScriptBindAllocation(int con, int script, int alloc, int slot);
-    synchronized void nScriptBindAllocation(int script, int alloc, int slot) {
+    native void rsnScriptBindAllocation(long con, long script, long alloc, int slot);
+    synchronized void nScriptBindAllocation(long script, long alloc, int slot) {
         validate();
         rsnScriptBindAllocation(mContext, script, alloc, slot);
     }
-    native void rsnScriptSetTimeZone(int con, int script, byte[] timeZone);
-    synchronized void nScriptSetTimeZone(int script, byte[] timeZone) {
+    native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone);
+    synchronized void nScriptSetTimeZone(long script, byte[] timeZone) {
         validate();
         rsnScriptSetTimeZone(mContext, script, timeZone);
     }
-    native void rsnScriptInvoke(int con, int id, int slot);
-    synchronized void nScriptInvoke(int id, int slot) {
+    native void rsnScriptInvoke(long con, long id, int slot);
+    synchronized void nScriptInvoke(long id, int slot) {
         validate();
         rsnScriptInvoke(mContext, id, slot);
     }
-    native void rsnScriptForEach(int con, int id, int slot, int ain, int aout, byte[] params);
-    native void rsnScriptForEach(int con, int id, int slot, int ain, int aout);
-    native void rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout, byte[] params,
+    native void rsnScriptForEach(long con, long id, int slot, long ain, long aout, byte[] params);
+    native void rsnScriptForEach(long con, long id, int slot, long ain, long aout);
+    native void rsnScriptForEachClipped(long con, long id, int slot, long ain, long aout, byte[] params,
                                         int xstart, int xend, int ystart, int yend, int zstart, int zend);
-    native void rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout,
+    native void rsnScriptForEachClipped(long con, long id, int slot, long ain, long aout,
                                         int xstart, int xend, int ystart, int yend, int zstart, int zend);
-    synchronized void nScriptForEach(int id, int slot, int ain, int aout, byte[] params) {
+    synchronized void nScriptForEach(long id, int slot, long ain, long aout, byte[] params) {
         validate();
         if (params == null) {
             rsnScriptForEach(mContext, id, slot, ain, aout);
@@ -609,7 +565,7 @@
         }
     }
 
-    synchronized void nScriptForEachClipped(int id, int slot, int ain, int aout, byte[] params,
+    synchronized void nScriptForEachClipped(long id, int slot, long ain, long aout, byte[] params,
                                             int xstart, int xend, int ystart, int yend, int zstart, int zend) {
         validate();
         if (params == null) {
@@ -619,127 +575,127 @@
         }
     }
 
-    native void rsnScriptInvokeV(int con, int id, int slot, byte[] params);
-    synchronized void nScriptInvokeV(int id, int slot, byte[] params) {
+    native void rsnScriptInvokeV(long con, long id, int slot, byte[] params);
+    synchronized void nScriptInvokeV(long id, int slot, byte[] params) {
         validate();
         rsnScriptInvokeV(mContext, id, slot, params);
     }
 
-    native void rsnScriptSetVarI(int con, int id, int slot, int val);
-    synchronized void nScriptSetVarI(int id, int slot, int val) {
+    native void rsnScriptSetVarI(long con, long id, int slot, int val);
+    synchronized void nScriptSetVarI(long id, int slot, int val) {
         validate();
         rsnScriptSetVarI(mContext, id, slot, val);
     }
-    native int rsnScriptGetVarI(int con, int id, int slot);
-    synchronized int nScriptGetVarI(int id, int slot) {
+    native int rsnScriptGetVarI(long con, long id, int slot);
+    synchronized int nScriptGetVarI(long id, int slot) {
         validate();
         return rsnScriptGetVarI(mContext, id, slot);
     }
 
-    native void rsnScriptSetVarJ(int con, int id, int slot, long val);
-    synchronized void nScriptSetVarJ(int id, int slot, long val) {
+    native void rsnScriptSetVarJ(long con, long id, int slot, long val);
+    synchronized void nScriptSetVarJ(long id, int slot, long val) {
         validate();
         rsnScriptSetVarJ(mContext, id, slot, val);
     }
-    native long rsnScriptGetVarJ(int con, int id, int slot);
-    synchronized long nScriptGetVarJ(int id, int slot) {
+    native long rsnScriptGetVarJ(long con, long id, int slot);
+    synchronized long nScriptGetVarJ(long id, int slot) {
         validate();
         return rsnScriptGetVarJ(mContext, id, slot);
     }
 
-    native void rsnScriptSetVarF(int con, int id, int slot, float val);
-    synchronized void nScriptSetVarF(int id, int slot, float val) {
+    native void rsnScriptSetVarF(long con, long id, int slot, float val);
+    synchronized void nScriptSetVarF(long id, int slot, float val) {
         validate();
         rsnScriptSetVarF(mContext, id, slot, val);
     }
-    native float rsnScriptGetVarF(int con, int id, int slot);
-    synchronized float nScriptGetVarF(int id, int slot) {
+    native float rsnScriptGetVarF(long con, long id, int slot);
+    synchronized float nScriptGetVarF(long id, int slot) {
         validate();
         return rsnScriptGetVarF(mContext, id, slot);
     }
-    native void rsnScriptSetVarD(int con, int id, int slot, double val);
-    synchronized void nScriptSetVarD(int id, int slot, double val) {
+    native void rsnScriptSetVarD(long con, long id, int slot, double val);
+    synchronized void nScriptSetVarD(long id, int slot, double val) {
         validate();
         rsnScriptSetVarD(mContext, id, slot, val);
     }
-    native double rsnScriptGetVarD(int con, int id, int slot);
-    synchronized double nScriptGetVarD(int id, int slot) {
+    native double rsnScriptGetVarD(long con, long id, int slot);
+    synchronized double nScriptGetVarD(long id, int slot) {
         validate();
         return rsnScriptGetVarD(mContext, id, slot);
     }
-    native void rsnScriptSetVarV(int con, int id, int slot, byte[] val);
-    synchronized void nScriptSetVarV(int id, int slot, byte[] val) {
+    native void rsnScriptSetVarV(long con, long id, int slot, byte[] val);
+    synchronized void nScriptSetVarV(long id, int slot, byte[] val) {
         validate();
         rsnScriptSetVarV(mContext, id, slot, val);
     }
-    native void rsnScriptGetVarV(int con, int id, int slot, byte[] val);
-    synchronized void nScriptGetVarV(int id, int slot, byte[] val) {
+    native void rsnScriptGetVarV(long con, long id, int slot, byte[] val);
+    synchronized void nScriptGetVarV(long id, int slot, byte[] val) {
         validate();
         rsnScriptGetVarV(mContext, id, slot, val);
     }
-    native void rsnScriptSetVarVE(int con, int id, int slot, byte[] val,
-                                  int e, int[] dims);
-    synchronized void nScriptSetVarVE(int id, int slot, byte[] val,
-                                      int e, int[] dims) {
+    native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val,
+                                  long e, int[] dims);
+    synchronized void nScriptSetVarVE(long id, int slot, byte[] val,
+                                      long e, int[] dims) {
         validate();
         rsnScriptSetVarVE(mContext, id, slot, val, e, dims);
     }
-    native void rsnScriptSetVarObj(int con, int id, int slot, int val);
-    synchronized void nScriptSetVarObj(int id, int slot, int val) {
+    native void rsnScriptSetVarObj(long con, long id, int slot, long val);
+    synchronized void nScriptSetVarObj(long id, int slot, long val) {
         validate();
         rsnScriptSetVarObj(mContext, id, slot, val);
     }
 
-    native int  rsnScriptCCreate(int con, String resName, String cacheDir,
+    native int  rsnScriptCCreate(long con, String resName, String cacheDir,
                                  byte[] script, int length);
     synchronized int nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
         validate();
         return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
     }
 
-    native int  rsnScriptIntrinsicCreate(int con, int id, int eid);
-    synchronized int nScriptIntrinsicCreate(int id, int eid) {
+    native long rsnScriptIntrinsicCreate(long con, int id, long eid);
+    synchronized long nScriptIntrinsicCreate(int id, long eid) {
         validate();
         return rsnScriptIntrinsicCreate(mContext, id, eid);
     }
 
-    native int  rsnScriptKernelIDCreate(int con, int sid, int slot, int sig);
-    synchronized int nScriptKernelIDCreate(int sid, int slot, int sig) {
+    native long  rsnScriptKernelIDCreate(long con, long sid, int slot, int sig);
+    synchronized long nScriptKernelIDCreate(long sid, int slot, int sig) {
         validate();
         return rsnScriptKernelIDCreate(mContext, sid, slot, sig);
     }
 
-    native int  rsnScriptFieldIDCreate(int con, int sid, int slot);
-    synchronized int nScriptFieldIDCreate(int sid, int slot) {
+    native long  rsnScriptFieldIDCreate(long con, long sid, int slot);
+    synchronized long nScriptFieldIDCreate(long sid, int slot) {
         validate();
         return rsnScriptFieldIDCreate(mContext, sid, slot);
     }
 
-    native int  rsnScriptGroupCreate(int con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types);
-    synchronized int nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types) {
+    native long rsnScriptGroupCreate(long con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types);
+    synchronized long nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types) {
         validate();
         return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
     }
 
-    native void rsnScriptGroupSetInput(int con, int group, int kernel, int alloc);
-    synchronized void nScriptGroupSetInput(int group, int kernel, int alloc) {
+    native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc);
+    synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) {
         validate();
         rsnScriptGroupSetInput(mContext, group, kernel, alloc);
     }
 
-    native void rsnScriptGroupSetOutput(int con, int group, int kernel, int alloc);
-    synchronized void nScriptGroupSetOutput(int group, int kernel, int alloc) {
+    native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc);
+    synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) {
         validate();
         rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
     }
 
-    native void rsnScriptGroupExecute(int con, int group);
-    synchronized void nScriptGroupExecute(int group) {
+    native void rsnScriptGroupExecute(long con, long group);
+    synchronized void nScriptGroupExecute(long group) {
         validate();
         rsnScriptGroupExecute(mContext, group);
     }
 
-    native int  rsnSamplerCreate(int con, int magFilter, int minFilter,
+    native int  rsnSamplerCreate(long con, int magFilter, int minFilter,
                                  int wrapS, int wrapT, int wrapR, float aniso);
     synchronized int nSamplerCreate(int magFilter, int minFilter,
                                  int wrapS, int wrapT, int wrapR, float aniso) {
@@ -747,7 +703,7 @@
         return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
     }
 
-    native int  rsnProgramStoreCreate(int con, boolean r, boolean g, boolean b, boolean a,
+    native int  rsnProgramStoreCreate(long con, boolean r, boolean g, boolean b, boolean a,
                                       boolean depthMask, boolean dither,
                                       int srcMode, int dstMode, int depthFunc);
     synchronized int nProgramStoreCreate(boolean r, boolean g, boolean b, boolean a,
@@ -758,72 +714,72 @@
                                      dstMode, depthFunc);
     }
 
-    native int  rsnProgramRasterCreate(int con, boolean pointSprite, int cullMode);
-    synchronized int nProgramRasterCreate(boolean pointSprite, int cullMode) {
+    native long rsnProgramRasterCreate(long con, boolean pointSprite, int cullMode);
+    synchronized long nProgramRasterCreate(boolean pointSprite, int cullMode) {
         validate();
         return rsnProgramRasterCreate(mContext, pointSprite, cullMode);
     }
 
-    native void rsnProgramBindConstants(int con, int pv, int slot, int mID);
-    synchronized void nProgramBindConstants(int pv, int slot, int mID) {
+    native void rsnProgramBindConstants(long con, long pv, int slot, long mID);
+    synchronized void nProgramBindConstants(long pv, int slot, long mID) {
         validate();
         rsnProgramBindConstants(mContext, pv, slot, mID);
     }
-    native void rsnProgramBindTexture(int con, int vpf, int slot, int a);
-    synchronized void nProgramBindTexture(int vpf, int slot, int a) {
+    native void rsnProgramBindTexture(long con, long vpf, int slot, long a);
+    synchronized void nProgramBindTexture(long vpf, int slot, long a) {
         validate();
         rsnProgramBindTexture(mContext, vpf, slot, a);
     }
-    native void rsnProgramBindSampler(int con, int vpf, int slot, int s);
-    synchronized void nProgramBindSampler(int vpf, int slot, int s) {
+    native void rsnProgramBindSampler(long con, long vpf, int slot, long s);
+    synchronized void nProgramBindSampler(long vpf, int slot, long s) {
         validate();
         rsnProgramBindSampler(mContext, vpf, slot, s);
     }
-    native int  rsnProgramFragmentCreate(int con, String shader, String[] texNames, int[] params);
-    synchronized int nProgramFragmentCreate(String shader, String[] texNames, int[] params) {
+    native long rsnProgramFragmentCreate(long con, String shader, String[] texNames, int[] params);
+    synchronized long nProgramFragmentCreate(String shader, String[] texNames, int[] params) {
         validate();
         return rsnProgramFragmentCreate(mContext, shader, texNames, params);
     }
-    native int  rsnProgramVertexCreate(int con, String shader, String[] texNames, int[] params);
-    synchronized int nProgramVertexCreate(String shader, String[] texNames, int[] params) {
+    native long rsnProgramVertexCreate(long con, String shader, String[] texNames, int[] params);
+    synchronized long nProgramVertexCreate(String shader, String[] texNames, int[] params) {
         validate();
         return rsnProgramVertexCreate(mContext, shader, texNames, params);
     }
 
-    native int  rsnMeshCreate(int con, int[] vtx, int[] idx, int[] prim);
-    synchronized int nMeshCreate(int[] vtx, int[] idx, int[] prim) {
+    native long rsnMeshCreate(long con, int[] vtx, int[] idx, int[] prim);
+    synchronized long nMeshCreate(int[] vtx, int[] idx, int[] prim) {
         validate();
         return rsnMeshCreate(mContext, vtx, idx, prim);
     }
-    native int  rsnMeshGetVertexBufferCount(int con, int id);
-    synchronized int nMeshGetVertexBufferCount(int id) {
+    native int  rsnMeshGetVertexBufferCount(long con, long id);
+    synchronized int nMeshGetVertexBufferCount(long id) {
         validate();
         return rsnMeshGetVertexBufferCount(mContext, id);
     }
-    native int  rsnMeshGetIndexCount(int con, int id);
-    synchronized int nMeshGetIndexCount(int id) {
+    native int  rsnMeshGetIndexCount(long con, long id);
+    synchronized int nMeshGetIndexCount(long id) {
         validate();
         return rsnMeshGetIndexCount(mContext, id);
     }
-    native void rsnMeshGetVertices(int con, int id, int[] vtxIds, int vtxIdCount);
-    synchronized void nMeshGetVertices(int id, int[] vtxIds, int vtxIdCount) {
+    native void rsnMeshGetVertices(long con, long id, int[] vtxIds, int vtxIdCount);
+    synchronized void nMeshGetVertices(long id, int[] vtxIds, int vtxIdCount) {
         validate();
         rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount);
     }
-    native void rsnMeshGetIndices(int con, int id, int[] idxIds, int[] primitives, int vtxIdCount);
-    synchronized void nMeshGetIndices(int id, int[] idxIds, int[] primitives, int vtxIdCount) {
+    native void rsnMeshGetIndices(long con, long id, int[] idxIds, int[] primitives, int vtxIdCount);
+    synchronized void nMeshGetIndices(long id, int[] idxIds, int[] primitives, int vtxIdCount) {
         validate();
         rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount);
     }
 
-    native int  rsnPathCreate(int con, int prim, boolean isStatic, int vtx, int loop, float q);
-    synchronized int nPathCreate(int prim, boolean isStatic, int vtx, int loop, float q) {
+    native long rsnPathCreate(long con, int prim, boolean isStatic, long vtx, int loop, float q);
+    synchronized long nPathCreate(int prim, boolean isStatic, long vtx, int loop, float q) {
         validate();
         return rsnPathCreate(mContext, prim, isStatic, vtx, loop, q);
     }
 
-    int     mDev;
-    int     mContext;
+    long     mDev;
+    long     mContext;
     @SuppressWarnings({"FieldCanBeLocal"})
     MessageThread mMessageThread;
 
@@ -1248,7 +1204,7 @@
         return mContext != 0;
     }
 
-    int safeID(BaseObj o) {
+    long safeID(BaseObj o) {
         if(o != null) {
             return o.getID(this);
         }
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index bac9c68..714e835 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -16,17 +16,10 @@
 
 package android.renderscript;
 
-import java.lang.reflect.Field;
-
 import android.content.Context;
-import android.graphics.PixelFormat;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.graphics.SurfaceTexture;
-import android.util.Log;
 import android.view.Surface;
 import android.view.SurfaceHolder;
-import android.view.SurfaceView;
 
 /**
  * @hide
@@ -286,7 +279,7 @@
      */
     public void bindRootScript(Script s) {
         validate();
-        nContextBindRootScript(safeID(s));
+        nContextBindRootScript((int)safeID(s));
     }
 
     /**
@@ -298,7 +291,7 @@
      */
     public void bindProgramStore(ProgramStore p) {
         validate();
-        nContextBindProgramStore(safeID(p));
+        nContextBindProgramStore((int)safeID(p));
     }
 
     /**
@@ -310,7 +303,7 @@
      */
     public void bindProgramFragment(ProgramFragment p) {
         validate();
-        nContextBindProgramFragment(safeID(p));
+        nContextBindProgramFragment((int)safeID(p));
     }
 
     /**
@@ -322,7 +315,7 @@
      */
     public void bindProgramRaster(ProgramRaster p) {
         validate();
-        nContextBindProgramRaster(safeID(p));
+        nContextBindProgramRaster((int)safeID(p));
     }
 
     /**
@@ -334,7 +327,7 @@
      */
     public void bindProgramVertex(ProgramVertex p) {
         validate();
-        nContextBindProgramVertex(safeID(p));
+        nContextBindProgramVertex((int)safeID(p));
     }
 
 }
diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java
index 623055fe..39b867b 100644
--- a/graphics/java/android/renderscript/Sampler.java
+++ b/graphics/java/android/renderscript/Sampler.java
@@ -16,17 +16,6 @@
 
 package android.renderscript;
 
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.util.Log;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-
 /**
  * Sampler object that defines how Allocations can be read as textures within a
  * kernel. Samplers are used in conjunction with the {@code rsSample} runtime
diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java
index 0026e0e..5ab18f7 100644
--- a/graphics/java/android/renderscript/Script.java
+++ b/graphics/java/android/renderscript/Script.java
@@ -36,7 +36,7 @@
         Script mScript;
         int mSlot;
         int mSig;
-        KernelID(int id, RenderScript rs, Script s, int slot, int sig) {
+        KernelID(long id, RenderScript rs, Script s, int slot, int sig) {
             super(id, rs);
             mScript = s;
             mSlot = slot;
@@ -54,7 +54,7 @@
             return k;
         }
 
-        int id = mRS.nScriptKernelIDCreate(getID(mRS), slot, sig);
+        long id = mRS.nScriptKernelIDCreate(getID(mRS), slot, sig);
         if (id == 0) {
             throw new RSDriverException("Failed to create KernelID");
         }
@@ -75,7 +75,7 @@
     public static final class FieldID extends BaseObj {
         Script mScript;
         int mSlot;
-        FieldID(int id, RenderScript rs, Script s, int slot) {
+        FieldID(long id, RenderScript rs, Script s, int slot) {
             super(id, rs);
             mScript = s;
             mSlot = slot;
@@ -92,7 +92,7 @@
             return f;
         }
 
-        int id = mRS.nScriptFieldIDCreate(getID(mRS), slot);
+        long id = mRS.nScriptFieldIDCreate(getID(mRS), slot);
         if (id == 0) {
             throw new RSDriverException("Failed to create FieldID");
         }
@@ -132,11 +132,11 @@
             throw new RSIllegalArgumentException(
                 "At least one of ain or aout is required to be non-null.");
         }
-        int in_id = 0;
+        long in_id = 0;
         if (ain != null) {
             in_id = ain.getID(mRS);
         }
-        int out_id = 0;
+        long out_id = 0;
         if (aout != null) {
             out_id = aout.getID(mRS);
         }
@@ -161,11 +161,11 @@
             forEach(slot, ain, aout, v);
             return;
         }
-        int in_id = 0;
+        long in_id = 0;
         if (ain != null) {
             in_id = ain.getID(mRS);
         }
-        int out_id = 0;
+        long out_id = 0;
         if (aout != null) {
             out_id = aout.getID(mRS);
         }
@@ -176,7 +176,7 @@
         mRS.nScriptForEachClipped(getID(mRS), slot, in_id, out_id, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend);
     }
 
-    Script(int id, RenderScript rs) {
+    Script(long id, RenderScript rs) {
         super(id, rs);
     }
 
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index b0a5759..c7979f6 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -16,18 +16,11 @@
 
 package android.renderscript;
 
-import android.content.Context;
 import android.content.res.Resources;
-import android.util.Log;
 
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Map.Entry;
-import java.util.HashMap;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
 
 /**
  * The superclass for all user-defined scripts. This is only
diff --git a/graphics/java/android/renderscript/ScriptGroup.java b/graphics/java/android/renderscript/ScriptGroup.java
index 1416641..f1a7273 100644
--- a/graphics/java/android/renderscript/ScriptGroup.java
+++ b/graphics/java/android/renderscript/ScriptGroup.java
@@ -16,7 +16,6 @@
 
 package android.renderscript;
 
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 
 /**
@@ -89,7 +88,7 @@
     }
 
 
-    ScriptGroup(int id, RenderScript rs) {
+    ScriptGroup(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -380,6 +379,7 @@
          * @return ScriptGroup The new ScriptGroup
          */
         public ScriptGroup create() {
+            // FIXME: this is broken for 64-bit
 
             if (mNodes.size() == 0) {
                 throw new RSInvalidStateException("Empty script groups are not allowed");
@@ -400,7 +400,7 @@
                 Node n = mNodes.get(ct);
                 for (int ct2=0; ct2 < n.mKernels.size(); ct2++) {
                     final Script.KernelID kid = n.mKernels.get(ct2);
-                    kernels[idx++] = kid.getID(mRS);
+                    kernels[idx++] = (int)kid.getID(mRS);
 
                     boolean hasInput = false;
                     boolean hasOutput = false;
@@ -434,17 +434,17 @@
 
             for (int ct=0; ct < mLines.size(); ct++) {
                 ConnectLine cl = mLines.get(ct);
-                src[ct] = cl.mFrom.getID(mRS);
+                src[ct] = (int)cl.mFrom.getID(mRS);
                 if (cl.mToK != null) {
-                    dstk[ct] = cl.mToK.getID(mRS);
+                    dstk[ct] = (int)cl.mToK.getID(mRS);
                 }
                 if (cl.mToF != null) {
-                    dstf[ct] = cl.mToF.getID(mRS);
+                    dstf[ct] = (int)cl.mToF.getID(mRS);
                 }
-                types[ct] = cl.mAllocationType.getID(mRS);
+                types[ct] = (int)cl.mAllocationType.getID(mRS);
             }
 
-            int id = mRS.nScriptGroupCreate(kernels, src, dstk, dstf, types);
+            long id = mRS.nScriptGroupCreate(kernels, src, dstk, dstf, types);
             if (id == 0) {
                 throw new RSRuntimeException("Object creation error, should not happen.");
             }
diff --git a/graphics/java/android/renderscript/ScriptIntrinsic.java b/graphics/java/android/renderscript/ScriptIntrinsic.java
index 096268a..8719e017 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsic.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsic.java
@@ -25,7 +25,7 @@
  * Not intended for direct use.
  **/
 public abstract class ScriptIntrinsic extends Script {
-    ScriptIntrinsic(int id, RenderScript rs) {
+    ScriptIntrinsic(long id, RenderScript rs) {
         super(id, rs);
     }
 }
diff --git a/graphics/java/android/renderscript/ScriptIntrinsic3DLUT.java b/graphics/java/android/renderscript/ScriptIntrinsic3DLUT.java
index 34540a1..33e64bd 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsic3DLUT.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsic3DLUT.java
@@ -16,8 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
-
 /**
  *
  * Intrinsic for converting RGB to RGBA by using a 3D lookup table.  The
@@ -30,7 +28,7 @@
     private Allocation mLUT;
     private Element mElement;
 
-    private ScriptIntrinsic3DLUT(int id, RenderScript rs, Element e) {
+    private ScriptIntrinsic3DLUT(long id, RenderScript rs, Element e) {
         super(id, rs);
         mElement = e;
     }
@@ -46,7 +44,7 @@
      * @return ScriptIntrinsic3DLUT
      */
     public static ScriptIntrinsic3DLUT create(RenderScript rs, Element e) {
-        int id = rs.nScriptIntrinsicCreate(8, e.getID(rs));
+        long id = rs.nScriptIntrinsicCreate(8, e.getID(rs));
 
         if (!e.isCompatible(Element.U8_4(rs))) {
             throw new RSIllegalArgumentException("Element must be compatible with uchar4.");
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicBlend.java b/graphics/java/android/renderscript/ScriptIntrinsicBlend.java
index 0e05bc8..40f1a3e 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicBlend.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicBlend.java
@@ -21,7 +21,7 @@
  * Intrinsic kernels for blending two {@link android.renderscript.Allocation} objects.
  **/
 public class ScriptIntrinsicBlend extends ScriptIntrinsic {
-    ScriptIntrinsicBlend(int id, RenderScript rs) {
+    ScriptIntrinsicBlend(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -35,7 +35,7 @@
      */
     public static ScriptIntrinsicBlend create(RenderScript rs, Element e) {
         // 7 comes from RS_SCRIPT_INTRINSIC_ID_BLEND in rsDefines.h
-        int id = rs.nScriptIntrinsicCreate(7, e.getID(rs));
+        long id = rs.nScriptIntrinsicCreate(7, e.getID(rs));
         return new ScriptIntrinsicBlend(id, rs);
 
     }
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
index aaf5ffc..2b36d27 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
@@ -16,10 +16,6 @@
 
 package android.renderscript;
 
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
 /**
  * Intrinsic Gausian blur filter. Applies a gaussian blur of the
  * specified radius to all elements of an allocation.
@@ -30,7 +26,7 @@
     private final float[] mValues = new float[9];
     private Allocation mInput;
 
-    private ScriptIntrinsicBlur(int id, RenderScript rs) {
+    private ScriptIntrinsicBlur(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -49,7 +45,7 @@
         if ((!e.isCompatible(Element.U8_4(rs))) && (!e.isCompatible(Element.U8(rs)))) {
             throw new RSIllegalArgumentException("Unsuported element type.");
         }
-        int id = rs.nScriptIntrinsicCreate(5, e.getID(rs));
+        long id = rs.nScriptIntrinsicCreate(5, e.getID(rs));
         ScriptIntrinsicBlur sib = new ScriptIntrinsicBlur(id, rs);
         sib.setRadius(5.f);
         return sib;
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java b/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
index 32c3d15..4b0d507 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
@@ -16,8 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
-
 /**
  * Intrinsic for applying a color matrix to allocations.
  *
@@ -43,7 +41,7 @@
     private final Matrix4f mMatrix = new Matrix4f();
     private final Float4 mAdd = new Float4();
 
-    private ScriptIntrinsicColorMatrix(int id, RenderScript rs) {
+    private ScriptIntrinsicColorMatrix(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -75,7 +73,7 @@
      * @return ScriptIntrinsicColorMatrix
      */
     public static ScriptIntrinsicColorMatrix create(RenderScript rs) {
-        int id = rs.nScriptIntrinsicCreate(2, 0);
+        long id = rs.nScriptIntrinsicCreate(2, 0);
         return new ScriptIntrinsicColorMatrix(id, rs);
 
     }
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
index 5d3c1d3..a1a1b7e 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
@@ -16,8 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
-
 /**
  * Intrinsic for applying a 3x3 convolve to an allocation.
  *
@@ -26,7 +24,7 @@
     private final float[] mValues = new float[9];
     private Allocation mInput;
 
-    private ScriptIntrinsicConvolve3x3(int id, RenderScript rs) {
+    private ScriptIntrinsicConvolve3x3(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -61,7 +59,7 @@
             !e.isCompatible(Element.F32_4(rs))) {
             throw new RSIllegalArgumentException("Unsuported element type.");
         }
-        int id = rs.nScriptIntrinsicCreate(1, e.getID(rs));
+        long id = rs.nScriptIntrinsicCreate(1, e.getID(rs));
         ScriptIntrinsicConvolve3x3 si = new ScriptIntrinsicConvolve3x3(id, rs);
         si.setCoefficients(f);
         return si;
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
index ad09f95..8b66896 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
@@ -16,8 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
-
 /**
  * Intrinsic for applying a 5x5 convolve to an allocation.
  *
@@ -26,7 +24,7 @@
     private final float[] mValues = new float[25];
     private Allocation mInput;
 
-    private ScriptIntrinsicConvolve5x5(int id, RenderScript rs) {
+    private ScriptIntrinsicConvolve5x5(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -62,7 +60,7 @@
             throw new RSIllegalArgumentException("Unsuported element type.");
         }
 
-        int id = rs.nScriptIntrinsicCreate(4, e.getID(rs));
+        long id = rs.nScriptIntrinsicCreate(4, e.getID(rs));
         return new ScriptIntrinsicConvolve5x5(id, rs);
 
     }
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicHistogram.java b/graphics/java/android/renderscript/ScriptIntrinsicHistogram.java
index adc2d95..536663d 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicHistogram.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicHistogram.java
@@ -16,10 +16,6 @@
 
 package android.renderscript;
 
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
 /**
  * Intrinsic Histogram filter.
  *
@@ -28,7 +24,7 @@
 public final class ScriptIntrinsicHistogram extends ScriptIntrinsic {
     private Allocation mOut;
 
-    private ScriptIntrinsicHistogram(int id, RenderScript rs) {
+    private ScriptIntrinsicHistogram(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -52,7 +48,7 @@
             (!e.isCompatible(Element.U8(rs)))) {
             throw new RSIllegalArgumentException("Unsuported element type.");
         }
-        int id = rs.nScriptIntrinsicCreate(9, e.getID(rs));
+        long id = rs.nScriptIntrinsicCreate(9, e.getID(rs));
         ScriptIntrinsicHistogram sib = new ScriptIntrinsicHistogram(id, rs);
         return sib;
     }
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java
index 0f7ab38..001095c 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java
@@ -16,8 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
-
 /**
  * Intrinsic for applying a per-channel lookup table. Each
  * channel of the input has an independant lookup table. The
@@ -30,7 +28,7 @@
     private final byte mCache[] = new byte[1024];
     private boolean mDirty = true;
 
-    private ScriptIntrinsicLUT(int id, RenderScript rs) {
+    private ScriptIntrinsicLUT(long id, RenderScript rs) {
         super(id, rs);
         mTables = Allocation.createSized(rs, Element.U8(rs), 1024);
         for (int ct=0; ct < 256; ct++) {
@@ -53,7 +51,7 @@
      * @return ScriptIntrinsicLUT
      */
     public static ScriptIntrinsicLUT create(RenderScript rs, Element e) {
-        int id = rs.nScriptIntrinsicCreate(3, e.getID(rs));
+        long id = rs.nScriptIntrinsicCreate(3, e.getID(rs));
         return new ScriptIntrinsicLUT(id, rs);
 
     }
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
index 845625d..f942982 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
@@ -27,7 +27,7 @@
 public final class ScriptIntrinsicYuvToRGB extends ScriptIntrinsic {
     private Allocation mInput;
 
-    ScriptIntrinsicYuvToRGB(int id, RenderScript rs) {
+    ScriptIntrinsicYuvToRGB(long id, RenderScript rs) {
         super(id, rs);
     }
 
@@ -43,7 +43,7 @@
      */
     public static ScriptIntrinsicYuvToRGB create(RenderScript rs, Element e) {
         // 6 comes from RS_SCRIPT_INTRINSIC_YUV_TO_RGB in rsDefines.h
-        int id = rs.nScriptIntrinsicCreate(6, e.getID(rs));
+        long id = rs.nScriptIntrinsicCreate(6, e.getID(rs));
         ScriptIntrinsicYuvToRGB si = new ScriptIntrinsicYuvToRGB(id, rs);
         return si;
     }
diff --git a/graphics/java/android/renderscript/Short2.java b/graphics/java/android/renderscript/Short2.java
index 7c6027f..24809f7 100644
--- a/graphics/java/android/renderscript/Short2.java
+++ b/graphics/java/android/renderscript/Short2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -16,27 +16,428 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
 
 /**
  * Class for exposing the native RenderScript Short2 type back to the Android system.
  *
- **/
+ * Vector version of the basic short type.
+ * Provides two short fields packed.
+ */
 public class Short2 {
+    public short x;
+    public short y;
+
     public Short2() {
     }
 
-    public Short2(short initX, short initY) {
-        x = initX;
-        y = initY;
+    /** @hide */
+    public Short2(short i) {
+        this.x = this.y = i;
     }
 
-    public short x;
-    public short y;
+    public Short2(short x, short y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /** @hide */
+    public Short2(Short2 source) {
+        this.x = source.x;
+        this.y = source.y;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     */
+    public void add(Short2 a) {
+        this.x += a.x;
+        this.y += a.y;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short2 add(Short2 a, Short2 b) {
+        Short2 result = new Short2();
+        result.x = (short)(a.x + b.x);
+        result.y = (short)(a.y + b.y);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(short value) {
+        x += value;
+        y += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short2 add(Short2 a, short b) {
+        Short2 result = new Short2();
+        result.x = (short)(a.x + b);
+        result.y = (short)(a.y + b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     */
+    public void sub(Short2 a) {
+        this.x -= a.x;
+        this.y -= a.y;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short2 sub(Short2 a, Short2 b) {
+        Short2 result = new Short2();
+        result.x = (short)(a.x - b.x);
+        result.y = (short)(a.y - b.y);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(short value) {
+        x -= value;
+        y -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short2 sub(Short2 a, short b) {
+        Short2 result = new Short2();
+        result.x = (short)(a.x - b);
+        result.y = (short)(a.y - b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     */
+    public void mul(Short2 a) {
+        this.x *= a.x;
+        this.y *= a.y;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short2 mul(Short2 a, Short2 b) {
+        Short2 result = new Short2();
+        result.x = (short)(a.x * b.x);
+        result.y = (short)(a.y * b.y);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(short value) {
+        x *= value;
+        y *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short2 mul(Short2 a, short b) {
+        Short2 result = new Short2();
+        result.x = (short)(a.x * b);
+        result.y = (short)(a.y * b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     */
+    public void div(Short2 a) {
+        this.x /= a.x;
+        this.y /= a.y;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short2 div(Short2 a, Short2 b) {
+        Short2 result = new Short2();
+        result.x = (short)(a.x / b.x);
+        result.y = (short)(a.y / b.y);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(short value) {
+        x /= value;
+        y /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short2 div(Short2 a, short b) {
+        Short2 result = new Short2();
+        result.x = (short)(a.x / b);
+        result.y = (short)(a.y / b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     */
+    public void mod(Short2 a) {
+        this.x %= a.x;
+        this.y %= a.y;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short2 mod(Short2 a, Short2 b) {
+        Short2 result = new Short2();
+        result.x = (short)(a.x % b.x);
+        result.y = (short)(a.y % b.y);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param value
+     */
+    public void mod(short value) {
+        x %= value;
+        y %= value;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short2 mod(Short2 a, short b) {
+        Short2 result = new Short2();
+        result.x = (short)(a.x % b);
+        result.y = (short)(a.y % b);
+
+        return result;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public short length() {
+        return 2;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        this.x = (short)(-x);
+        this.y = (short)(-y);
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public short dotProduct(Short2 a) {
+        return (short)((x * a.x) + (y * a.y));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static short dotProduct(Short2 a, Short2 b) {
+        return (short)((b.x * a.x) + (b.y * a.y));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Short2 a, short factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+    }
+
+    /** @hide
+     * set vector value by Short2
+     *
+     * @param a
+     */
+    public void set(Short2 a) {
+        this.x = a.x;
+        this.y = a.y;
+    }
+
+    /** @hide
+     * set the vector field value by Short
+     *
+     * @param a
+     * @param b
+     */
+    public void setValues(short a, short b) {
+        this.x = a;
+        this.y = b;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public short elementSum() {
+        return (short)(x + y);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public short get(int i) {
+        switch (i) {
+        case 0:
+            return (short)(x);
+        case 1:
+            return (short)(y);
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, short value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, short value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * copy the vector to short array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(short[] data, int offset) {
+        data[offset] = (short)(x);
+        data[offset + 1] = (short)(y);
+    }
 }
-
-
-
-
diff --git a/graphics/java/android/renderscript/Short3.java b/graphics/java/android/renderscript/Short3.java
index 49de05e..661db0a 100644
--- a/graphics/java/android/renderscript/Short3.java
+++ b/graphics/java/android/renderscript/Short3.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -16,29 +16,462 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript short3 type back to the Android system.
- *
- **/
+ * Vector version of the basic short type.
+ * Provides three short fields packed.
+ */
 public class Short3 {
-    public Short3() {
-    }
-
-    public Short3(short initX, short initY, short initZ) {
-        x = initX;
-        y = initY;
-        z = initZ;
-    }
-
     public short x;
     public short y;
     public short z;
+
+    public Short3() {
+    }
+
+    /** @hide */
+    public Short3(short i) {
+        this.x = this.y = this.z = i;
+    }
+
+    public Short3(short x, short y, short z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    /** @hide */
+    public Short3(Short3 source) {
+        this.x = source.x;
+        this.y = source.y;
+        this.z = source.z;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     */
+    public void add(Short3 a) {
+        this.x += a.x;
+        this.y += a.y;
+        this.z += a.z;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short3 add(Short3 a, Short3 b) {
+        Short3 result = new Short3();
+        result.x = (short)(a.x + b.x);
+        result.y = (short)(a.y + b.y);
+        result.z = (short)(a.z + b.z);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(short value) {
+        x += value;
+        y += value;
+        z += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short3 add(Short3 a, short b) {
+        Short3 result = new Short3();
+        result.x = (short)(a.x + b);
+        result.y = (short)(a.y + b);
+        result.z = (short)(a.z + b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     */
+    public void sub(Short3 a) {
+        this.x -= a.x;
+        this.y -= a.y;
+        this.z -= a.z;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short3 sub(Short3 a, Short3 b) {
+        Short3 result = new Short3();
+        result.x = (short)(a.x - b.x);
+        result.y = (short)(a.y - b.y);
+        result.z = (short)(a.z - b.z);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(short value) {
+        x -= value;
+        y -= value;
+        z -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short3 sub(Short3 a, short b) {
+        Short3 result = new Short3();
+        result.x = (short)(a.x - b);
+        result.y = (short)(a.y - b);
+        result.z = (short)(a.z - b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     */
+    public void mul(Short3 a) {
+        this.x *= a.x;
+        this.y *= a.y;
+        this.z *= a.z;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short3 mul(Short3 a, Short3 b) {
+        Short3 result = new Short3();
+        result.x = (short)(a.x * b.x);
+        result.y = (short)(a.y * b.y);
+        result.z = (short)(a.z * b.z);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(short value) {
+        x *= value;
+        y *= value;
+        z *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short3 mul(Short3 a, short b) {
+        Short3 result = new Short3();
+        result.x = (short)(a.x * b);
+        result.y = (short)(a.y * b);
+        result.z = (short)(a.z * b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     */
+    public void div(Short3 a) {
+        this.x /= a.x;
+        this.y /= a.y;
+        this.z /= a.z;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short3 div(Short3 a, Short3 b) {
+        Short3 result = new Short3();
+        result.x = (short)(a.x / b.x);
+        result.y = (short)(a.y / b.y);
+        result.z = (short)(a.z / b.z);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(short value) {
+        x /= value;
+        y /= value;
+        z /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short3 div(Short3 a, short b) {
+        Short3 result = new Short3();
+        result.x = (short)(a.x / b);
+        result.y = (short)(a.y / b);
+        result.z = (short)(a.z / b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     */
+    public void mod(Short3 a) {
+        this.x %= a.x;
+        this.y %= a.y;
+        this.z %= a.z;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short3 mod(Short3 a, Short3 b) {
+        Short3 result = new Short3();
+        result.x = (short)(a.x % b.x);
+        result.y = (short)(a.y % b.y);
+        result.z = (short)(a.z % b.z);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param value
+     */
+    public void mod(short value) {
+        x %= value;
+        y %= value;
+        z %= value;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short3 mod(Short3 a, short b) {
+        Short3 result = new Short3();
+        result.x = (short)(a.x % b);
+        result.y = (short)(a.y % b);
+        result.z = (short)(a.z % b);
+
+        return result;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public short length() {
+        return 3;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        this.x = (short)(-x);
+        this.y = (short)(-y);
+        this.z = (short)(-z);
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public short dotProduct(Short3 a) {
+        return (short)((x * a.x) + (y * a.y) + (z * a.z));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static short dotProduct(Short3 a, Short3 b) {
+        return (short)((b.x * a.x) + (b.y * a.y) + (b.z * a.z));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Short3 a, short factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+        z += a.z * factor;
+    }
+
+    /** @hide
+     * set vector value by Short3
+     *
+     * @param a
+     */
+    public void set(Short3 a) {
+        this.x = a.x;
+        this.y = a.y;
+        this.z = a.z;
+    }
+
+    /** @hide
+     * set the vector field value by Short
+     *
+     * @param a
+     * @param b
+     * @param c
+     */
+    public void setValues(short a, short b, short c) {
+        this.x = a;
+        this.y = b;
+        this.z = c;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public short elementSum() {
+        return (short)(x + y + z);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public short get(int i) {
+        switch (i) {
+        case 0:
+            return (short)(x);
+        case 1:
+            return (short)(y);
+        case 2:
+            return (short)(z);
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, short value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        case 2:
+            z = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, short value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        case 2:
+            z += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * copy the vector to short array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(short[] data, int offset) {
+        data[offset] = (short)(x);
+        data[offset + 1] = (short)(y);
+        data[offset + 2] = (short)(z);
+    }
 }
-
-
-
-
diff --git a/graphics/java/android/renderscript/Short4.java b/graphics/java/android/renderscript/Short4.java
index a7807a4..a2d74f2 100644
--- a/graphics/java/android/renderscript/Short4.java
+++ b/graphics/java/android/renderscript/Short4.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -16,30 +16,499 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
-
 /**
- * Class for exposing the native RenderScript short4 type back to the Android system.
- *
- **/
+ * Vector version of the basic short type.
+ * Provides four short fields packed.
+ */
 public class Short4 {
-    public Short4() {
-    }
-
-    public Short4(short initX, short initY, short initZ, short initW) {
-        x = initX;
-        y = initY;
-        z = initZ;
-        w = initW;
-    }
-
     public short x;
     public short y;
     public short z;
     public short w;
+
+    public Short4() {
+    }
+
+    /** @hide */
+    public Short4(short i) {
+        this.x = this.y = this.z = this.w = i;
+    }
+
+    public Short4(short x, short y, short z, short w) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        this.w = w;
+    }
+
+    /** @hide */
+    public Short4(Short4 source) {
+        this.x = source.x;
+        this.y = source.y;
+        this.z = source.z;
+        this.w = source.w;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     */
+    public void add(Short4 a) {
+        this.x += a.x;
+        this.y += a.y;
+        this.z += a.z;
+        this.w += a.w;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short4 add(Short4 a, Short4 b) {
+        Short4 result = new Short4();
+        result.x = (short)(a.x + b.x);
+        result.y = (short)(a.y + b.y);
+        result.z = (short)(a.z + b.z);
+        result.w = (short)(a.w + b.w);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param value
+     */
+    public void add(short value) {
+        x += value;
+        y += value;
+        z += value;
+        w += value;
+    }
+
+    /** @hide
+     * Vector add
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short4 add(Short4 a, short b) {
+        Short4 result = new Short4();
+        result.x = (short)(a.x + b);
+        result.y = (short)(a.y + b);
+        result.z = (short)(a.z + b);
+        result.w = (short)(a.w + b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     */
+    public void sub(Short4 a) {
+        this.x -= a.x;
+        this.y -= a.y;
+        this.z -= a.z;
+        this.w -= a.w;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short4 sub(Short4 a, Short4 b) {
+        Short4 result = new Short4();
+        result.x = (short)(a.x - b.x);
+        result.y = (short)(a.y - b.y);
+        result.z = (short)(a.z - b.z);
+        result.w = (short)(a.w - b.w);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param value
+     */
+    public void sub(short value) {
+        x -= value;
+        y -= value;
+        z -= value;
+        w -= value;
+    }
+
+    /** @hide
+     * Vector subtraction
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short4 sub(Short4 a, short b) {
+        Short4 result = new Short4();
+        result.x = (short)(a.x - b);
+        result.y = (short)(a.y - b);
+        result.z = (short)(a.z - b);
+        result.w = (short)(a.w - b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     */
+    public void mul(Short4 a) {
+        this.x *= a.x;
+        this.y *= a.y;
+        this.z *= a.z;
+        this.w *= a.w;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short4 mul(Short4 a, Short4 b) {
+        Short4 result = new Short4();
+        result.x = (short)(a.x * b.x);
+        result.y = (short)(a.y * b.y);
+        result.z = (short)(a.z * b.z);
+        result.w = (short)(a.w * b.w);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param value
+     */
+    public void mul(short value) {
+        x *= value;
+        y *= value;
+        z *= value;
+        w *= value;
+    }
+
+    /** @hide
+     * Vector multiplication
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short4 mul(Short4 a, short b) {
+        Short4 result = new Short4();
+        result.x = (short)(a.x * b);
+        result.y = (short)(a.y * b);
+        result.z = (short)(a.z * b);
+        result.w = (short)(a.w * b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     */
+    public void div(Short4 a) {
+        this.x /= a.x;
+        this.y /= a.y;
+        this.z /= a.z;
+        this.w /= a.w;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short4 div(Short4 a, Short4 b) {
+        Short4 result = new Short4();
+        result.x = (short)(a.x / b.x);
+        result.y = (short)(a.y / b.y);
+        result.z = (short)(a.z / b.z);
+        result.w = (short)(a.w / b.w);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param value
+     */
+    public void div(short value) {
+        x /= value;
+        y /= value;
+        z /= value;
+        w /= value;
+    }
+
+    /** @hide
+     * Vector division
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short4 div(Short4 a, short b) {
+        Short4 result = new Short4();
+        result.x = (short)(a.x / b);
+        result.y = (short)(a.y / b);
+        result.z = (short)(a.z / b);
+        result.w = (short)(a.w / b);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     */
+    public void mod(Short4 a) {
+        this.x %= a.x;
+        this.y %= a.y;
+        this.z %= a.z;
+        this.w %= a.w;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short4 mod(Short4 a, Short4 b) {
+        Short4 result = new Short4();
+        result.x = (short)(a.x % b.x);
+        result.y = (short)(a.y % b.y);
+        result.z = (short)(a.z % b.z);
+        result.w = (short)(a.w % b.w);
+
+        return result;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param value
+     */
+    public void mod(short value) {
+        x %= value;
+        y %= value;
+        z %= value;
+        w %= value;
+    }
+
+    /** @hide
+     * Vector Modulo
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static Short4 mod(Short4 a, short b) {
+        Short4 result = new Short4();
+        result.x = (short)(a.x % b);
+        result.y = (short)(a.y % b);
+        result.z = (short)(a.z % b);
+        result.w = (short)(a.w % b);
+
+        return result;
+    }
+
+    /** @hide
+     * get vector length
+     *
+     * @return
+     */
+    public short length() {
+        return 4;
+    }
+
+    /** @hide
+     * set vector negate
+     */
+    public void negate() {
+        this.x = (short)(-x);
+        this.y = (short)(-y);
+        this.z = (short)(-z);
+        this.w = (short)(-w);
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @return
+     */
+    public short dotProduct(Short4 a) {
+        return (short)((x * a.x) + (y * a.y) + (z * a.z) + (w * a.w));
+    }
+
+    /** @hide
+     * Vector dot Product
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static short dotProduct(Short4 a, Short4 b) {
+        return (short)((b.x * a.x) + (b.y * a.y) + (b.z * a.z) + (b.w * a.w));
+    }
+
+    /** @hide
+     * Vector add Multiple
+     *
+     * @param a
+     * @param factor
+     */
+    public void addMultiple(Short4 a, short factor) {
+        x += a.x * factor;
+        y += a.y * factor;
+        z += a.z * factor;
+        w += a.w * factor;
+    }
+
+    /** @hide
+     * set vector value by Short4
+     *
+     * @param a
+     */
+    public void set(Short4 a) {
+        this.x = a.x;
+        this.y = a.y;
+        this.z = a.z;
+        this.w = a.w;
+    }
+
+    /** @hide
+     * set the vector field value by Short
+     *
+     * @param a
+     * @param b
+     * @param c
+     * @param d
+     */
+    public void setValues(short a, short b, short c, short d) {
+        this.x = a;
+        this.y = b;
+        this.z = c;
+        this.w = d;
+    }
+
+    /** @hide
+     * return the element sum of vector
+     *
+     * @return
+     */
+    public short elementSum() {
+        return (short)(x + y + z + w);
+    }
+
+    /** @hide
+     * get the vector field value by index
+     *
+     * @param i
+     * @return
+     */
+    public short get(int i) {
+        switch (i) {
+        case 0:
+            return (short)(x);
+        case 1:
+            return (short)(y);
+        case 2:
+            return (short)(z);
+        case 3:
+            return (short)(w);
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * set the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void setAt(int i, short value) {
+        switch (i) {
+        case 0:
+            x = value;
+            return;
+        case 1:
+            y = value;
+            return;
+        case 2:
+            z = value;
+            return;
+        case 3:
+            w = value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * add the vector field value by index
+     *
+     * @param i
+     * @param value
+     */
+    public void addAt(int i, short value) {
+        switch (i) {
+        case 0:
+            x += value;
+            return;
+        case 1:
+            y += value;
+            return;
+        case 2:
+            z += value;
+            return;
+        case 3:
+            w += value;
+            return;
+        default:
+            throw new IndexOutOfBoundsException("Index: i");
+        }
+    }
+
+    /** @hide
+     * copy the vector to short array
+     *
+     * @param data
+     * @param offset
+     */
+    public void copyTo(short[] data, int offset) {
+        data[offset] = (short)(x);
+        data[offset + 1] = (short)(y);
+        data[offset + 2] = (short)(z);
+        data[offset + 3] = (short)(w);
+    }
 }
-
-
-
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index e023739..83bf4a5 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -16,12 +16,6 @@
 
 package android.renderscript;
 
-
-import java.lang.reflect.Field;
-
-import android.graphics.ImageFormat;
-import android.util.Log;
-
 /**
  * <p>A Type describes the {@link android.renderscript.Element} and dimensions used for an {@link
  * android.renderscript.Allocation} or a parallel operation. Types are created through {@link
@@ -190,16 +184,18 @@
     }
 
 
-    Type(int id, RenderScript rs) {
+    Type(long id, RenderScript rs) {
         super(id, rs);
     }
 
     @Override
     void updateFromNative() {
+        // FIXME: rsaTypeGetNativeData needs 32-bit and 64-bit paths
+
         // We have 6 integer to obtain mDimX; mDimY; mDimZ;
         // mDimLOD; mDimFaces; mElement;
         int[] dataBuffer = new int[6];
-        mRS.nTypeGetNativeData(getID(mRS), dataBuffer);
+        mRS.nTypeGetNativeData((int)getID(mRS), dataBuffer);
 
         mDimX = dataBuffer[0];
         mDimY = dataBuffer[1];
@@ -216,6 +212,81 @@
     }
 
     /**
+     * Utility function for creating basic 1D types. The type is
+     * created without mipmaps enabled.
+     *
+     * @param rs The RenderScript context
+     * @param e The Element for the Type
+     * @param dimX The X dimension, must be > 0
+     *
+     * @return Type
+     */
+    static public Type createX(RenderScript rs, Element e, int dimX) {
+        if (dimX < 1) {
+            throw new RSInvalidStateException("Dimension must be >= 1.");
+        }
+
+        long id = rs.nTypeCreate(e.getID(rs), dimX, 0, 0, false, false, 0);
+        Type t = new Type(id, rs);
+        t.mElement = e;
+        t.mDimX = dimX;
+        t.calcElementCount();
+        return t;
+    }
+
+    /**
+     * Utility function for creating basic 2D types. The type is
+     * created without mipmaps or cubemaps.
+     *
+     * @param rs The RenderScript context
+     * @param e The Element for the Type
+     * @param dimX The X dimension, must be > 0
+     * @param dimY The Y dimension, must be > 0
+     *
+     * @return Type
+     */
+    static public Type createXY(RenderScript rs, Element e, int dimX, int dimY) {
+        if ((dimX < 1) || (dimY < 1)) {
+            throw new RSInvalidStateException("Dimension must be >= 1.");
+        }
+
+        long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, 0, false, false, 0);
+        Type t = new Type(id, rs);
+        t.mElement = e;
+        t.mDimX = dimX;
+        t.mDimY = dimY;
+        t.calcElementCount();
+        return t;
+    }
+
+    /**
+     * Utility function for creating basic 3D types. The type is
+     * created without mipmaps.
+     *
+     * @param rs The RenderScript context
+     * @param e The Element for the Type
+     * @param dimX The X dimension, must be > 0
+     * @param dimY The Y dimension, must be > 0
+     * @param dimZ The Z dimension, must be > 0
+     *
+     * @return Type
+     */
+    static public Type createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ) {
+        if ((dimX < 1) || (dimY < 1) || (dimZ < 1)) {
+            throw new RSInvalidStateException("Dimension must be >= 1.");
+        }
+
+        long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, dimZ, false, false, 0);
+        Type t = new Type(id, rs);
+        t.mElement = e;
+        t.mDimX = dimX;
+        t.mDimY = dimY;
+        t.mDimZ = dimZ;
+        t.calcElementCount();
+        return t;
+    }
+
+    /**
      * Builder class for Type.
      *
      */
@@ -336,7 +407,7 @@
                 }
             }
 
-            int id = mRS.nTypeCreate(mElement.getID(mRS),
+            long id = mRS.nTypeCreate(mElement.getID(mRS),
                                      mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv);
             Type t = new Type(id, mRS);
             t.mElement = mElement;
diff --git a/graphics/jni/Android.mk b/graphics/jni/Android.mk
index e8beae53..cbb5b3b 100644
--- a/graphics/jni/Android.mk
+++ b/graphics/jni/Android.mk
@@ -26,7 +26,7 @@
 	$(rs_generated_include_dir) \
 	$(call include-path-for, corecg graphics)
 
-LOCAL_CFLAGS +=
+LOCAL_CFLAGS += -Wno-unused-parameter
 
 LOCAL_LDLIBS := -lpthread
 LOCAL_ADDITIONAL_DEPENDENCIES := $(addprefix $(rs_generated_include_dir)/,rsgApiFuncDecl.h)
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index cbc4e5a..619e737 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -50,6 +50,63 @@
 
 using namespace android;
 
+#define PER_ARRAY_TYPE(flag, fnc, ...) {                                                \
+    jint len = 0;                                                                       \
+    void *ptr = NULL;                                                                   \
+    size_t typeBytes = 0;                                                               \
+    switch(dataType) {                                                                  \
+    case RS_TYPE_FLOAT_32:                                                              \
+        len = _env->GetArrayLength((jfloatArray)data);                                  \
+        ptr = _env->GetFloatArrayElements((jfloatArray)data, flag);                     \
+        typeBytes = 4;                                                                  \
+        fnc(__VA_ARGS__);                                                               \
+        _env->ReleaseFloatArrayElements((jfloatArray)data, (jfloat *)ptr, JNI_ABORT);   \
+        return;                                                                         \
+    case RS_TYPE_FLOAT_64:                                                              \
+        len = _env->GetArrayLength((jdoubleArray)data);                                 \
+        ptr = _env->GetDoubleArrayElements((jdoubleArray)data, flag);                   \
+        typeBytes = 8;                                                                  \
+        fnc(__VA_ARGS__);                                                               \
+        _env->ReleaseDoubleArrayElements((jdoubleArray)data, (jdouble *)ptr, JNI_ABORT);\
+        return;                                                                         \
+    case RS_TYPE_SIGNED_8:                                                              \
+    case RS_TYPE_UNSIGNED_8:                                                            \
+        len = _env->GetArrayLength((jbyteArray)data);                                   \
+        ptr = _env->GetByteArrayElements((jbyteArray)data, flag);                       \
+        typeBytes = 1;                                                                  \
+        fnc(__VA_ARGS__);                                                               \
+        _env->ReleaseByteArrayElements((jbyteArray)data, (jbyte*)ptr, JNI_ABORT);       \
+        return;                                                                         \
+    case RS_TYPE_SIGNED_16:                                                             \
+    case RS_TYPE_UNSIGNED_16:                                                           \
+        len = _env->GetArrayLength((jshortArray)data);                                  \
+        ptr = _env->GetShortArrayElements((jshortArray)data, flag);                     \
+        typeBytes = 2;                                                                  \
+        fnc(__VA_ARGS__);                                                               \
+        _env->ReleaseShortArrayElements((jshortArray)data, (jshort *)ptr, JNI_ABORT);   \
+        return;                                                                         \
+    case RS_TYPE_SIGNED_32:                                                             \
+    case RS_TYPE_UNSIGNED_32:                                                           \
+        len = _env->GetArrayLength((jintArray)data);                                    \
+        ptr = _env->GetIntArrayElements((jintArray)data, flag);                         \
+        typeBytes = 4;                                                                  \
+        fnc(__VA_ARGS__);                                                               \
+        _env->ReleaseIntArrayElements((jintArray)data, (jint *)ptr, JNI_ABORT);         \
+        return;                                                                         \
+    case RS_TYPE_SIGNED_64:                                                             \
+    case RS_TYPE_UNSIGNED_64:                                                           \
+        len = _env->GetArrayLength((jlongArray)data);                                   \
+        ptr = _env->GetLongArrayElements((jlongArray)data, flag);                       \
+        typeBytes = 8;                                                                  \
+        fnc(__VA_ARGS__);                                                               \
+        _env->ReleaseLongArrayElements((jlongArray)data, (jlong *)ptr, JNI_ABORT);      \
+        return;                                                                         \
+    default:                                                                            \
+        break;                                                                          \
+    }                                                                                   \
+}
+
+
 class AutoJavaStringToUTF8 {
 public:
     AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) {
@@ -113,7 +170,7 @@
 
 static void _nInit(JNIEnv *_env, jclass _this)
 {
-    gContextId             = _env->GetFieldID(_this, "mContext", "I");
+    gContextId             = _env->GetFieldID(_this, "mContext", "J");
 
     jclass bitmapClass = _env->FindClass("android/graphics/Bitmap");
     gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I");
@@ -122,28 +179,28 @@
 // ---------------------------------------------------------------------------
 
 static void
-nContextFinish(JNIEnv *_env, jobject _this, RsContext con)
+nContextFinish(JNIEnv *_env, jobject _this, jlong con)
 {
     LOG_API("nContextFinish, con(%p)", con);
-    rsContextFinish(con);
+    rsContextFinish((RsContext)con);
 }
 
 static void
-nAssignName(JNIEnv *_env, jobject _this, RsContext con, jint obj, jbyteArray str)
+nAssignName(JNIEnv *_env, jobject _this, jlong con, jlong obj, jbyteArray str)
 {
     LOG_API("nAssignName, con(%p), obj(%p)", con, (void *)obj);
     jint len = _env->GetArrayLength(str);
     jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
-    rsAssignName(con, (void *)obj, (const char *)cptr, len);
+    rsAssignName((RsContext)con, (void *)obj, (const char *)cptr, len);
     _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
 }
 
 static jstring
-nGetName(JNIEnv *_env, jobject _this, RsContext con, jint obj)
+nGetName(JNIEnv *_env, jobject _this, jlong con, jlong obj)
 {
     LOG_API("nGetName, con(%p), obj(%p)", con, (void *)obj);
     const char *name = NULL;
-    rsaGetName(con, (void *)obj, &name);
+    rsaGetName((RsContext)con, (void *)obj, &name);
     if(name == NULL || strlen(name) == 0) {
         return NULL;
     }
@@ -151,15 +208,15 @@
 }
 
 static void
-nObjDestroy(JNIEnv *_env, jobject _this, RsContext con, jint obj)
+nObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
 {
     LOG_API("nObjDestroy, con(%p) obj(%p)", con, (void *)obj);
-    rsObjDestroy(con, (void *)obj);
+    rsObjDestroy((RsContext)con, (void *)obj);
 }
 
 // ---------------------------------------------------------------------------
 
-static jint
+static jlong
 nDeviceCreate(JNIEnv *_env, jobject _this)
 {
     LOG_API("nDeviceCreate");
@@ -180,14 +237,14 @@
     return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
 }
 
-static jint
+static jlong
 nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer, jint ct)
 {
     LOG_API("nContextCreate");
     return (jint)rsContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, 0);
 }
 
-static jint
+static jlong
 nContextCreateGL(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer,
                  int colorMin, int colorPref,
                  int alphaMin, int alphaPref,
@@ -212,16 +269,16 @@
 }
 
 static void
-nContextSetPriority(JNIEnv *_env, jobject _this, RsContext con, jint p)
+nContextSetPriority(JNIEnv *_env, jobject _this, jlong con, jint p)
 {
     LOG_API("ContextSetPriority, con(%p), priority(%i)", con, p);
-    rsContextSetPriority(con, p);
+    rsContextSetPriority((RsContext)con, p);
 }
 
 
 
 static void
-nContextSetSurface(JNIEnv *_env, jobject _this, RsContext con, jint width, jint height, jobject wnd)
+nContextSetSurface(JNIEnv *_env, jobject _this, jlong con, jint width, jint height, jobject wnd)
 {
     LOG_API("nContextSetSurface, con(%p), width(%i), height(%i), surface(%p)", con, width, height, (Surface *)wnd);
 
@@ -232,47 +289,47 @@
         window = android_view_Surface_getNativeWindow(_env, wnd).get();
     }
 
-    rsContextSetSurface(con, width, height, window);
+    rsContextSetSurface((RsContext)con, width, height, window);
 }
 
 static void
-nContextDestroy(JNIEnv *_env, jobject _this, RsContext con)
+nContextDestroy(JNIEnv *_env, jobject _this, jlong con)
 {
     LOG_API("nContextDestroy, con(%p)", con);
-    rsContextDestroy(con);
+    rsContextDestroy((RsContext)con);
 }
 
 static void
-nContextDump(JNIEnv *_env, jobject _this, RsContext con, jint bits)
+nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits)
 {
     LOG_API("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
     rsContextDump((RsContext)con, bits);
 }
 
 static void
-nContextPause(JNIEnv *_env, jobject _this, RsContext con)
+nContextPause(JNIEnv *_env, jobject _this, jlong con)
 {
     LOG_API("nContextPause, con(%p)", con);
-    rsContextPause(con);
+    rsContextPause((RsContext)con);
 }
 
 static void
-nContextResume(JNIEnv *_env, jobject _this, RsContext con)
+nContextResume(JNIEnv *_env, jobject _this, jlong con)
 {
     LOG_API("nContextResume, con(%p)", con);
-    rsContextResume(con);
+    rsContextResume((RsContext)con);
 }
 
 
 static jstring
-nContextGetErrorMessage(JNIEnv *_env, jobject _this, RsContext con)
+nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con)
 {
     LOG_API("nContextGetErrorMessage, con(%p)", con);
     char buf[1024];
 
     size_t receiveLen;
     uint32_t subID;
-    int id = rsContextGetMessage(con,
+    int id = rsContextGetMessage((RsContext)con,
                                  buf, sizeof(buf),
                                  &receiveLen, sizeof(receiveLen),
                                  &subID, sizeof(subID));
@@ -283,14 +340,14 @@
 }
 
 static jint
-nContextGetUserMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray data)
+nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data)
 {
     jint len = _env->GetArrayLength(data);
     LOG_API("nContextGetMessage, con(%p), len(%i)", con, len);
     jint *ptr = _env->GetIntArrayElements(data, NULL);
     size_t receiveLen;
     uint32_t subID;
-    int id = rsContextGetMessage(con,
+    int id = rsContextGetMessage((RsContext)con,
                                  ptr, len * 4,
                                  &receiveLen, sizeof(receiveLen),
                                  &subID, sizeof(subID));
@@ -302,13 +359,13 @@
 }
 
 static jint
-nContextPeekMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray auxData)
+nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData)
 {
     LOG_API("nContextPeekMessage, con(%p)", con);
     jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL);
     size_t receiveLen;
     uint32_t subID;
-    int id = rsContextPeekMessage(con, &receiveLen, sizeof(receiveLen),
+    int id = rsContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen),
                                   &subID, sizeof(subID));
     auxDataPtr[0] = (jint)subID;
     auxDataPtr[1] = (jint)receiveLen;
@@ -316,20 +373,20 @@
     return id;
 }
 
-static void nContextInitToClient(JNIEnv *_env, jobject _this, RsContext con)
+static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con)
 {
     LOG_API("nContextInitToClient, con(%p)", con);
-    rsContextInitToClient(con);
+    rsContextInitToClient((RsContext)con);
 }
 
-static void nContextDeinitToClient(JNIEnv *_env, jobject _this, RsContext con)
+static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con)
 {
     LOG_API("nContextDeinitToClient, con(%p)", con);
-    rsContextDeinitToClient(con);
+    rsContextDeinitToClient((RsContext)con);
 }
 
 static void
-nContextSendMessage(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray data)
+nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data)
 {
     jint *ptr = NULL;
     jint len = 0;
@@ -338,7 +395,7 @@
         jint *ptr = _env->GetIntArrayElements(data, NULL);
     }
     LOG_API("nContextSendMessage, con(%p), id(%i), len(%i)", con, id, len);
-    rsContextSendMessage(con, id, (const uint8_t *)ptr, len * sizeof(int));
+    rsContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int));
     if (data) {
         _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
     }
@@ -346,15 +403,15 @@
 
 
 
-static jint
-nElementCreate(JNIEnv *_env, jobject _this, RsContext con, jint type, jint kind, jboolean norm, jint size)
+static jlong
+nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm, jint size)
 {
     LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", con, type, kind, norm, size);
-    return (jint)rsElementCreate(con, (RsDataType)type, (RsDataKind)kind, norm, size);
+    return (jlong)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind, norm, size);
 }
 
-static jint
-nElementCreate2(JNIEnv *_env, jobject _this, RsContext con,
+static jlong
+nElementCreate2(JNIEnv *_env, jobject _this, jlong con,
                 jintArray _ids, jobjectArray _names, jintArray _arraySizes)
 {
     int fieldCount = _env->GetArrayLength(_ids);
@@ -368,7 +425,7 @@
     const char **nameArray = names.c_str();
     size_t *sizeArray = names.c_str_len();
 
-    jint id = (jint)rsElementCreate2(con,
+    jlong id = (jlong)rsElementCreate2((RsContext)con,
                                      (RsElement *)ids, fieldCount,
                                      nameArray, fieldCount * sizeof(size_t),  sizeArray,
                                      (const uint32_t *)arraySizes, fieldCount);
@@ -379,7 +436,7 @@
 }
 
 static void
-nElementGetNativeData(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray _elementData)
+nElementGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jintArray _elementData)
 {
     int dataSize = _env->GetArrayLength(_elementData);
     LOG_API("nElementGetNativeData, con(%p)", con);
@@ -388,7 +445,7 @@
     assert(dataSize == 5);
 
     uint32_t elementData[5];
-    rsaElementGetNativeData(con, (RsElement)id, elementData, dataSize);
+    rsaElementGetNativeData((RsContext)con, (RsElement)id, elementData, dataSize);
 
     for(jint i = 0; i < dataSize; i ++) {
         _env->SetIntArrayRegion(_elementData, i, 1, (const jint*)&elementData[i]);
@@ -397,7 +454,7 @@
 
 
 static void
-nElementGetSubElements(JNIEnv *_env, jobject _this, RsContext con, jint id,
+nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id,
                        jintArray _IDs,
                        jobjectArray _names,
                        jintArray _arraySizes)
@@ -409,7 +466,7 @@
     const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
     uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
 
-    rsaElementGetSubElements(con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize);
+    rsaElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize);
 
     for(jint i = 0; i < dataSize; i++) {
         _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
@@ -424,19 +481,18 @@
 
 // -----------------------------------
 
-static int
-nTypeCreate(JNIEnv *_env, jobject _this, RsContext con, RsElement eid,
+static jlong
+nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
             jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
 {
     LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
             con, eid, dimx, dimy, dimz, mips, faces, yuv);
 
-    jint id = (jint)rsTypeCreate(con, (RsElement)eid, dimx, dimy, dimz, mips, faces, yuv);
-    return (jint)id;
+    return (jlong)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips, faces, yuv);
 }
 
 static void
-nTypeGetNativeData(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray _typeData)
+nTypeGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jintArray _typeData)
 {
     // We are packing 6 items: mDimX; mDimY; mDimZ;
     // mDimLOD; mDimFaces; mElement; into typeData
@@ -446,7 +502,7 @@
     LOG_API("nTypeCreate, con(%p)", con);
 
     uint32_t typeData[6];
-    rsaTypeGetNativeData(con, (RsType)id, typeData, 6);
+    rsaTypeGetNativeData((RsContext)con, (RsType)id, typeData, 6);
 
     for(jint i = 0; i < elementCount; i ++) {
         _env->SetIntArrayRegion(_typeData, i, 1, (const jint*)&typeData[i]);
@@ -455,26 +511,26 @@
 
 // -----------------------------------
 
-static jint
-nAllocationCreateTyped(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mips, jint usage, jint pointer)
+static jlong
+nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage, jint pointer)
 {
     LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)", con, (RsElement)type, mips, usage, (void *)pointer);
-    return (jint) rsAllocationCreateTyped(con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uint32_t)pointer);
+    return (jint) rsAllocationCreateTyped((RsContext)con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uint32_t)pointer);
 }
 
 static void
-nAllocationSyncAll(JNIEnv *_env, jobject _this, RsContext con, jint a, jint bits)
+nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits)
 {
     LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", con, (RsAllocation)a, bits);
-    rsAllocationSyncAll(con, (RsAllocation)a, (RsAllocationUsageType)bits);
+    rsAllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits);
 }
 
 static jobject
-nAllocationGetSurface(JNIEnv *_env, jobject _this, RsContext con, jint a)
+nAllocationGetSurface(JNIEnv *_env, jobject _this, jlong con, jlong a)
 {
     LOG_API("nAllocationGetSurface, con(%p), a(%p)", con, (RsAllocation)a);
 
-    IGraphicBufferProducer *v = (IGraphicBufferProducer *)rsAllocationGetSurface(con, (RsAllocation)a);
+    IGraphicBufferProducer *v = (IGraphicBufferProducer *)rsAllocationGetSurface((RsContext)con, (RsAllocation)a);
     sp<IGraphicBufferProducer> bp = v;
     v->decStrong(NULL);
 
@@ -483,7 +539,7 @@
 }
 
 static void
-nAllocationSetSurface(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc, jobject sur)
+nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur)
 {
     LOG_API("nAllocationSetSurface, con(%p), alloc(%p), surface(%p)",
             con, alloc, (Surface *)sur);
@@ -493,33 +549,33 @@
         s = android_view_Surface_getSurface(_env, sur);
     }
 
-    rsAllocationSetSurface(con, alloc, static_cast<ANativeWindow *>(s.get()));
+    rsAllocationSetSurface((RsContext)con, (RsAllocation)alloc, static_cast<ANativeWindow *>(s.get()));
 }
 
 static void
-nAllocationIoSend(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc)
+nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
 {
     LOG_API("nAllocationIoSend, con(%p), alloc(%p)", con, alloc);
-    rsAllocationIoSend(con, alloc);
+    rsAllocationIoSend((RsContext)con, (RsAllocation)alloc);
 }
 
 static void
-nAllocationIoReceive(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc)
+nAllocationIoReceive(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
 {
     LOG_API("nAllocationIoReceive, con(%p), alloc(%p)", con, alloc);
-    rsAllocationIoReceive(con, alloc);
+    rsAllocationIoReceive((RsContext)con, (RsAllocation)alloc);
 }
 
 
 static void
-nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, RsContext con, jint alloc)
+nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
 {
     LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", con, (RsAllocation)alloc);
-    rsAllocationGenerateMipmaps(con, (RsAllocation)alloc);
+    rsAllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc);
 }
 
-static int
-nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
+static jlong
+nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, jobject jbitmap, jint usage)
 {
     SkBitmap const * nativeBitmap =
             (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
@@ -527,15 +583,15 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    jint id = (jint)rsAllocationCreateFromBitmap(con,
+    jlong id = (jlong)rsAllocationCreateFromBitmap((RsContext)con,
                                                   (RsType)type, (RsAllocationMipmapControl)mip,
                                                   ptr, bitmap.getSize(), usage);
     bitmap.unlockPixels();
     return id;
 }
 
-static int
-nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
+static jlong
+nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, jobject jbitmap, jint usage)
 {
     SkBitmap const * nativeBitmap =
             (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
@@ -543,15 +599,15 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    jint id = (jint)rsAllocationCreateTyped(con,
+    jlong id = (jlong)rsAllocationCreateTyped((RsContext)con,
                                             (RsType)type, (RsAllocationMipmapControl)mip,
                                             (uint32_t)usage, (size_t)ptr);
     bitmap.unlockPixels();
     return id;
 }
 
-static int
-nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
+static jlong
+nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, jobject jbitmap, jint usage)
 {
     SkBitmap const * nativeBitmap =
             (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
@@ -559,7 +615,7 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    jint id = (jint)rsAllocationCubeCreateFromBitmap(con,
+    jlong id = (jlong)rsAllocationCubeCreateFromBitmap((RsContext)con,
                                                       (RsType)type, (RsAllocationMipmapControl)mip,
                                                       ptr, bitmap.getSize(), usage);
     bitmap.unlockPixels();
@@ -567,7 +623,7 @@
 }
 
 static void
-nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
+nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
 {
     SkBitmap const * nativeBitmap =
             (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
@@ -577,14 +633,14 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    rsAllocation2DData(con, (RsAllocation)alloc, 0, 0,
+    rsAllocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0,
                        0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
                        w, h, ptr, bitmap.getSize(), 0);
     bitmap.unlockPixels();
 }
 
 static void
-nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
+nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
 {
     SkBitmap const * nativeBitmap =
             (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
@@ -592,7 +648,7 @@
 
     bitmap.lockPixels();
     void* ptr = bitmap.getPixels();
-    rsAllocationCopyToBitmap(con, (RsAllocation)alloc, ptr, bitmap.getSize());
+    rsAllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, ptr, bitmap.getSize());
     bitmap.unlockPixels();
     bitmap.notifyPixelsChanged();
 }
@@ -605,106 +661,43 @@
 
 
 static void
-nAllocationData1D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jintArray data, int sizeBytes)
+nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
+                  jint count, jobject data, int sizeBytes, int dataType)
 {
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation1DData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
-    jint *ptr = _env->GetIntArrayElements(data, NULL);
-    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
-    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nAllocationData1D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jshortArray data, int sizeBytes)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation1DData_s, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
-    jshort *ptr = _env->GetShortArrayElements(data, NULL);
-    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
-    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nAllocationData1D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jbyteArray data, int sizeBytes)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation1DData_b, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
-    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
-    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
-    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nAllocationData1D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jfloatArray data, int sizeBytes)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation1DData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
-    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
-    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
+    RsAllocation *alloc = (RsAllocation *)_alloc;
+    LOG_API("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i), dataType(%i)",
+            con, alloc, offset, count, len, sizeBytes, dataType);
+    PER_ARRAY_TYPE(NULL, rsAllocation1DData, (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
 }
 
 static void
 //    native void rsnAllocationElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes);
-nAllocationElementData1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint compIdx, jbyteArray data, int sizeBytes)
+nAllocationElementData1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint offset, jint lod, jint compIdx, jbyteArray data, int sizeBytes)
 {
     jint len = _env->GetArrayLength(data);
     LOG_API("nAllocationElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, compIdx, len, sizeBytes);
     jbyte *ptr = _env->GetByteArrayElements(data, NULL);
-    rsAllocation1DElementData(con, (RsAllocation)alloc, offset, lod, ptr, sizeBytes, compIdx);
+    rsAllocation1DElementData((RsContext)con, (RsAllocation)alloc, offset, lod, ptr, sizeBytes, compIdx);
     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
 }
 
 static void
-nAllocationData2D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
-                    jint w, jint h, jshortArray data, int sizeBytes)
+nAllocationData2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
+                  jint w, jint h, jobject data, int sizeBytes, int dataType)
 {
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation2DData_s, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
-    jshort *ptr = _env->GetShortArrayElements(data, NULL);
-    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes, 0);
-    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
+    RsAllocation *alloc = (RsAllocation *)_alloc;
+    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
+    LOG_API("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) type(%i)",
+            con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
+    PER_ARRAY_TYPE(NULL, rsAllocation2DData, (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
 }
 
 static void
-nAllocationData2D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
-                    jint w, jint h, jbyteArray data, int sizeBytes)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation2DData_b, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
-    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
-    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes, 0);
-    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nAllocationData2D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
-                    jint w, jint h, jintArray data, int sizeBytes)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation2DData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
-    jint *ptr = _env->GetIntArrayElements(data, NULL);
-    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes, 0);
-    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nAllocationData2D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
-                    jint w, jint h, jfloatArray data, int sizeBytes)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation2DData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
-    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes, 0);
-    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nAllocationData2D_alloc(JNIEnv *_env, jobject _this, RsContext con,
-                        jint dstAlloc, jint dstXoff, jint dstYoff,
+nAllocationData2D_alloc(JNIEnv *_env, jobject _this, jlong con,
+                        jlong dstAlloc, jint dstXoff, jint dstYoff,
                         jint dstMip, jint dstFace,
                         jint width, jint height,
-                        jint srcAlloc, jint srcXoff, jint srcYoff,
+                        jlong srcAlloc, jint srcXoff, jint srcYoff,
                         jint srcMip, jint srcFace)
 {
     LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
@@ -713,7 +706,7 @@
             con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
             width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
 
-    rsAllocationCopy2DRange(con,
+    rsAllocationCopy2DRange((RsContext)con,
                             (RsAllocation)dstAlloc,
                             dstXoff, dstYoff,
                             dstMip, dstFace,
@@ -724,55 +717,21 @@
 }
 
 static void
-nAllocationData3D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint zoff, jint lod,
-                    jint w, jint h, jint d, jshortArray data, int sizeBytes)
+nAllocationData3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
+                    jint w, jint h, jint d, jobject data, int sizeBytes, int dataType)
 {
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation3DData_s, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, zoff, w, h, d, len);
-    jshort *ptr = _env->GetShortArrayElements(data, NULL);
-    rsAllocation3DData(con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
-    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
+    RsAllocation *alloc = (RsAllocation *)_alloc;
+    LOG_API("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i), h(%i), d(%i), sizeBytes(%i)",
+            con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, sizeBytes);
+    PER_ARRAY_TYPE(NULL, rsAllocation3DData, (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
 }
 
 static void
-nAllocationData3D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint zoff, jint lod,
-                    jint w, jint h, jint d, jbyteArray data, int sizeBytes)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation3DData_b, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, zoff, w, h, d, len);
-    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
-    rsAllocation3DData(con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
-    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nAllocationData3D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint zoff, jint lod,
-                    jint w, jint h, jint d, jintArray data, int sizeBytes)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation3DData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, zoff, w, h, d, len);
-    jint *ptr = _env->GetIntArrayElements(data, NULL);
-    rsAllocation3DData(con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
-    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nAllocationData3D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint zoff, jint lod,
-                    jint w, jint h, jint d, jfloatArray data, int sizeBytes)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocation3DData_f, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, zoff, w, h, d, len);
-    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    rsAllocation3DData(con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
-    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nAllocationData3D_alloc(JNIEnv *_env, jobject _this, RsContext con,
-                        jint dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
+nAllocationData3D_alloc(JNIEnv *_env, jobject _this, jlong con,
+                        jlong dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
                         jint dstMip,
                         jint width, jint height, jint depth,
-                        jint srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
+                        jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
                         jint srcMip)
 {
     LOG_API("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
@@ -781,7 +740,7 @@
             con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
             width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
 
-    rsAllocationCopy3DRange(con,
+    rsAllocationCopy3DRange((RsContext)con,
                             (RsAllocation)dstAlloc,
                             dstXoff, dstYoff, dstZoff, dstMip,
                             width, height, depth,
@@ -789,79 +748,65 @@
                             srcXoff, srcYoff, srcZoff, srcMip);
 }
 
+
 static void
-nAllocationRead_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jintArray data)
+nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, int dataType)
 {
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
-    jint *ptr = _env->GetIntArrayElements(data, NULL);
-    jsize length = _env->GetArrayLength(data);
-    rsAllocationRead(con, (RsAllocation)alloc, ptr, length * sizeof(int));
-    _env->ReleaseIntArrayElements(data, ptr, 0);
+    RsAllocation *alloc = (RsAllocation *)_alloc;
+    LOG_API("nAllocationRead, con(%p), alloc(%p)", con, (RsAllocation)alloc);
+    PER_ARRAY_TYPE(0, rsAllocationRead, (RsContext)con, alloc, ptr, len * typeBytes);
 }
 
 static void
-nAllocationRead_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jshortArray data)
+nAllocationRead1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
+                  jint count, jobject data, int sizeBytes, int dataType)
 {
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
-    jshort *ptr = _env->GetShortArrayElements(data, NULL);
-    jsize length = _env->GetArrayLength(data);
-    rsAllocationRead(con, (RsAllocation)alloc, ptr, length * sizeof(short));
-    _env->ReleaseShortArrayElements(data, ptr, 0);
+    RsAllocation *alloc = (RsAllocation *)_alloc;
+    LOG_API("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i), dataType(%i)",
+            con, alloc, offset, count, len, sizeBytes, dataType);
+    PER_ARRAY_TYPE(0, rsAllocation1DRead, (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
 }
 
 static void
-nAllocationRead_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jbyteArray data)
+nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
+                  jint w, jint h, jobject data, int sizeBytes, int dataType)
 {
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
-    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
-    jsize length = _env->GetArrayLength(data);
-    rsAllocationRead(con, (RsAllocation)alloc, ptr, length * sizeof(char));
-    _env->ReleaseByteArrayElements(data, ptr, 0);
+    RsAllocation *alloc = (RsAllocation *)_alloc;
+    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
+    LOG_API("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) type(%i)",
+            con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
+    PER_ARRAY_TYPE(0, rsAllocation2DRead, (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
 }
 
-static void
-nAllocationRead_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jfloatArray data)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
-    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    jsize length = _env->GetArrayLength(data);
-    rsAllocationRead(con, (RsAllocation)alloc, ptr, length * sizeof(float));
-    _env->ReleaseFloatArrayElements(data, ptr, 0);
-}
-
-static jint
-nAllocationGetType(JNIEnv *_env, jobject _this, RsContext con, jint a)
+static jlong
+nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
 {
     LOG_API("nAllocationGetType, con(%p), a(%p)", con, (RsAllocation)a);
-    return (jint) rsaAllocationGetType(con, (RsAllocation)a);
+    return (jlong) rsaAllocationGetType((RsContext)con, (RsAllocation)a);
 }
 
 static void
-nAllocationResize1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX)
+nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
 {
     LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", con, (RsAllocation)alloc, dimX);
-    rsAllocationResize1D(con, (RsAllocation)alloc, dimX);
+    rsAllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
 }
 
 // -----------------------------------
 
-static int
-nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, RsContext con, jint native_asset)
+static jlong
+nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con, jlong native_asset)
 {
     ALOGV("______nFileA3D %u", (uint32_t) native_asset);
 
     Asset* asset = reinterpret_cast<Asset*>(native_asset);
 
-    jint id = (jint)rsaFileA3DCreateFromMemory(con, asset->getBuffer(false), asset->getLength());
+    jlong id = (jlong)rsaFileA3DCreateFromMemory((RsContext)con, asset->getBuffer(false), asset->getLength());
     return id;
 }
 
-static int
-nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, RsContext con, jobject _assetMgr, jstring _path)
+static jlong
+nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path)
 {
     AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
     if (mgr == NULL) {
@@ -874,34 +819,34 @@
         return 0;
     }
 
-    jint id = (jint)rsaFileA3DCreateFromAsset(con, asset);
+    jlong id = (jlong)rsaFileA3DCreateFromAsset((RsContext)con, asset);
     return id;
 }
 
-static int
-nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, RsContext con, jstring fileName)
+static jlong
+nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, jlong con, jstring fileName)
 {
     AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
-    jint id = (jint)rsaFileA3DCreateFromFile(con, fileNameUTF.c_str());
+    jlong id = (jlong)rsaFileA3DCreateFromFile((RsContext)con, fileNameUTF.c_str());
 
     return id;
 }
 
-static int
-nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D)
+static jint
+nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D)
 {
     int32_t numEntries = 0;
-    rsaFileA3DGetNumIndexEntries(con, &numEntries, (RsFile)fileA3D);
+    rsaFileA3DGetNumIndexEntries((RsContext)con, &numEntries, (RsFile)fileA3D);
     return numEntries;
 }
 
 static void
-nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries)
+nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries)
 {
     ALOGV("______nFileA3D %u", (uint32_t) fileA3D);
     RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry));
 
-    rsaFileA3DGetIndexEntries(con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D);
+    rsaFileA3DGetIndexEntries((RsContext)con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D);
 
     for(jint i = 0; i < numEntries; i ++) {
         _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName));
@@ -912,21 +857,21 @@
 }
 
 static int
-nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D, jint index)
+nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint index)
 {
     ALOGV("______nFileA3D %u", (uint32_t) fileA3D);
-    jint id = (jint)rsaFileA3DGetEntryByIndex(con, (uint32_t)index, (RsFile)fileA3D);
+    jint id = (jint)rsaFileA3DGetEntryByIndex((RsContext)con, (uint32_t)index, (RsFile)fileA3D);
     return id;
 }
 
 // -----------------------------------
 
 static int
-nFontCreateFromFile(JNIEnv *_env, jobject _this, RsContext con,
+nFontCreateFromFile(JNIEnv *_env, jobject _this, jlong con,
                     jstring fileName, jfloat fontSize, jint dpi)
 {
     AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
-    jint id = (jint)rsFontCreateFromFile(con,
+    jint id = (jint)rsFontCreateFromFile((RsContext)con,
                                          fileNameUTF.c_str(), fileNameUTF.length(),
                                          fontSize, dpi);
 
@@ -934,13 +879,13 @@
 }
 
 static int
-nFontCreateFromAssetStream(JNIEnv *_env, jobject _this, RsContext con,
+nFontCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con,
                            jstring name, jfloat fontSize, jint dpi, jint native_asset)
 {
     Asset* asset = reinterpret_cast<Asset*>(native_asset);
     AutoJavaStringToUTF8 nameUTF(_env, name);
 
-    jint id = (jint)rsFontCreateFromMemory(con,
+    jint id = (jint)rsFontCreateFromMemory((RsContext)con,
                                            nameUTF.c_str(), nameUTF.length(),
                                            fontSize, dpi,
                                            asset->getBuffer(false), asset->getLength());
@@ -948,7 +893,7 @@
 }
 
 static int
-nFontCreateFromAsset(JNIEnv *_env, jobject _this, RsContext con, jobject _assetMgr, jstring _path,
+nFontCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path,
                      jfloat fontSize, jint dpi)
 {
     AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
@@ -962,7 +907,7 @@
         return 0;
     }
 
-    jint id = (jint)rsFontCreateFromMemory(con,
+    jint id = (jint)rsFontCreateFromMemory((RsContext)con,
                                            str.c_str(), str.length(),
                                            fontSize, dpi,
                                            asset->getBuffer(false), asset->getLength());
@@ -973,112 +918,112 @@
 // -----------------------------------
 
 static void
-nScriptBindAllocation(JNIEnv *_env, jobject _this, RsContext con, jint script, jint alloc, jint slot)
+nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot)
 {
     LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot);
-    rsScriptBindAllocation(con, (RsScript)script, (RsAllocation)alloc, slot);
+    rsScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
 }
 
 static void
-nScriptSetVarI(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
+nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val)
 {
     LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
-    rsScriptSetVarI(con, (RsScript)script, slot, val);
+    rsScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
 }
 
 static jint
-nScriptGetVarI(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot)
+nScriptGetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
 {
     LOG_API("nScriptGetVarI, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
     int value = 0;
-    rsScriptGetVarV(con, (RsScript)script, slot, &value, sizeof(value));
+    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
     return value;
 }
 
 static void
-nScriptSetVarObj(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
+nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
 {
     LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
-    rsScriptSetVarObj(con, (RsScript)script, slot, (RsObjectBase)val);
+    rsScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
 }
 
 static void
-nScriptSetVarJ(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jlong val)
+nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
 {
     LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", con, (void *)script, slot, val);
-    rsScriptSetVarJ(con, (RsScript)script, slot, val);
+    rsScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
 }
 
 static jlong
-nScriptGetVarJ(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot)
+nScriptGetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
 {
     LOG_API("nScriptGetVarJ, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
     jlong value = 0;
-    rsScriptGetVarV(con, (RsScript)script, slot, &value, sizeof(value));
+    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
     return value;
 }
 
 static void
-nScriptSetVarF(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, float val)
+nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val)
 {
     LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", con, (void *)script, slot, val);
-    rsScriptSetVarF(con, (RsScript)script, slot, val);
+    rsScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
 }
 
 static jfloat
-nScriptGetVarF(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot)
+nScriptGetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
 {
     LOG_API("nScriptGetVarF, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
     jfloat value = 0;
-    rsScriptGetVarV(con, (RsScript)script, slot, &value, sizeof(value));
+    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
     return value;
 }
 
 static void
-nScriptSetVarD(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, double val)
+nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val)
 {
     LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", con, (void *)script, slot, val);
-    rsScriptSetVarD(con, (RsScript)script, slot, val);
+    rsScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
 }
 
 static jdouble
-nScriptGetVarD(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot)
+nScriptGetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
 {
     LOG_API("nScriptGetVarD, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
     jdouble value = 0;
-    rsScriptGetVarV(con, (RsScript)script, slot, &value, sizeof(value));
+    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
     return value;
 }
 
 static void
-nScriptSetVarV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
+nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
 {
     LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
     jint len = _env->GetArrayLength(data);
     jbyte *ptr = _env->GetByteArrayElements(data, NULL);
-    rsScriptSetVarV(con, (RsScript)script, slot, ptr, len);
+    rsScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
 }
 
 static void
-nScriptGetVarV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
+nScriptGetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
 {
     LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
     jint len = _env->GetArrayLength(data);
     jbyte *ptr = _env->GetByteArrayElements(data, NULL);
-    rsScriptGetVarV(con, (RsScript)script, slot, ptr, len);
+    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
 }
 
 static void
-nScriptSetVarVE(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data, jint elem, jintArray dims)
+nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jlong elem, jintArray dims)
 {
     LOG_API("nScriptSetVarVE, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
     jint len = _env->GetArrayLength(data);
     jbyte *ptr = _env->GetByteArrayElements(data, NULL);
     jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
     jint *dimsPtr = _env->GetIntArrayElements(dims, NULL);
-    rsScriptSetVarVE(con, (RsScript)script, slot, ptr, len, (RsElement)elem,
+    rsScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
                      (const size_t*) dimsPtr, dimsLen);
     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
     _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
@@ -1086,7 +1031,7 @@
 
 
 static void
-nScriptSetTimeZone(JNIEnv *_env, jobject _this, RsContext con, jint script, jbyteArray timeZone)
+nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone)
 {
     LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone);
 
@@ -1094,7 +1039,7 @@
     jbyte* timeZone_ptr;
     timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
 
-    rsScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length);
+    rsScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
 
     if (timeZone_ptr) {
         _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
@@ -1102,43 +1047,43 @@
 }
 
 static void
-nScriptInvoke(JNIEnv *_env, jobject _this, RsContext con, jint obj, jint slot)
+nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot)
 {
     LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj);
-    rsScriptInvoke(con, (RsScript)obj, slot);
+    rsScriptInvoke((RsContext)con, (RsScript)obj, slot);
 }
 
 static void
-nScriptInvokeV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
+nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
 {
     LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
     jint len = _env->GetArrayLength(data);
     jbyte *ptr = _env->GetByteArrayElements(data, NULL);
-    rsScriptInvokeV(con, (RsScript)script, slot, ptr, len);
+    rsScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
 }
 
 static void
-nScriptForEach(JNIEnv *_env, jobject _this, RsContext con,
-               jint script, jint slot, jint ain, jint aout)
+nScriptForEach(JNIEnv *_env, jobject _this, jlong con,
+               jlong script, jint slot, jlong ain, jlong aout)
 {
     LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
-    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, NULL, 0);
+    rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, NULL, 0);
 }
 static void
-nScriptForEachV(JNIEnv *_env, jobject _this, RsContext con,
-                jint script, jint slot, jint ain, jint aout, jbyteArray params)
+nScriptForEachV(JNIEnv *_env, jobject _this, jlong con,
+                jlong script, jint slot, jlong ain, jlong aout, jbyteArray params)
 {
     LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
     jint len = _env->GetArrayLength(params);
     jbyte *ptr = _env->GetByteArrayElements(params, NULL);
-    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, NULL, 0);
+    rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, NULL, 0);
     _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
 }
 
 static void
-nScriptForEachClipped(JNIEnv *_env, jobject _this, RsContext con,
-                      jint script, jint slot, jint ain, jint aout,
+nScriptForEachClipped(JNIEnv *_env, jobject _this, jlong con,
+                      jlong script, jint slot, jlong ain, jlong aout,
                       jint xstart, jint xend,
                       jint ystart, jint yend, jint zstart, jint zend)
 {
@@ -1153,12 +1098,12 @@
     sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
     sc.arrayStart = 0;
     sc.arrayEnd = 0;
-    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, &sc, sizeof(sc));
+    rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, &sc, sizeof(sc));
 }
 
 static void
-nScriptForEachClippedV(JNIEnv *_env, jobject _this, RsContext con,
-                       jint script, jint slot, jint ain, jint aout,
+nScriptForEachClippedV(JNIEnv *_env, jobject _this, jlong con,
+                       jlong script, jint slot, jlong ain, jlong aout,
                        jbyteArray params, jint xstart, jint xend,
                        jint ystart, jint yend, jint zstart, jint zend)
 {
@@ -1175,14 +1120,14 @@
     sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
     sc.arrayStart = 0;
     sc.arrayEnd = 0;
-    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, &sc, sizeof(sc));
+    rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, &sc, sizeof(sc));
     _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
 }
 
 // -----------------------------------
 
 static jint
-nScriptCCreate(JNIEnv *_env, jobject _this, RsContext con,
+nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
                jstring resName, jstring cacheDir,
                jbyteArray scriptRef, jint length)
 {
@@ -1214,9 +1159,9 @@
     script_ptr = (jbyte *)
         _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
 
-    //rsScriptCSetText(con, (const char *)script_ptr, length);
+    //rsScriptCSetText((RsContext)con, (const char *)script_ptr, length);
 
-    ret = (jint)rsScriptCCreate(con,
+    ret = (jint)rsScriptCCreate((RsContext)con,
                                 resNameUTF.c_str(), resNameUTF.length(),
                                 cacheDirUTF.c_str(), cacheDirUTF.length(),
                                 (const char *)script_ptr, length);
@@ -1230,29 +1175,29 @@
     return ret;
 }
 
-static jint
-nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, RsContext con, jint id, jint eid)
+static jlong
+nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid)
 {
     LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", con, id, (void *)eid);
-    return (jint)rsScriptIntrinsicCreate(con, id, (RsElement)eid);
+    return (jlong)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
 }
 
-static jint
-nScriptKernelIDCreate(JNIEnv *_env, jobject _this, RsContext con, jint sid, jint slot, jint sig)
+static jlong
+nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig)
 {
     LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", con, (void *)sid, slot, sig);
-    return (jint)rsScriptKernelIDCreate(con, (RsScript)sid, slot, sig);
+    return (jint)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
 }
 
-static jint
-nScriptFieldIDCreate(JNIEnv *_env, jobject _this, RsContext con, jint sid, jint slot)
+static jlong
+nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
 {
     LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", con, (void *)sid, slot);
-    return (jint)rsScriptFieldIDCreate(con, (RsScript)sid, slot);
+    return (jint)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
 }
 
-static jint
-nScriptGroupCreate(JNIEnv *_env, jobject _this, RsContext con, jintArray _kernels, jintArray _src,
+static jlong
+nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jintArray _kernels, jintArray _src,
     jintArray _dstk, jintArray _dstf, jintArray _types)
 {
     LOG_API("nScriptGroupCreate, con(%p)", con);
@@ -1268,7 +1213,7 @@
     jint typesLen = _env->GetArrayLength(_types) * sizeof(int);
     jint *typesPtr = _env->GetIntArrayElements(_types, NULL);
 
-    int id = (int)rsScriptGroupCreate(con,
+    int id = (int)rsScriptGroupCreate((RsContext)con,
                                (RsScriptKernelID *)kernelsPtr, kernelsLen,
                                (RsScriptKernelID *)srcPtr, srcLen,
                                (RsScriptKernelID *)dstkPtr, dstkLen,
@@ -1284,39 +1229,39 @@
 }
 
 static void
-nScriptGroupSetInput(JNIEnv *_env, jobject _this, RsContext con, jint gid, jint kid, jint alloc)
+nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
 {
     LOG_API("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", con,
         (void *)gid, (void *)kid, (void *)alloc);
-    rsScriptGroupSetInput(con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
+    rsScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
 }
 
 static void
-nScriptGroupSetOutput(JNIEnv *_env, jobject _this, RsContext con, jint gid, jint kid, jint alloc)
+nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
 {
     LOG_API("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", con,
         (void *)gid, (void *)kid, (void *)alloc);
-    rsScriptGroupSetOutput(con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
+    rsScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
 }
 
 static void
-nScriptGroupExecute(JNIEnv *_env, jobject _this, RsContext con, jint gid)
+nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
 {
     LOG_API("nScriptGroupSetOutput, con(%p) group(%p)", con, (void *)gid);
-    rsScriptGroupExecute(con, (RsScriptGroup)gid);
+    rsScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
 }
 
 // ---------------------------------------------------------------------------
 
 static jint
-nProgramStoreCreate(JNIEnv *_env, jobject _this, RsContext con,
+nProgramStoreCreate(JNIEnv *_env, jobject _this, jlong con,
                     jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
                     jboolean depthMask, jboolean ditherEnable,
                     jint srcFunc, jint destFunc,
                     jint depthFunc)
 {
     LOG_API("nProgramStoreCreate, con(%p)", con);
-    return (jint)rsProgramStoreCreate(con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
+    return (jint)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
                                       depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
                                       (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
 }
@@ -1324,30 +1269,30 @@
 // ---------------------------------------------------------------------------
 
 static void
-nProgramBindConstants(JNIEnv *_env, jobject _this, RsContext con, jint vpv, jint slot, jint a)
+nProgramBindConstants(JNIEnv *_env, jobject _this, jlong con, jlong vpv, jint slot, jlong a)
 {
     LOG_API("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
-    rsProgramBindConstants(con, (RsProgram)vpv, slot, (RsAllocation)a);
+    rsProgramBindConstants((RsContext)con, (RsProgram)vpv, slot, (RsAllocation)a);
 }
 
 static void
-nProgramBindTexture(JNIEnv *_env, jobject _this, RsContext con, jint vpf, jint slot, jint a)
+nProgramBindTexture(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
 {
     LOG_API("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
-    rsProgramBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
+    rsProgramBindTexture((RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
 }
 
 static void
-nProgramBindSampler(JNIEnv *_env, jobject _this, RsContext con, jint vpf, jint slot, jint a)
+nProgramBindSampler(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
 {
     LOG_API("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a);
-    rsProgramBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a);
+    rsProgramBindSampler((RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
 }
 
 // ---------------------------------------------------------------------------
 
-static jint
-nProgramFragmentCreate(JNIEnv *_env, jobject _this, RsContext con, jstring shader,
+static jlong
+nProgramFragmentCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
                        jobjectArray texNames, jintArray params)
 {
     AutoJavaStringToUTF8 shaderUTF(_env, shader);
@@ -1361,7 +1306,7 @@
 
     LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", con, paramLen);
 
-    jint ret = (jint)rsProgramFragmentCreate(con, shaderUTF.c_str(), shaderUTF.length(),
+    jlong ret = (jlong)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
                                              nameArray, texCount, sizeArray,
                                              (uint32_t *)paramPtr, paramLen);
 
@@ -1372,8 +1317,8 @@
 
 // ---------------------------------------------------------------------------
 
-static jint
-nProgramVertexCreate(JNIEnv *_env, jobject _this, RsContext con, jstring shader,
+static jlong
+nProgramVertexCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
                      jobjectArray texNames, jintArray params)
 {
     AutoJavaStringToUTF8 shaderUTF(_env, shader);
@@ -1387,7 +1332,7 @@
     const char ** nameArray = names.c_str();
     size_t* sizeArray = names.c_str_len();
 
-    jint ret = (jint)rsProgramVertexCreate(con, shaderUTF.c_str(), shaderUTF.length(),
+    jlong ret = (jlong)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
                                            nameArray, texCount, sizeArray,
                                            (uint32_t *)paramPtr, paramLen);
 
@@ -1397,60 +1342,60 @@
 
 // ---------------------------------------------------------------------------
 
-static jint
-nProgramRasterCreate(JNIEnv *_env, jobject _this, RsContext con, jboolean pointSprite, jint cull)
+static jlong
+nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
 {
     LOG_API("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", con, pointSprite, cull);
-    return (jint)rsProgramRasterCreate(con, pointSprite, (RsCullMode)cull);
+    return (jint)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
 }
 
 
 // ---------------------------------------------------------------------------
 
 static void
-nContextBindRootScript(JNIEnv *_env, jobject _this, RsContext con, jint script)
+nContextBindRootScript(JNIEnv *_env, jobject _this, jlong con, jint script)
 {
     LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script);
-    rsContextBindRootScript(con, (RsScript)script);
+    rsContextBindRootScript((RsContext)con, (RsScript)script);
 }
 
 static void
-nContextBindProgramStore(JNIEnv *_env, jobject _this, RsContext con, jint pfs)
+nContextBindProgramStore(JNIEnv *_env, jobject _this, jlong con, jint pfs)
 {
     LOG_API("nContextBindProgramStore, con(%p), pfs(%p)", con, (RsProgramStore)pfs);
-    rsContextBindProgramStore(con, (RsProgramStore)pfs);
+    rsContextBindProgramStore((RsContext)con, (RsProgramStore)pfs);
 }
 
 static void
-nContextBindProgramFragment(JNIEnv *_env, jobject _this, RsContext con, jint pf)
+nContextBindProgramFragment(JNIEnv *_env, jobject _this, jlong con, jint pf)
 {
     LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf);
-    rsContextBindProgramFragment(con, (RsProgramFragment)pf);
+    rsContextBindProgramFragment((RsContext)con, (RsProgramFragment)pf);
 }
 
 static void
-nContextBindProgramVertex(JNIEnv *_env, jobject _this, RsContext con, jint pf)
+nContextBindProgramVertex(JNIEnv *_env, jobject _this, jlong con, jint pf)
 {
     LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf);
-    rsContextBindProgramVertex(con, (RsProgramVertex)pf);
+    rsContextBindProgramVertex((RsContext)con, (RsProgramVertex)pf);
 }
 
 static void
-nContextBindProgramRaster(JNIEnv *_env, jobject _this, RsContext con, jint pf)
+nContextBindProgramRaster(JNIEnv *_env, jobject _this, jlong con, jint pf)
 {
     LOG_API("nContextBindProgramRaster, con(%p), pf(%p)", con, (RsProgramRaster)pf);
-    rsContextBindProgramRaster(con, (RsProgramRaster)pf);
+    rsContextBindProgramRaster((RsContext)con, (RsProgramRaster)pf);
 }
 
 
 // ---------------------------------------------------------------------------
 
 static jint
-nSamplerCreate(JNIEnv *_env, jobject _this, RsContext con, jint magFilter, jint minFilter,
+nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
                jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
 {
     LOG_API("nSamplerCreate, con(%p)", con);
-    return (jint)rsSamplerCreate(con,
+    return (jint)rsSamplerCreate((RsContext)con,
                                  (RsSamplerValue)magFilter,
                                  (RsSamplerValue)minFilter,
                                  (RsSamplerValue)wrapS,
@@ -1461,19 +1406,18 @@
 
 // ---------------------------------------------------------------------------
 
-//native int  rsnPathCreate(int con, int prim, boolean isStatic, int vtx, int loop, float q);
-static jint
-nPathCreate(JNIEnv *_env, jobject _this, RsContext con, jint prim, jboolean isStatic, jint _vtx, jint _loop, jfloat q) {
+static jlong
+nPathCreate(JNIEnv *_env, jobject _this, jlong con, jint prim, jboolean isStatic, jlong _vtx, jint _loop, jfloat q) {
     LOG_API("nPathCreate, con(%p)", con);
 
-    int id = (int)rsPathCreate(con, (RsPathPrimitive)prim, isStatic,
-                               (RsAllocation)_vtx,
-                               (RsAllocation)_loop, q);
+    jlong id = (jlong)rsPathCreate((RsContext)con, (RsPathPrimitive)prim, isStatic,
+                                   (RsAllocation)_vtx,
+                                   (RsAllocation)_loop, q);
     return id;
 }
 
-static jint
-nMeshCreate(JNIEnv *_env, jobject _this, RsContext con, jintArray _vtx, jintArray _idx, jintArray _prim)
+static jlong
+nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jintArray _vtx, jintArray _idx, jintArray _prim)
 {
     LOG_API("nMeshCreate, con(%p)", con);
 
@@ -1484,7 +1428,7 @@
     jint primLen = _env->GetArrayLength(_prim);
     jint *primPtr = _env->GetIntArrayElements(_prim, NULL);
 
-    int id = (int)rsMeshCreate(con,
+    int id = (int)rsMeshCreate((RsContext)con,
                                (RsAllocation *)vtxPtr, vtxLen,
                                (RsAllocation *)idxPtr, idxLen,
                                (uint32_t *)primPtr, primLen);
@@ -1496,30 +1440,30 @@
 }
 
 static jint
-nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
+nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
 {
     LOG_API("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", con, (RsMesh)mesh);
     jint vtxCount = 0;
-    rsaMeshGetVertexBufferCount(con, (RsMesh)mesh, &vtxCount);
+    rsaMeshGetVertexBufferCount((RsContext)con, (RsMesh)mesh, &vtxCount);
     return vtxCount;
 }
 
 static jint
-nMeshGetIndexCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
+nMeshGetIndexCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
 {
     LOG_API("nMeshGetIndexCount, con(%p), Mesh(%p)", con, (RsMesh)mesh);
     jint idxCount = 0;
-    rsaMeshGetIndexCount(con, (RsMesh)mesh, &idxCount);
+    rsaMeshGetIndexCount((RsContext)con, (RsMesh)mesh, &idxCount);
     return idxCount;
 }
 
 static void
-nMeshGetVertices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray _ids, int numVtxIDs)
+nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jintArray _ids, int numVtxIDs)
 {
     LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh);
 
     RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
-    rsaMeshGetVertices(con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
+    rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
 
     for(jint i = 0; i < numVtxIDs; i ++) {
         _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&allocs[i]);
@@ -1529,14 +1473,14 @@
 }
 
 static void
-nMeshGetIndices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray _idxIds, jintArray _primitives, int numIndices)
+nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jintArray _idxIds, jintArray _primitives, int numIndices)
 {
     LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh);
 
     RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
     uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
 
-    rsaMeshGetIndices(con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
+    rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
 
     for(jint i = 0; i < numIndices; i ++) {
         _env->SetIntArrayRegion(_idxIds, i, 1, (const jint*)&allocs[i]);
@@ -1555,142 +1499,132 @@
 static JNINativeMethod methods[] = {
 {"_nInit",                         "()V",                                     (void*)_nInit },
 
-{"nDeviceCreate",                  "()I",                                     (void*)nDeviceCreate },
-{"nDeviceDestroy",                 "(I)V",                                    (void*)nDeviceDestroy },
-{"nDeviceSetConfig",               "(III)V",                                  (void*)nDeviceSetConfig },
-{"nContextGetUserMessage",         "(I[I)I",                                  (void*)nContextGetUserMessage },
-{"nContextGetErrorMessage",        "(I)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
-{"nContextPeekMessage",            "(I[I)I",                                  (void*)nContextPeekMessage },
+{"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
+{"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
+{"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
+{"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
+{"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
+{"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
 
-{"nContextInitToClient",           "(I)V",                                    (void*)nContextInitToClient },
-{"nContextDeinitToClient",         "(I)V",                                    (void*)nContextDeinitToClient },
+{"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
+{"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
 
 
 // All methods below are thread protected in java.
-{"rsnContextCreate",                 "(IIII)I",                               (void*)nContextCreate },
-{"rsnContextCreateGL",               "(IIIIIIIIIIIIIFI)I",                    (void*)nContextCreateGL },
-{"rsnContextFinish",                 "(I)V",                                  (void*)nContextFinish },
-{"rsnContextSetPriority",            "(II)V",                                 (void*)nContextSetPriority },
-{"rsnContextSetSurface",             "(IIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
-{"rsnContextDestroy",                "(I)V",                                  (void*)nContextDestroy },
-{"rsnContextDump",                   "(II)V",                                 (void*)nContextDump },
-{"rsnContextPause",                  "(I)V",                                  (void*)nContextPause },
-{"rsnContextResume",                 "(I)V",                                  (void*)nContextResume },
-{"rsnContextSendMessage",            "(II[I)V",                               (void*)nContextSendMessage },
-{"rsnAssignName",                    "(II[B)V",                               (void*)nAssignName },
-{"rsnGetName",                       "(II)Ljava/lang/String;",                (void*)nGetName },
-{"rsnObjDestroy",                    "(II)V",                                 (void*)nObjDestroy },
+{"rsnContextCreate",                 "(JIII)J",                               (void*)nContextCreate },
+{"rsnContextCreateGL",               "(JIIIIIIIIIIIIFI)J",                    (void*)nContextCreateGL },
+{"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
+{"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
+{"rsnContextSetSurface",             "(JIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
+{"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
+{"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
+{"rsnContextPause",                  "(J)V",                                  (void*)nContextPause },
+{"rsnContextResume",                 "(J)V",                                  (void*)nContextResume },
+{"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
+{"rsnAssignName",                    "(JJ[B)V",                               (void*)nAssignName },
+{"rsnGetName",                       "(JJ)Ljava/lang/String;",                (void*)nGetName },
+{"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
 
-{"rsnFileA3DCreateFromFile",         "(ILjava/lang/String;)I",                (void*)nFileA3DCreateFromFile },
-{"rsnFileA3DCreateFromAssetStream",  "(II)I",                                 (void*)nFileA3DCreateFromAssetStream },
-{"rsnFileA3DCreateFromAsset",        "(ILandroid/content/res/AssetManager;Ljava/lang/String;)I",            (void*)nFileA3DCreateFromAsset },
-{"rsnFileA3DGetNumIndexEntries",     "(II)I",                                 (void*)nFileA3DGetNumIndexEntries },
-{"rsnFileA3DGetIndexEntries",        "(III[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
-{"rsnFileA3DGetEntryByIndex",        "(III)I",                                (void*)nFileA3DGetEntryByIndex },
+{"rsnFileA3DCreateFromFile",         "(JLjava/lang/String;)J",                (void*)nFileA3DCreateFromFile },
+{"rsnFileA3DCreateFromAssetStream",  "(JI)J",                                 (void*)nFileA3DCreateFromAssetStream },
+{"rsnFileA3DCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;)J",            (void*)nFileA3DCreateFromAsset },
+{"rsnFileA3DGetNumIndexEntries",     "(JJ)I",                                 (void*)nFileA3DGetNumIndexEntries },
+{"rsnFileA3DGetIndexEntries",        "(JJI[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
+{"rsnFileA3DGetEntryByIndex",        "(JJI)I",                                (void*)nFileA3DGetEntryByIndex },
 
-{"rsnFontCreateFromFile",            "(ILjava/lang/String;FI)I",              (void*)nFontCreateFromFile },
-{"rsnFontCreateFromAssetStream",     "(ILjava/lang/String;FII)I",             (void*)nFontCreateFromAssetStream },
-{"rsnFontCreateFromAsset",        "(ILandroid/content/res/AssetManager;Ljava/lang/String;FI)I",            (void*)nFontCreateFromAsset },
+{"rsnFontCreateFromFile",            "(JLjava/lang/String;FI)I",              (void*)nFontCreateFromFile },
+{"rsnFontCreateFromAssetStream",     "(JLjava/lang/String;FII)I",             (void*)nFontCreateFromAssetStream },
+{"rsnFontCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;FI)I",            (void*)nFontCreateFromAsset },
 
-{"rsnElementCreate",                 "(IIIZI)I",                              (void*)nElementCreate },
-{"rsnElementCreate2",                "(I[I[Ljava/lang/String;[I)I",           (void*)nElementCreate2 },
-{"rsnElementGetNativeData",          "(II[I)V",                               (void*)nElementGetNativeData },
-{"rsnElementGetSubElements",         "(II[I[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
+{"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
+{"rsnElementCreate2",                "(J[I[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
+{"rsnElementGetNativeData",          "(JJ[I)V",                               (void*)nElementGetNativeData },
+{"rsnElementGetSubElements",         "(JJ[I[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
 
-{"rsnTypeCreate",                    "(IIIIIZZI)I",                           (void*)nTypeCreate },
-{"rsnTypeGetNativeData",             "(II[I)V",                               (void*)nTypeGetNativeData },
+{"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
+{"rsnTypeGetNativeData",             "(JJ[I)V",                               (void*)nTypeGetNativeData },
 
-{"rsnAllocationCreateTyped",         "(IIIII)I",                               (void*)nAllocationCreateTyped },
-{"rsnAllocationCreateFromBitmap",    "(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCreateFromBitmap },
-{"rsnAllocationCreateBitmapBackedAllocation",    "(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCreateBitmapBackedAllocation },
-{"rsnAllocationCubeCreateFromBitmap","(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCubeCreateFromBitmap },
+{"rsnAllocationCreateTyped",         "(JJIII)J",                               (void*)nAllocationCreateTyped },
+{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
+{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
+{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
 
-{"rsnAllocationCopyFromBitmap",      "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
-{"rsnAllocationCopyToBitmap",        "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
+{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
+{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
 
-{"rsnAllocationSyncAll",             "(III)V",                                (void*)nAllocationSyncAll },
-{"rsnAllocationGetSurface",          "(II)Landroid/view/Surface;",            (void*)nAllocationGetSurface },
-{"rsnAllocationSetSurface",          "(IILandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
-{"rsnAllocationIoSend",              "(II)V",                                 (void*)nAllocationIoSend },
-{"rsnAllocationIoReceive",           "(II)V",                                 (void*)nAllocationIoReceive },
-{"rsnAllocationData1D",              "(IIIII[II)V",                           (void*)nAllocationData1D_i },
-{"rsnAllocationData1D",              "(IIIII[SI)V",                           (void*)nAllocationData1D_s },
-{"rsnAllocationData1D",              "(IIIII[BI)V",                           (void*)nAllocationData1D_b },
-{"rsnAllocationData1D",              "(IIIII[FI)V",                           (void*)nAllocationData1D_f },
-{"rsnAllocationElementData1D",       "(IIIII[BI)V",                           (void*)nAllocationElementData1D },
-{"rsnAllocationData2D",              "(IIIIIIII[II)V",                        (void*)nAllocationData2D_i },
-{"rsnAllocationData2D",              "(IIIIIIII[SI)V",                        (void*)nAllocationData2D_s },
-{"rsnAllocationData2D",              "(IIIIIIII[BI)V",                        (void*)nAllocationData2D_b },
-{"rsnAllocationData2D",              "(IIIIIIII[FI)V",                        (void*)nAllocationData2D_f },
-{"rsnAllocationData2D",              "(IIIIIIIIIIIII)V",                      (void*)nAllocationData2D_alloc },
-{"rsnAllocationData3D",              "(IIIIIIIII[II)V",                       (void*)nAllocationData3D_i },
-{"rsnAllocationData3D",              "(IIIIIIIII[SI)V",                       (void*)nAllocationData3D_s },
-{"rsnAllocationData3D",              "(IIIIIIIII[BI)V",                       (void*)nAllocationData3D_b },
-{"rsnAllocationData3D",              "(IIIIIIIII[FI)V",                       (void*)nAllocationData3D_f },
-{"rsnAllocationData3D",              "(IIIIIIIIIIIIII)V",                     (void*)nAllocationData3D_alloc },
-{"rsnAllocationRead",                "(II[I)V",                               (void*)nAllocationRead_i },
-{"rsnAllocationRead",                "(II[S)V",                               (void*)nAllocationRead_s },
-{"rsnAllocationRead",                "(II[B)V",                               (void*)nAllocationRead_b },
-{"rsnAllocationRead",                "(II[F)V",                               (void*)nAllocationRead_f },
-{"rsnAllocationGetType",             "(II)I",                                 (void*)nAllocationGetType},
-{"rsnAllocationResize1D",            "(III)V",                                (void*)nAllocationResize1D },
-{"rsnAllocationGenerateMipmaps",     "(II)V",                                 (void*)nAllocationGenerateMipmaps },
+{"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
+{"rsnAllocationGetSurface",          "(JJ)Landroid/view/Surface;",            (void*)nAllocationGetSurface },
+{"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
+{"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
+{"rsnAllocationIoReceive",           "(JJ)V",                                 (void*)nAllocationIoReceive },
+{"rsnAllocationData1D",              "(JJIIILjava/lang/Object;II)V",          (void*)nAllocationData1D },
+{"rsnAllocationElementData1D",       "(JJIII[BI)V",                           (void*)nAllocationElementData1D },
+{"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;II)V",       (void*)nAllocationData2D },
+{"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
+{"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;II)V",      (void*)nAllocationData3D },
+{"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
+{"rsnAllocationRead",                "(JJLjava/lang/Object;I)V",              (void*)nAllocationRead },
+{"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;II)V",          (void*)nAllocationRead1D },
+{"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;II)V",       (void*)nAllocationRead2D },
+{"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
+{"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
+{"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
 
-{"rsnScriptBindAllocation",          "(IIII)V",                               (void*)nScriptBindAllocation },
-{"rsnScriptSetTimeZone",             "(II[B)V",                               (void*)nScriptSetTimeZone },
-{"rsnScriptInvoke",                  "(III)V",                                (void*)nScriptInvoke },
-{"rsnScriptInvokeV",                 "(III[B)V",                              (void*)nScriptInvokeV },
-{"rsnScriptForEach",                 "(IIIII)V",                              (void*)nScriptForEach },
-{"rsnScriptForEach",                 "(IIIII[B)V",                            (void*)nScriptForEachV },
-{"rsnScriptForEachClipped",          "(IIIIIIIIIII)V",                        (void*)nScriptForEachClipped },
-{"rsnScriptForEachClipped",          "(IIIII[BIIIIII)V",                      (void*)nScriptForEachClippedV },
-{"rsnScriptSetVarI",                 "(IIII)V",                               (void*)nScriptSetVarI },
-{"rsnScriptGetVarI",                 "(III)I",                                (void*)nScriptGetVarI },
-{"rsnScriptSetVarJ",                 "(IIIJ)V",                               (void*)nScriptSetVarJ },
-{"rsnScriptGetVarJ",                 "(III)J",                                (void*)nScriptGetVarJ },
-{"rsnScriptSetVarF",                 "(IIIF)V",                               (void*)nScriptSetVarF },
-{"rsnScriptGetVarF",                 "(III)F",                                (void*)nScriptGetVarF },
-{"rsnScriptSetVarD",                 "(IIID)V",                               (void*)nScriptSetVarD },
-{"rsnScriptGetVarD",                 "(III)D",                                (void*)nScriptGetVarD },
-{"rsnScriptSetVarV",                 "(III[B)V",                              (void*)nScriptSetVarV },
-{"rsnScriptGetVarV",                 "(III[B)V",                              (void*)nScriptGetVarV },
-{"rsnScriptSetVarVE",                "(III[BI[I)V",                           (void*)nScriptSetVarVE },
-{"rsnScriptSetVarObj",               "(IIII)V",                               (void*)nScriptSetVarObj },
+{"rsnScriptBindAllocation",          "(JJJI)V",                               (void*)nScriptBindAllocation },
+{"rsnScriptSetTimeZone",             "(JJ[B)V",                               (void*)nScriptSetTimeZone },
+{"rsnScriptInvoke",                  "(JJI)V",                                (void*)nScriptInvoke },
+{"rsnScriptInvokeV",                 "(JJI[B)V",                              (void*)nScriptInvokeV },
+{"rsnScriptForEach",                 "(JJIJJ)V",                              (void*)nScriptForEach },
+{"rsnScriptForEach",                 "(JJIJJ[B)V",                            (void*)nScriptForEachV },
+{"rsnScriptForEachClipped",          "(JJIJJIIIIII)V",                        (void*)nScriptForEachClipped },
+{"rsnScriptForEachClipped",          "(JJIJJ[BIIIIII)V",                      (void*)nScriptForEachClippedV },
+{"rsnScriptSetVarI",                 "(JJII)V",                               (void*)nScriptSetVarI },
+{"rsnScriptGetVarI",                 "(JJI)I",                                (void*)nScriptGetVarI },
+{"rsnScriptSetVarJ",                 "(JJIJ)V",                               (void*)nScriptSetVarJ },
+{"rsnScriptGetVarJ",                 "(JJI)J",                                (void*)nScriptGetVarJ },
+{"rsnScriptSetVarF",                 "(JJIF)V",                               (void*)nScriptSetVarF },
+{"rsnScriptGetVarF",                 "(JJI)F",                                (void*)nScriptGetVarF },
+{"rsnScriptSetVarD",                 "(JJID)V",                               (void*)nScriptSetVarD },
+{"rsnScriptGetVarD",                 "(JJI)D",                                (void*)nScriptGetVarD },
+{"rsnScriptSetVarV",                 "(JJI[B)V",                              (void*)nScriptSetVarV },
+{"rsnScriptGetVarV",                 "(JJI[B)V",                              (void*)nScriptGetVarV },
+{"rsnScriptSetVarVE",                "(JJI[BJ[I)V",                           (void*)nScriptSetVarVE },
+{"rsnScriptSetVarObj",               "(JJIJ)V",                               (void*)nScriptSetVarObj },
 
-{"rsnScriptCCreate",                 "(ILjava/lang/String;Ljava/lang/String;[BI)I",  (void*)nScriptCCreate },
-{"rsnScriptIntrinsicCreate",         "(III)I",                                (void*)nScriptIntrinsicCreate },
-{"rsnScriptKernelIDCreate",          "(IIII)I",                               (void*)nScriptKernelIDCreate },
-{"rsnScriptFieldIDCreate",           "(III)I",                                (void*)nScriptFieldIDCreate },
-{"rsnScriptGroupCreate",             "(I[I[I[I[I[I)I",                        (void*)nScriptGroupCreate },
-{"rsnScriptGroupSetInput",           "(IIII)V",                               (void*)nScriptGroupSetInput },
-{"rsnScriptGroupSetOutput",          "(IIII)V",                               (void*)nScriptGroupSetOutput },
-{"rsnScriptGroupExecute",            "(II)V",                                 (void*)nScriptGroupExecute },
+{"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)I",  (void*)nScriptCCreate },
+{"rsnScriptIntrinsicCreate",         "(JIJ)J",                                (void*)nScriptIntrinsicCreate },
+{"rsnScriptKernelIDCreate",          "(JJII)J",                               (void*)nScriptKernelIDCreate },
+{"rsnScriptFieldIDCreate",           "(JJI)J",                                (void*)nScriptFieldIDCreate },
+{"rsnScriptGroupCreate",             "(J[I[I[I[I[I)J",                        (void*)nScriptGroupCreate },
+{"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
+{"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
+{"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
 
-{"rsnProgramStoreCreate",            "(IZZZZZZIII)I",                         (void*)nProgramStoreCreate },
+{"rsnProgramStoreCreate",            "(JZZZZZZIII)I",                         (void*)nProgramStoreCreate },
 
-{"rsnProgramBindConstants",          "(IIII)V",                               (void*)nProgramBindConstants },
-{"rsnProgramBindTexture",            "(IIII)V",                               (void*)nProgramBindTexture },
-{"rsnProgramBindSampler",            "(IIII)V",                               (void*)nProgramBindSampler },
+{"rsnProgramBindConstants",          "(JJIJ)V",                               (void*)nProgramBindConstants },
+{"rsnProgramBindTexture",            "(JJIJ)V",                               (void*)nProgramBindTexture },
+{"rsnProgramBindSampler",            "(JJIJ)V",                               (void*)nProgramBindSampler },
 
-{"rsnProgramFragmentCreate",         "(ILjava/lang/String;[Ljava/lang/String;[I)I",              (void*)nProgramFragmentCreate },
-{"rsnProgramRasterCreate",           "(IZI)I",                                (void*)nProgramRasterCreate },
-{"rsnProgramVertexCreate",           "(ILjava/lang/String;[Ljava/lang/String;[I)I",              (void*)nProgramVertexCreate },
+{"rsnProgramFragmentCreate",         "(JLjava/lang/String;[Ljava/lang/String;[I)J",              (void*)nProgramFragmentCreate },
+{"rsnProgramRasterCreate",           "(JZI)J",                                (void*)nProgramRasterCreate },
+{"rsnProgramVertexCreate",           "(JLjava/lang/String;[Ljava/lang/String;[I)J",              (void*)nProgramVertexCreate },
 
-{"rsnContextBindRootScript",         "(II)V",                                 (void*)nContextBindRootScript },
-{"rsnContextBindProgramStore",       "(II)V",                                 (void*)nContextBindProgramStore },
-{"rsnContextBindProgramFragment",    "(II)V",                                 (void*)nContextBindProgramFragment },
-{"rsnContextBindProgramVertex",      "(II)V",                                 (void*)nContextBindProgramVertex },
-{"rsnContextBindProgramRaster",      "(II)V",                                 (void*)nContextBindProgramRaster },
+{"rsnContextBindRootScript",         "(JI)V",                                 (void*)nContextBindRootScript },
+{"rsnContextBindProgramStore",       "(JI)V",                                 (void*)nContextBindProgramStore },
+{"rsnContextBindProgramFragment",    "(JI)V",                                 (void*)nContextBindProgramFragment },
+{"rsnContextBindProgramVertex",      "(JI)V",                                 (void*)nContextBindProgramVertex },
+{"rsnContextBindProgramRaster",      "(JI)V",                                 (void*)nContextBindProgramRaster },
 
-{"rsnSamplerCreate",                 "(IIIIIIF)I",                            (void*)nSamplerCreate },
+{"rsnSamplerCreate",                 "(JIIIIIF)I",                            (void*)nSamplerCreate },
 
-{"rsnPathCreate",                    "(IIZIIF)I",                             (void*)nPathCreate },
-{"rsnMeshCreate",                    "(I[I[I[I)I",                            (void*)nMeshCreate },
+{"rsnPathCreate",                    "(JIZJIF)J",                             (void*)nPathCreate },
+{"rsnMeshCreate",                    "(J[I[I[I)J",                            (void*)nMeshCreate },
 
-{"rsnMeshGetVertexBufferCount",      "(II)I",                                 (void*)nMeshGetVertexBufferCount },
-{"rsnMeshGetIndexCount",             "(II)I",                                 (void*)nMeshGetIndexCount },
-{"rsnMeshGetVertices",               "(II[II)V",                              (void*)nMeshGetVertices },
-{"rsnMeshGetIndices",                "(II[I[II)V",                            (void*)nMeshGetIndices },
+{"rsnMeshGetVertexBufferCount",      "(JJ)I",                                 (void*)nMeshGetVertexBufferCount },
+{"rsnMeshGetIndexCount",             "(JJ)I",                                 (void*)nMeshGetIndexCount },
+{"rsnMeshGetVertices",               "(JJ[II)V",                              (void*)nMeshGetVertices },
+{"rsnMeshGetIndices",                "(JJ[I[II)V",                            (void*)nMeshGetIndices },
 
 };
 
diff --git a/include/androidfw/Asset.h b/include/androidfw/Asset.h
deleted file mode 100644
index 1fe0e06..0000000
--- a/include/androidfw/Asset.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Class providing access to a read-only asset.  Asset objects are NOT
-// thread-safe, and should not be shared across threads.
-//
-#ifndef __LIBS_ASSET_H
-#define __LIBS_ASSET_H
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#include <utils/Compat.h>
-#include <utils/Errors.h>
-#include <utils/FileMap.h>
-#include <utils/String8.h>
-
-namespace android {
-
-/*
- * Instances of this class provide read-only operations on a byte stream.
- *
- * Access may be optimized for streaming, random, or whole buffer modes.  All
- * operations are supported regardless of how the file was opened, but some
- * things will be less efficient.  [pass that in??]
- *
- * "Asset" is the base class for all types of assets.  The classes below
- * provide most of the implementation.  The AssetManager uses one of the
- * static "create" functions defined here to create a new instance.
- */
-class Asset {
-public:
-    virtual ~Asset(void);
-
-    static int32_t getGlobalCount();
-    static String8 getAssetAllocations();
-    
-    /* used when opening an asset */
-    typedef enum AccessMode {
-        ACCESS_UNKNOWN = 0,
-
-        /* read chunks, and seek forward and backward */
-        ACCESS_RANDOM,
-
-        /* read sequentially, with an occasional forward seek */
-        ACCESS_STREAMING,
-
-        /* caller plans to ask for a read-only buffer with all data */
-        ACCESS_BUFFER,
-    } AccessMode;
-
-    /*
-     * Read data from the current offset.  Returns the actual number of
-     * bytes read, 0 on EOF, or -1 on error.
-     */
-    virtual ssize_t read(void* buf, size_t count) = 0;
-
-    /*
-     * Seek to the specified offset.  "whence" uses the same values as
-     * lseek/fseek.  Returns the new position on success, or (off64_t) -1
-     * on failure.
-     */
-    virtual off64_t seek(off64_t offset, int whence) = 0;
-
-    /*
-     * Close the asset, freeing all associated resources.
-     */
-    virtual void close(void) = 0;
-
-    /*
-     * Get a pointer to a buffer with the entire contents of the file.
-     */
-    virtual const void* getBuffer(bool wordAligned) = 0;
-
-    /*
-     * Get the total amount of data that can be read.
-     */
-    virtual off64_t getLength(void) const = 0;
-
-    /*
-     * Get the total amount of data that can be read from the current position.
-     */
-    virtual off64_t getRemainingLength(void) const = 0;
-
-    /*
-     * Open a new file descriptor that can be used to read this asset.
-     * Returns -1 if you can not use the file descriptor (for example if the
-     * asset is compressed).
-     */
-    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const = 0;
-
-    /*
-     * Return whether this asset's buffer is allocated in RAM (not mmapped).
-     * Note: not virtual so it is safe to call even when being destroyed.
-     */
-    virtual bool isAllocated(void) const { return false; }
-
-    /*
-     * Get a string identifying the asset's source.  This might be a full
-     * path, it might be a colon-separated list of identifiers.
-     *
-     * This is NOT intended to be used for anything except debug output.
-     * DO NOT try to parse this or use it to open a file.
-     */
-    const char* getAssetSource(void) const { return mAssetSource.string(); }
-
-protected:
-    Asset(void);        // constructor; only invoked indirectly
-
-    /* handle common seek() housekeeping */
-    off64_t handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn);
-
-    /* set the asset source string */
-    void setAssetSource(const String8& path) { mAssetSource = path; }
-
-    AccessMode getAccessMode(void) const { return mAccessMode; }
-
-private:
-    /* these operations are not implemented */
-    Asset(const Asset& src);
-    Asset& operator=(const Asset& src);
-
-    /* AssetManager needs access to our "create" functions */
-    friend class AssetManager;
-
-    /*
-     * Create the asset from a named file on disk.
-     */
-    static Asset* createFromFile(const char* fileName, AccessMode mode);
-
-    /*
-     * Create the asset from a named, compressed file on disk (e.g. ".gz").
-     */
-    static Asset* createFromCompressedFile(const char* fileName,
-        AccessMode mode);
-
-#if 0
-    /*
-     * Create the asset from a segment of an open file.  This will fail
-     * if "offset" and "length" don't fit within the bounds of the file.
-     *
-     * The asset takes ownership of the file descriptor.
-     */
-    static Asset* createFromFileSegment(int fd, off64_t offset, size_t length,
-        AccessMode mode);
-
-    /*
-     * Create from compressed data.  "fd" should be seeked to the start of
-     * the compressed data.  This could be inside a gzip file or part of a
-     * Zip archive.
-     *
-     * The asset takes ownership of the file descriptor.
-     *
-     * This may not verify the validity of the compressed data until first
-     * use.
-     */
-    static Asset* createFromCompressedData(int fd, off64_t offset,
-        int compressionMethod, size_t compressedLength,
-        size_t uncompressedLength, AccessMode mode);
-#endif
-
-    /*
-     * Create the asset from a memory-mapped file segment.
-     *
-     * The asset takes ownership of the FileMap.
-     */
-    static Asset* createFromUncompressedMap(FileMap* dataMap, AccessMode mode);
-
-    /*
-     * Create the asset from a memory-mapped file segment with compressed
-     * data.  "method" is a Zip archive compression method constant.
-     *
-     * The asset takes ownership of the FileMap.
-     */
-    static Asset* createFromCompressedMap(FileMap* dataMap, int method,
-        size_t uncompressedLen, AccessMode mode);
-
-
-    /*
-     * Create from a reference-counted chunk of shared memory.
-     */
-    // TODO
-
-    AccessMode  mAccessMode;        // how the asset was opened
-    String8    mAssetSource;       // debug string
-    
-    Asset*		mNext;				// linked list.
-    Asset*		mPrev;
-};
-
-
-/*
- * ===========================================================================
- *
- * Innards follow.  Do not use these classes directly.
- */
-
-/*
- * An asset based on an uncompressed file on disk.  It may encompass the
- * entire file or just a piece of it.  Access is through fread/fseek.
- */
-class _FileAsset : public Asset {
-public:
-    _FileAsset(void);
-    virtual ~_FileAsset(void);
-
-    /*
-     * Use a piece of an already-open file.
-     *
-     * On success, the object takes ownership of "fd".
-     */
-    status_t openChunk(const char* fileName, int fd, off64_t offset, size_t length);
-
-    /*
-     * Use a memory-mapped region.
-     *
-     * On success, the object takes ownership of "dataMap".
-     */
-    status_t openChunk(FileMap* dataMap);
-
-    /*
-     * Standard Asset interfaces.
-     */
-    virtual ssize_t read(void* buf, size_t count);
-    virtual off64_t seek(off64_t offset, int whence);
-    virtual void close(void);
-    virtual const void* getBuffer(bool wordAligned);
-    virtual off64_t getLength(void) const { return mLength; }
-    virtual off64_t getRemainingLength(void) const { return mLength-mOffset; }
-    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const;
-    virtual bool isAllocated(void) const { return mBuf != NULL; }
-
-private:
-    off64_t     mStart;         // absolute file offset of start of chunk
-    off64_t     mLength;        // length of the chunk
-    off64_t     mOffset;        // current local offset, 0 == mStart
-    FILE*       mFp;            // for read/seek
-    char*       mFileName;      // for opening
-
-    /*
-     * To support getBuffer() we either need to read the entire thing into
-     * a buffer or memory-map it.  For small files it's probably best to
-     * just read them in.
-     */
-    enum { kReadVsMapThreshold = 4096 };
-
-    FileMap*    mMap;           // for memory map
-    unsigned char* mBuf;        // for read
-    
-    const void* ensureAlignment(FileMap* map);
-};
-
-
-/*
- * An asset based on compressed data in a file.
- */
-class _CompressedAsset : public Asset {
-public:
-    _CompressedAsset(void);
-    virtual ~_CompressedAsset(void);
-
-    /*
-     * Use a piece of an already-open file.
-     *
-     * On success, the object takes ownership of "fd".
-     */
-    status_t openChunk(int fd, off64_t offset, int compressionMethod,
-        size_t uncompressedLen, size_t compressedLen);
-
-    /*
-     * Use a memory-mapped region.
-     *
-     * On success, the object takes ownership of "fd".
-     */
-    status_t openChunk(FileMap* dataMap, int compressionMethod,
-        size_t uncompressedLen);
-
-    /*
-     * Standard Asset interfaces.
-     */
-    virtual ssize_t read(void* buf, size_t count);
-    virtual off64_t seek(off64_t offset, int whence);
-    virtual void close(void);
-    virtual const void* getBuffer(bool wordAligned);
-    virtual off64_t getLength(void) const { return mUncompressedLen; }
-    virtual off64_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }
-    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const { return -1; }
-    virtual bool isAllocated(void) const { return mBuf != NULL; }
-
-private:
-    off64_t     mStart;         // offset to start of compressed data
-    off64_t     mCompressedLen; // length of the compressed data
-    off64_t     mUncompressedLen; // length of the uncompressed data
-    off64_t     mOffset;        // current offset, 0 == start of uncomp data
-
-    FileMap*    mMap;           // for memory-mapped input
-    int         mFd;            // for file input
-
-    class StreamingZipInflater* mZipInflater;  // for streaming large compressed assets
-
-    unsigned char*  mBuf;       // for getBuffer()
-};
-
-// need: shared mmap version?
-
-}; // namespace android
-
-#endif // __LIBS_ASSET_H
diff --git a/include/androidfw/AssetDir.h b/include/androidfw/AssetDir.h
deleted file mode 100644
index bd89d7d..0000000
--- a/include/androidfw/AssetDir.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Access a chunk of the asset hierarchy as if it were a single directory.
-//
-#ifndef __LIBS_ASSETDIR_H
-#define __LIBS_ASSETDIR_H
-
-#include <androidfw/misc.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
-#include <utils/SortedVector.h>
-#include <sys/types.h>
-
-namespace android {
-
-/*
- * This provides vector-style access to a directory.  We do this rather
- * than modeling opendir/readdir access because it's simpler and the
- * nature of the operation requires us to have all data on hand anyway.
- *
- * The list of files will be sorted in ascending order by ASCII value.
- *
- * The contents are populated by our friend, the AssetManager.
- */
-class AssetDir {
-public:
-    AssetDir(void)
-        : mFileInfo(NULL)
-        {}
-    virtual ~AssetDir(void) {
-        delete mFileInfo;
-    }
-
-    /*
-     * Vector-style access.
-     */
-    size_t getFileCount(void) { return mFileInfo->size(); }
-    const String8& getFileName(int idx) {
-        return mFileInfo->itemAt(idx).getFileName();
-    }
-    const String8& getSourceName(int idx) {
-        return mFileInfo->itemAt(idx).getSourceName();
-    }
-
-    /*
-     * Get the type of a file (usually regular or directory).
-     */
-    FileType getFileType(int idx) {
-        return mFileInfo->itemAt(idx).getFileType();
-    }
-
-private:
-    /* these operations are not implemented */
-    AssetDir(const AssetDir& src);
-    const AssetDir& operator=(const AssetDir& src);
-
-    friend class AssetManager;
-
-    /*
-     * This holds information about files in the asset hierarchy.
-     */
-    class FileInfo {
-    public:
-        FileInfo(void) {}
-        FileInfo(const String8& path)      // useful for e.g. svect.indexOf
-            : mFileName(path), mFileType(kFileTypeUnknown)
-            {}
-        ~FileInfo(void) {}
-        FileInfo(const FileInfo& src) {
-            copyMembers(src);
-        }
-        const FileInfo& operator= (const FileInfo& src) {
-            if (this != &src)
-                copyMembers(src);
-            return *this;
-        }
-
-        void copyMembers(const FileInfo& src) {
-            mFileName = src.mFileName;
-            mFileType = src.mFileType;
-            mSourceName = src.mSourceName;
-        }
-
-        /* need this for SortedVector; must compare only on file name */
-        bool operator< (const FileInfo& rhs) const {
-            return mFileName < rhs.mFileName;
-        }
-
-        /* used by AssetManager */
-        bool operator== (const FileInfo& rhs) const {
-            return mFileName == rhs.mFileName;
-        }
-
-        void set(const String8& path, FileType type) {
-            mFileName = path;
-            mFileType = type;
-        }
-
-        const String8& getFileName(void) const { return mFileName; }
-        void setFileName(const String8& path) { mFileName = path; }
-
-        FileType getFileType(void) const { return mFileType; }
-        void setFileType(FileType type) { mFileType = type; }
-
-        const String8& getSourceName(void) const { return mSourceName; }
-        void setSourceName(const String8& path) { mSourceName = path; }
-
-        /*
-         * Handy utility for finding an entry in a sorted vector of FileInfo.
-         * Returns the index of the matching entry, or -1 if none found.
-         */
-        static int findEntry(const SortedVector<FileInfo>* pVector,
-            const String8& fileName);
-
-    private:
-        String8    mFileName;      // filename only
-        FileType    mFileType;      // regular, directory, etc
-
-        String8    mSourceName;    // currently debug-only
-    };
-
-    /* AssetManager uses this to initialize us */
-    void setFileList(SortedVector<FileInfo>* list) { mFileInfo = list; }
-
-    SortedVector<FileInfo>* mFileInfo;
-};
-
-}; // namespace android
-
-#endif // __LIBS_ASSETDIR_H
diff --git a/include/androidfw/AssetManager.h b/include/androidfw/AssetManager.h
deleted file mode 100644
index d95b45e..0000000
--- a/include/androidfw/AssetManager.h
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Asset management class.  AssetManager objects are thread-safe.
-//
-#ifndef __LIBS_ASSETMANAGER_H
-#define __LIBS_ASSETMANAGER_H
-
-#include <androidfw/Asset.h>
-#include <androidfw/AssetDir.h>
-#include <androidfw/ZipFileRO.h>
-#include <utils/KeyedVector.h>
-#include <utils/SortedVector.h>
-#include <utils/String16.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-#include <utils/Vector.h>
-
-/*
- * Native-app access is via the opaque typedef struct AAssetManager in the C namespace.
- */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct AAssetManager { };
-
-#ifdef __cplusplus
-};
-#endif
-
-
-/*
- * Now the proper C++ android-namespace definitions
- */
-
-namespace android {
-
-class Asset;        // fwd decl for things that include Asset.h first
-class ResTable;
-struct ResTable_config;
-
-/*
- * Every application that uses assets needs one instance of this.  A
- * single instance may be shared across multiple threads, and a single
- * thread may have more than one instance (the latter is discouraged).
- *
- * The purpose of the AssetManager is to create Asset objects.  To do
- * this efficiently it may cache information about the locations of
- * files it has seen.  This can be controlled with the "cacheMode"
- * argument.
- *
- * The asset hierarchy may be examined like a filesystem, using
- * AssetDir objects to peruse a single directory.
- */
-class AssetManager : public AAssetManager {
-public:
-    typedef enum CacheMode {
-        CACHE_UNKNOWN = 0,
-        CACHE_OFF,          // don't try to cache file locations
-        CACHE_DEFER,        // construct cache as pieces are needed
-        //CACHE_SCAN,         // scan full(!) asset hierarchy at init() time
-    } CacheMode;
-
-    AssetManager(CacheMode cacheMode = CACHE_OFF);
-    virtual ~AssetManager(void);
-
-    static int32_t getGlobalCount();
-    
-    /*                                                                       
-     * Add a new source for assets.  This can be called multiple times to
-     * look in multiple places for assets.  It can be either a directory (for
-     * finding assets as raw files on the disk) or a ZIP file.  This newly
-     * added asset path will be examined first when searching for assets,
-     * before any that were previously added.
-     *
-     * Returns "true" on success, "false" on failure.  If 'cookie' is non-NULL,
-     * then on success, *cookie is set to the value corresponding to the
-     * newly-added asset source.
-     */
-    bool addAssetPath(const String8& path, void** cookie);
-
-    /*                                                                       
-     * Convenience for adding the standard system assets.  Uses the
-     * ANDROID_ROOT environment variable to find them.
-     */
-    bool addDefaultAssets();
-
-    /*                                                                       
-     * Iterate over the asset paths in this manager.  (Previously
-     * added via addAssetPath() and addDefaultAssets().)  On first call,
-     * 'cookie' must be NULL, resulting in the first cookie being returned.
-     * Each next cookie will be returned there-after, until NULL indicating
-     * the end has been reached.
-     */
-    void* nextAssetPath(void* cookie) const;
-
-    /*                                                                       
-     * Return an asset path in the manager.  'which' must be between 0 and
-     * countAssetPaths().
-     */
-    String8 getAssetPath(void* cookie) const;
-
-    /*
-     * Set the current locale and vendor.  The locale can change during
-     * the lifetime of an AssetManager if the user updates the device's
-     * language setting.  The vendor is less likely to change.
-     *
-     * Pass in NULL to indicate no preference.
-     */
-    void setLocale(const char* locale);
-    void setVendor(const char* vendor);
-
-    /*
-     * Choose screen orientation for resources values returned.
-     */
-    void setConfiguration(const ResTable_config& config, const char* locale = NULL);
-
-    void getConfiguration(ResTable_config* outConfig) const;
-
-    typedef Asset::AccessMode AccessMode;       // typing shortcut
-
-    /*
-     * Open an asset.
-     *
-     * This will search through locale-specific and vendor-specific
-     * directories and packages to find the file.
-     *
-     * The object returned does not depend on the AssetManager.  It should
-     * be freed by calling Asset::close().
-     */
-    Asset* open(const char* fileName, AccessMode mode);
-
-    /*
-     * Open a non-asset file as an asset.
-     *
-     * This is for opening files that are included in an asset package
-     * but aren't assets.  These sit outside the usual "locale/vendor"
-     * path hierarchy, and will not be seen by "AssetDir" or included
-     * in our filename cache.
-     */
-    Asset* openNonAsset(const char* fileName, AccessMode mode);
-
-    /*
-     * Explicit non-asset file.  The file explicitly named by the cookie (the
-     * resource set to look in) and fileName will be opened and returned.
-     */
-    Asset* openNonAsset(void* cookie, const char* fileName, AccessMode mode);
-
-    /*
-     * Open a directory within the asset hierarchy.
-     *
-     * The contents of the directory are an amalgam of vendor-specific,
-     * locale-specific, and generic assets stored loosely or in asset
-     * packages.  Depending on the cache setting and previous accesses,
-     * this call may incur significant disk overhead.
-     *
-     * To open the top-level directory, pass in "".
-     */
-    AssetDir* openDir(const char* dirName);
-
-    /*
-     * Open a directory within a particular path of the asset manager.
-     *
-     * The contents of the directory are an amalgam of vendor-specific,
-     * locale-specific, and generic assets stored loosely or in asset
-     * packages.  Depending on the cache setting and previous accesses,
-     * this call may incur significant disk overhead.
-     *
-     * To open the top-level directory, pass in "".
-     */
-    AssetDir* openNonAssetDir(void* cookie, const char* dirName);
-
-    /*
-     * Get the type of a file in the asset hierarchy.  They will either
-     * be "regular" or "directory".  [Currently only works for "regular".]
-     *
-     * Can also be used as a quick test for existence of a file.
-     */
-    FileType getFileType(const char* fileName);
-
-    /*                                                                       
-     * Return the complete resource table to find things in the package.
-     */
-    const ResTable& getResources(bool required = true) const;
-
-    /*
-     * Discard cached filename information.  This only needs to be called
-     * if somebody has updated the set of "loose" files, and we want to
-     * discard our cached notion of what's where.
-     */
-    void purge(void) { purgeFileNameCacheLocked(); }
-
-    /*
-     * Return true if the files this AssetManager references are all
-     * up-to-date (have not been changed since it was created).  If false
-     * is returned, you will need to create a new AssetManager to get
-     * the current data.
-     */
-    bool isUpToDate();
-    
-    /**
-     * Get the known locales for this asset manager object.
-     */
-    void getLocales(Vector<String8>* locales) const;
-
-private:
-    struct asset_path
-    {
-        String8 path;
-        FileType type;
-        String8 idmap;
-    };
-
-    Asset* openInPathLocked(const char* fileName, AccessMode mode,
-        const asset_path& path);
-    Asset* openNonAssetInPathLocked(const char* fileName, AccessMode mode,
-        const asset_path& path);
-    Asset* openInLocaleVendorLocked(const char* fileName, AccessMode mode,
-        const asset_path& path, const char* locale, const char* vendor);
-    String8 createPathNameLocked(const asset_path& path, const char* locale,
-        const char* vendor);
-    String8 createPathNameLocked(const asset_path& path, const char* rootDir);
-    String8 createZipSourceNameLocked(const String8& zipFileName,
-        const String8& dirName, const String8& fileName);
-
-    ZipFileRO* getZipFileLocked(const asset_path& path);
-    Asset* openAssetFromFileLocked(const String8& fileName, AccessMode mode);
-    Asset* openAssetFromZipLocked(const ZipFileRO* pZipFile,
-        const ZipEntryRO entry, AccessMode mode, const String8& entryName);
-
-    bool scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
-        const asset_path& path, const char* rootDir, const char* dirName);
-    SortedVector<AssetDir::FileInfo>* scanDirLocked(const String8& path);
-    bool scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
-        const asset_path& path, const char* rootDir, const char* dirName);
-    void mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
-        const SortedVector<AssetDir::FileInfo>* pContents);
-
-    void loadFileNameCacheLocked(void);
-    void fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
-        const char* dirName);
-    bool fncScanAndMergeDirLocked(
-        SortedVector<AssetDir::FileInfo>* pMergedInfo,
-        const asset_path& path, const char* locale, const char* vendor,
-        const char* dirName);
-    void purgeFileNameCacheLocked(void);
-
-    const ResTable* getResTable(bool required = true) const;
-    void setLocaleLocked(const char* locale);
-    void updateResourceParamsLocked() const;
-
-    bool createIdmapFileLocked(const String8& originalPath, const String8& overlayPath,
-                               const String8& idmapPath);
-
-    bool isIdmapStaleLocked(const String8& originalPath, const String8& overlayPath,
-                            const String8& idmapPath);
-
-    Asset* openIdmapLocked(const struct asset_path& ap) const;
-
-    bool getZipEntryCrcLocked(const String8& zipPath, const char* entryFilename, uint32_t* pCrc);
-
-    class SharedZip : public RefBase {
-    public:
-        static sp<SharedZip> get(const String8& path);
-
-        ZipFileRO* getZip();
-
-        Asset* getResourceTableAsset();
-        Asset* setResourceTableAsset(Asset* asset);
-
-        ResTable* getResourceTable();
-        ResTable* setResourceTable(ResTable* res);
-        
-        bool isUpToDate();
-        
-    protected:
-        ~SharedZip();
-
-    private:
-        SharedZip(const String8& path, time_t modWhen);
-        SharedZip(); // <-- not implemented
-
-        String8 mPath;
-        ZipFileRO* mZipFile;
-        time_t mModWhen;
-
-        Asset* mResourceTableAsset;
-        ResTable* mResourceTable;
-
-        static Mutex gLock;
-        static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
-    };
-
-    /*
-     * Manage a set of Zip files.  For each file we need a pointer to the
-     * ZipFile and a time_t with the file's modification date.
-     *
-     * We currently only have two zip files (current app, "common" app).
-     * (This was originally written for 8, based on app/locale/vendor.)
-     */
-    class ZipSet {
-    public:
-        ZipSet(void);
-        ~ZipSet(void);
-
-        /*
-         * Return a ZipFileRO structure for a ZipFileRO with the specified
-         * parameters.
-         */
-        ZipFileRO* getZip(const String8& path);
-
-        Asset* getZipResourceTableAsset(const String8& path);
-        Asset* setZipResourceTableAsset(const String8& path, Asset* asset);
-
-        ResTable* getZipResourceTable(const String8& path);
-        ResTable* setZipResourceTable(const String8& path, ResTable* res);
-
-        // generate path, e.g. "common/en-US-noogle.zip"
-        static String8 getPathName(const char* path);
-
-        bool isUpToDate();
-        
-    private:
-        void closeZip(int idx);
-
-        int getIndex(const String8& zip) const;
-        mutable Vector<String8> mZipPath;
-        mutable Vector<sp<SharedZip> > mZipFile;
-    };
-
-    // Protect all internal state.
-    mutable Mutex   mLock;
-
-    ZipSet          mZipSet;
-
-    Vector<asset_path> mAssetPaths;
-    char*           mLocale;
-    char*           mVendor;
-
-    mutable ResTable* mResources;
-    ResTable_config* mConfig;
-
-    /*
-     * Cached data for "loose" files.  This lets us avoid poking at the
-     * filesystem when searching for loose assets.  Each entry is the
-     * "extended partial" path, e.g. "default/default/foo/bar.txt".  The
-     * full set of files is present, including ".EXCLUDE" entries.
-     *
-     * We do not cache directory names.  We don't retain the ".gz",
-     * because to our clients "foo" and "foo.gz" both look like "foo".
-     */
-    CacheMode       mCacheMode;         // is the cache enabled?
-    bool            mCacheValid;        // clear when locale or vendor changes
-    SortedVector<AssetDir::FileInfo> mCache;
-};
-
-}; // namespace android
-
-#endif // __LIBS_ASSETMANAGER_H
diff --git a/include/androidfw/BackupHelpers.h b/include/androidfw/BackupHelpers.h
deleted file mode 100644
index 1bb04a7..0000000
--- a/include/androidfw/BackupHelpers.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UTILS_BACKUP_HELPERS_H
-#define _UTILS_BACKUP_HELPERS_H
-
-#include <utils/Errors.h>
-#include <utils/String8.h>
-#include <utils/KeyedVector.h>
-
-namespace android {
-
-enum {
-    BACKUP_HEADER_ENTITY_V1 = 0x61746144, // Data (little endian)
-};
-
-typedef struct {
-    int type; // BACKUP_HEADER_ENTITY_V1
-    int keyLen; // length of the key name, not including the null terminator
-    int dataSize; // size of the data, not including the padding, -1 means delete
-} entity_header_v1;
-
-struct SnapshotHeader {
-    int magic0;
-    int fileCount;
-    int magic1;
-    int totalSize;
-};
-
-struct FileState {
-    int modTime_sec;
-    int modTime_nsec;
-    int mode;
-    int size;
-    int crc32;
-    int nameLen;
-};
-
-struct FileRec {
-    String8 file;
-    bool deleted;
-    FileState s;
-};
-
-
-/**
- * Writes the data.
- *
- * If an error occurs, it poisons this object and all write calls will fail
- * with the error that occurred.
- */
-class BackupDataWriter
-{
-public:
-    BackupDataWriter(int fd);
-    // does not close fd
-    ~BackupDataWriter();
-
-    status_t WriteEntityHeader(const String8& key, size_t dataSize);
-
-    /* Note: WriteEntityData will write arbitrary data into the file without
-     * validation or a previously-supplied header.  The full backup implementation
-     * uses it this way to generate a controlled binary stream that is not
-     * entity-structured.  If the implementation here is changed, either this
-     * use case must remain valid, or the full backup implementation should be
-     * adjusted to use some other appropriate mechanism.
-     */
-    status_t WriteEntityData(const void* data, size_t size);
-
-    void SetKeyPrefix(const String8& keyPrefix);
-
-private:
-    explicit BackupDataWriter();
-    status_t write_padding_for(int n);
-    
-    int m_fd;
-    status_t m_status;
-    ssize_t m_pos;
-    int m_entityCount;
-    String8 m_keyPrefix;
-};
-
-/**
- * Reads the data.
- *
- * If an error occurs, it poisons this object and all write calls will fail
- * with the error that occurred.
- */
-class BackupDataReader
-{
-public:
-    BackupDataReader(int fd);
-    // does not close fd
-    ~BackupDataReader();
-
-    status_t Status();
-    status_t ReadNextHeader(bool* done, int* type);
-
-    bool HasEntities();
-    status_t ReadEntityHeader(String8* key, size_t* dataSize);
-    status_t SkipEntityData(); // must be called with the pointer at the beginning of the data.
-    ssize_t ReadEntityData(void* data, size_t size);
-
-private:
-    explicit BackupDataReader();
-    status_t skip_padding();
-    
-    int m_fd;
-    bool m_done;
-    status_t m_status;
-    ssize_t m_pos;
-    ssize_t m_dataEndPos;
-    int m_entityCount;
-    union {
-        int type;
-        entity_header_v1 entity;
-    } m_header;
-    String8 m_key;
-};
-
-int back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
-        char const* const* files, char const* const *keys, int fileCount);
-
-int write_tarfile(const String8& packageName, const String8& domain,
-        const String8& rootPath, const String8& filePath, BackupDataWriter* outputStream);
-
-class RestoreHelperBase
-{
-public:
-    RestoreHelperBase();
-    ~RestoreHelperBase();
-
-    status_t WriteFile(const String8& filename, BackupDataReader* in);
-    status_t WriteSnapshot(int fd);
-
-private:
-    void* m_buf;
-    bool m_loggedUnknownMetadata;
-    KeyedVector<String8,FileRec> m_files;
-};
-
-#define TEST_BACKUP_HELPERS 1
-
-#if TEST_BACKUP_HELPERS
-int backup_helper_test_empty();
-int backup_helper_test_four();
-int backup_helper_test_files();
-int backup_helper_test_null_base();
-int backup_helper_test_missing_file();
-int backup_helper_test_data_writer();
-int backup_helper_test_data_reader();
-#endif
-
-} // namespace android
-
-#endif // _UTILS_BACKUP_HELPERS_H
diff --git a/include/androidfw/CursorWindow.h b/include/androidfw/CursorWindow.h
deleted file mode 100644
index 8a2979a..0000000
--- a/include/androidfw/CursorWindow.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _ANDROID__DATABASE_WINDOW_H
-#define _ANDROID__DATABASE_WINDOW_H
-
-#include <cutils/log.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include <binder/Parcel.h>
-#include <utils/String8.h>
-
-#if LOG_NDEBUG
-
-#define IF_LOG_WINDOW() if (false)
-#define LOG_WINDOW(...)
-
-#else
-
-#define IF_LOG_WINDOW() IF_ALOG(LOG_DEBUG, "CursorWindow")
-#define LOG_WINDOW(...) ALOG(LOG_DEBUG, "CursorWindow", __VA_ARGS__)
-
-#endif
-
-namespace android {
-
-/**
- * This class stores a set of rows from a database in a buffer. The begining of the
- * window has first chunk of RowSlots, which are offsets to the row directory, followed by
- * an offset to the next chunk in a linked-list of additional chunk of RowSlots in case
- * the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a
- * FieldSlot per column, which has the size, offset, and type of the data for that field.
- * Note that the data types come from sqlite3.h.
- *
- * Strings are stored in UTF-8.
- */
-class CursorWindow {
-    CursorWindow(const String8& name, int ashmemFd,
-            void* data, size_t size, bool readOnly);
-
-public:
-    /* Field types. */
-    enum {
-        FIELD_TYPE_NULL = 0,
-        FIELD_TYPE_INTEGER = 1,
-        FIELD_TYPE_FLOAT = 2,
-        FIELD_TYPE_STRING = 3,
-        FIELD_TYPE_BLOB = 4,
-    };
-
-    /* Opaque type that describes a field slot. */
-    struct FieldSlot {
-    private:
-        int32_t type;
-        union {
-            double d;
-            int64_t l;
-            struct {
-                uint32_t offset;
-                uint32_t size;
-            } buffer;
-        } data;
-
-        friend class CursorWindow;
-    } __attribute((packed));
-
-    ~CursorWindow();
-
-    static status_t create(const String8& name, size_t size, CursorWindow** outCursorWindow);
-    static status_t createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow);
-
-    status_t writeToParcel(Parcel* parcel);
-
-    inline String8 name() { return mName; }
-    inline size_t size() { return mSize; }
-    inline size_t freeSpace() { return mSize - mHeader->freeOffset; }
-    inline uint32_t getNumRows() { return mHeader->numRows; }
-    inline uint32_t getNumColumns() { return mHeader->numColumns; }
-
-    status_t clear();
-    status_t setNumColumns(uint32_t numColumns);
-
-    /**
-     * Allocate a row slot and its directory.
-     * The row is initialized will null entries for each field.
-     */
-    status_t allocRow();
-    status_t freeLastRow();
-
-    status_t putBlob(uint32_t row, uint32_t column, const void* value, size_t size);
-    status_t putString(uint32_t row, uint32_t column, const char* value, size_t sizeIncludingNull);
-    status_t putLong(uint32_t row, uint32_t column, int64_t value);
-    status_t putDouble(uint32_t row, uint32_t column, double value);
-    status_t putNull(uint32_t row, uint32_t column);
-
-    /**
-     * Gets the field slot at the specified row and column.
-     * Returns null if the requested row or column is not in the window.
-     */
-    FieldSlot* getFieldSlot(uint32_t row, uint32_t column);
-
-    inline int32_t getFieldSlotType(FieldSlot* fieldSlot) {
-        return fieldSlot->type;
-    }
-
-    inline int64_t getFieldSlotValueLong(FieldSlot* fieldSlot) {
-        return fieldSlot->data.l;
-    }
-
-    inline double getFieldSlotValueDouble(FieldSlot* fieldSlot) {
-        return fieldSlot->data.d;
-    }
-
-    inline const char* getFieldSlotValueString(FieldSlot* fieldSlot,
-            size_t* outSizeIncludingNull) {
-        *outSizeIncludingNull = fieldSlot->data.buffer.size;
-        return static_cast<char*>(offsetToPtr(fieldSlot->data.buffer.offset));
-    }
-
-    inline const void* getFieldSlotValueBlob(FieldSlot* fieldSlot, size_t* outSize) {
-        *outSize = fieldSlot->data.buffer.size;
-        return offsetToPtr(fieldSlot->data.buffer.offset);
-    }
-
-private:
-    static const size_t ROW_SLOT_CHUNK_NUM_ROWS = 100;
-
-    struct Header {
-        // Offset of the lowest unused byte in the window.
-        uint32_t freeOffset;
-
-        // Offset of the first row slot chunk.
-        uint32_t firstChunkOffset;
-
-        uint32_t numRows;
-        uint32_t numColumns;
-    };
-
-    struct RowSlot {
-        uint32_t offset;
-    };
-
-    struct RowSlotChunk {
-        RowSlot slots[ROW_SLOT_CHUNK_NUM_ROWS];
-        uint32_t nextChunkOffset;
-    };
-
-    String8 mName;
-    int mAshmemFd;
-    void* mData;
-    size_t mSize;
-    bool mReadOnly;
-    Header* mHeader;
-
-    inline void* offsetToPtr(uint32_t offset) {
-        return static_cast<uint8_t*>(mData) + offset;
-    }
-
-    inline uint32_t offsetFromPtr(void* ptr) {
-        return static_cast<uint8_t*>(ptr) - static_cast<uint8_t*>(mData);
-    }
-
-    /**
-     * Allocate a portion of the window. Returns the offset
-     * of the allocation, or 0 if there isn't enough space.
-     * If aligned is true, the allocation gets 4 byte alignment.
-     */
-    uint32_t alloc(size_t size, bool aligned = false);
-
-    RowSlot* getRowSlot(uint32_t row);
-    RowSlot* allocRowSlot();
-
-    status_t putBlobOrString(uint32_t row, uint32_t column,
-            const void* value, size_t size, int32_t type);
-};
-
-}; // namespace android
-
-#endif
diff --git a/include/androidfw/ObbFile.h b/include/androidfw/ObbFile.h
deleted file mode 100644
index 47559cd..0000000
--- a/include/androidfw/ObbFile.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef OBBFILE_H_
-#define OBBFILE_H_
-
-#include <stdint.h>
-#include <strings.h>
-
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-namespace android {
-
-// OBB flags (bit 0)
-#define OBB_OVERLAY         (1 << 0)
-#define OBB_SALTED          (1 << 1)
-
-class ObbFile : public RefBase {
-protected:
-    virtual ~ObbFile();
-
-public:
-    ObbFile();
-
-    bool readFrom(const char* filename);
-    bool readFrom(int fd);
-    bool writeTo(const char* filename);
-    bool writeTo(int fd);
-    bool removeFrom(const char* filename);
-    bool removeFrom(int fd);
-
-    const char* getFileName() const {
-        return mFileName;
-    }
-
-    const String8 getPackageName() const {
-        return mPackageName;
-    }
-
-    void setPackageName(String8 packageName) {
-        mPackageName = packageName;
-    }
-
-    int32_t getVersion() const {
-        return mVersion;
-    }
-
-    void setVersion(int32_t version) {
-        mVersion = version;
-    }
-
-    int32_t getFlags() const {
-        return mFlags;
-    }
-
-    void setFlags(int32_t flags) {
-        mFlags = flags;
-    }
-
-    const unsigned char* getSalt(size_t* length) const {
-        if ((mFlags & OBB_SALTED) == 0) {
-            *length = 0;
-            return NULL;
-        }
-
-        *length = sizeof(mSalt);
-        return mSalt;
-    }
-
-    bool setSalt(const unsigned char* salt, size_t length) {
-        if (length != sizeof(mSalt)) {
-            return false;
-        }
-
-        memcpy(mSalt, salt, sizeof(mSalt));
-        mFlags |= OBB_SALTED;
-        return true;
-    }
-
-    bool isOverlay() {
-        return (mFlags & OBB_OVERLAY) == OBB_OVERLAY;
-    }
-
-    void setOverlay(bool overlay) {
-        if (overlay) {
-            mFlags |= OBB_OVERLAY;
-        } else {
-            mFlags &= ~OBB_OVERLAY;
-        }
-    }
-
-    static inline uint32_t get4LE(const unsigned char* buf) {
-        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
-    }
-
-    static inline void put4LE(unsigned char* buf, uint32_t val) {
-        buf[0] = val & 0xFF;
-        buf[1] = (val >> 8) & 0xFF;
-        buf[2] = (val >> 16) & 0xFF;
-        buf[3] = (val >> 24) & 0xFF;
-    }
-
-private:
-    /* Package name this ObbFile is associated with */
-    String8 mPackageName;
-
-    /* Package version this ObbFile is associated with */
-    int32_t mVersion;
-
-    /* Flags for this OBB type. */
-    int32_t mFlags;
-
-    /* Whether the file is salted. */
-    bool mSalted;
-
-    /* The encryption salt. */
-    unsigned char mSalt[8];
-
-    const char* mFileName;
-
-    size_t mFileSize;
-
-    size_t mFooterStart;
-
-    unsigned char* mReadBuf;
-
-    bool parseObbFile(int fd);
-};
-
-}
-#endif /* OBBFILE_H_ */
diff --git a/include/androidfw/PowerManager.h b/include/androidfw/PowerManager.h
deleted file mode 100644
index ba98db0..0000000
--- a/include/androidfw/PowerManager.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_POWER_MANAGER_H
-#define _ANDROIDFW_POWER_MANAGER_H
-
-
-namespace android {
-
-enum {
-    USER_ACTIVITY_EVENT_OTHER = 0,
-    USER_ACTIVITY_EVENT_BUTTON = 1,
-    USER_ACTIVITY_EVENT_TOUCH = 2,
-
-    USER_ACTIVITY_EVENT_LAST = USER_ACTIVITY_EVENT_TOUCH, // Last valid event code.
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_POWER_MANAGER_H
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
deleted file mode 100644
index 97afa59..0000000
--- a/include/androidfw/ResourceTypes.h
+++ /dev/null
@@ -1,1605 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-// Definitions of resource data structures.
-//
-#ifndef _LIBS_UTILS_RESOURCE_TYPES_H
-#define _LIBS_UTILS_RESOURCE_TYPES_H
-
-#include <androidfw/Asset.h>
-#include <utils/ByteOrder.h>
-#include <utils/Errors.h>
-#include <utils/String16.h>
-#include <utils/Vector.h>
-
-#include <utils/threads.h>
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <android/configuration.h>
-
-namespace android {
-
-/** ********************************************************************
- *  PNG Extensions
- *
- *  New private chunks that may be placed in PNG images.
- *
- *********************************************************************** */
-
-/**
- * This chunk specifies how to split an image into segments for
- * scaling.
- *
- * There are J horizontal and K vertical segments.  These segments divide
- * the image into J*K regions as follows (where J=4 and K=3):
- *
- *      F0   S0    F1     S1
- *   +-----+----+------+-------+
- * S2|  0  |  1 |  2   |   3   |
- *   +-----+----+------+-------+
- *   |     |    |      |       |
- *   |     |    |      |       |
- * F2|  4  |  5 |  6   |   7   |
- *   |     |    |      |       |
- *   |     |    |      |       |
- *   +-----+----+------+-------+
- * S3|  8  |  9 |  10  |   11  |
- *   +-----+----+------+-------+
- *
- * Each horizontal and vertical segment is considered to by either
- * stretchable (marked by the Sx labels) or fixed (marked by the Fy
- * labels), in the horizontal or vertical axis, respectively. In the
- * above example, the first is horizontal segment (F0) is fixed, the
- * next is stretchable and then they continue to alternate. Note that
- * the segment list for each axis can begin or end with a stretchable
- * or fixed segment.
- *
- * The relative sizes of the stretchy segments indicates the relative
- * amount of stretchiness of the regions bordered by the segments.  For
- * example, regions 3, 7 and 11 above will take up more horizontal space
- * than regions 1, 5 and 9 since the horizontal segment associated with
- * the first set of regions is larger than the other set of regions.  The
- * ratios of the amount of horizontal (or vertical) space taken by any
- * two stretchable slices is exactly the ratio of their corresponding
- * segment lengths.
- *
- * xDivs and yDivs point to arrays of horizontal and vertical pixel
- * indices.  The first pair of Divs (in either array) indicate the
- * starting and ending points of the first stretchable segment in that
- * axis. The next pair specifies the next stretchable segment, etc. So
- * in the above example xDiv[0] and xDiv[1] specify the horizontal
- * coordinates for the regions labeled 1, 5 and 9.  xDiv[2] and
- * xDiv[3] specify the coordinates for regions 3, 7 and 11. Note that
- * the leftmost slices always start at x=0 and the rightmost slices
- * always end at the end of the image. So, for example, the regions 0,
- * 4 and 8 (which are fixed along the X axis) start at x value 0 and
- * go to xDiv[0] and slices 2, 6 and 10 start at xDiv[1] and end at
- * xDiv[2].
- *
- * The array pointed to by the colors field lists contains hints for
- * each of the regions.  They are ordered according left-to-right and
- * top-to-bottom as indicated above. For each segment that is a solid
- * color the array entry will contain that color value; otherwise it
- * will contain NO_COLOR.  Segments that are completely transparent
- * will always have the value TRANSPARENT_COLOR.
- *
- * The PNG chunk type is "npTc".
- */
-struct Res_png_9patch
-{
-    Res_png_9patch() : wasDeserialized(false), xDivs(NULL),
-                       yDivs(NULL), colors(NULL) { }
-
-    int8_t wasDeserialized;
-    int8_t numXDivs;
-    int8_t numYDivs;
-    int8_t numColors;
-
-    // These tell where the next section of a patch starts.
-    // For example, the first patch includes the pixels from
-    // 0 to xDivs[0]-1 and the second patch includes the pixels
-    // from xDivs[0] to xDivs[1]-1.
-    // Note: allocation/free of these pointers is left to the caller.
-    int32_t* xDivs;
-    int32_t* yDivs;
-
-    int32_t paddingLeft, paddingRight;
-    int32_t paddingTop, paddingBottom;
-
-    enum {
-        // The 9 patch segment is not a solid color.
-        NO_COLOR = 0x00000001,
-
-        // The 9 patch segment is completely transparent.
-        TRANSPARENT_COLOR = 0x00000000
-    };
-    // Note: allocation/free of this pointer is left to the caller.
-    uint32_t* colors;
-
-    // Convert data from device representation to PNG file representation.
-    void deviceToFile();
-    // Convert data from PNG file representation to device representation.
-    void fileToDevice();
-    // Serialize/Marshall the patch data into a newly malloc-ed block
-    void* serialize();
-    // Serialize/Marshall the patch data
-    void serialize(void* outData);
-    // Deserialize/Unmarshall the patch data
-    static Res_png_9patch* deserialize(const void* data);
-    // Compute the size of the serialized data structure
-    size_t serializedSize();
-};
-
-/** ********************************************************************
- *  Base Types
- *
- *  These are standard types that are shared between multiple specific
- *  resource types.
- *
- *********************************************************************** */
-
-/**
- * Header that appears at the front of every data chunk in a resource.
- */
-struct ResChunk_header
-{
-    // Type identifier for this chunk.  The meaning of this value depends
-    // on the containing chunk.
-    uint16_t type;
-
-    // Size of the chunk header (in bytes).  Adding this value to
-    // the address of the chunk allows you to find its associated data
-    // (if any).
-    uint16_t headerSize;
-
-    // Total size of this chunk (in bytes).  This is the chunkSize plus
-    // the size of any data associated with the chunk.  Adding this value
-    // to the chunk allows you to completely skip its contents (including
-    // any child chunks).  If this value is the same as chunkSize, there is
-    // no data associated with the chunk.
-    uint32_t size;
-};
-
-enum {
-    RES_NULL_TYPE               = 0x0000,
-    RES_STRING_POOL_TYPE        = 0x0001,
-    RES_TABLE_TYPE              = 0x0002,
-    RES_XML_TYPE                = 0x0003,
-
-    // Chunk types in RES_XML_TYPE
-    RES_XML_FIRST_CHUNK_TYPE    = 0x0100,
-    RES_XML_START_NAMESPACE_TYPE= 0x0100,
-    RES_XML_END_NAMESPACE_TYPE  = 0x0101,
-    RES_XML_START_ELEMENT_TYPE  = 0x0102,
-    RES_XML_END_ELEMENT_TYPE    = 0x0103,
-    RES_XML_CDATA_TYPE          = 0x0104,
-    RES_XML_LAST_CHUNK_TYPE     = 0x017f,
-    // This contains a uint32_t array mapping strings in the string
-    // pool back to resource identifiers.  It is optional.
-    RES_XML_RESOURCE_MAP_TYPE   = 0x0180,
-
-    // Chunk types in RES_TABLE_TYPE
-    RES_TABLE_PACKAGE_TYPE      = 0x0200,
-    RES_TABLE_TYPE_TYPE         = 0x0201,
-    RES_TABLE_TYPE_SPEC_TYPE    = 0x0202
-};
-
-/**
- * Macros for building/splitting resource identifiers.
- */
-#define Res_VALIDID(resid) (resid != 0)
-#define Res_CHECKID(resid) ((resid&0xFFFF0000) != 0)
-#define Res_MAKEID(package, type, entry) \
-    (((package+1)<<24) | (((type+1)&0xFF)<<16) | (entry&0xFFFF))
-#define Res_GETPACKAGE(id) ((id>>24)-1)
-#define Res_GETTYPE(id) (((id>>16)&0xFF)-1)
-#define Res_GETENTRY(id) (id&0xFFFF)
-
-#define Res_INTERNALID(resid) ((resid&0xFFFF0000) != 0 && (resid&0xFF0000) == 0)
-#define Res_MAKEINTERNAL(entry) (0x01000000 | (entry&0xFFFF))
-#define Res_MAKEARRAY(entry) (0x02000000 | (entry&0xFFFF))
-
-#define Res_MAXPACKAGE 255
-
-/**
- * Representation of a value in a resource, supplying type
- * information.
- */
-struct Res_value
-{
-    // Number of bytes in this structure.
-    uint16_t size;
-
-    // Always set to 0.
-    uint8_t res0;
-        
-    // Type of the data value.
-    enum {
-        // Contains no data.
-        TYPE_NULL = 0x00,
-        // The 'data' holds a ResTable_ref, a reference to another resource
-        // table entry.
-        TYPE_REFERENCE = 0x01,
-        // The 'data' holds an attribute resource identifier.
-        TYPE_ATTRIBUTE = 0x02,
-        // The 'data' holds an index into the containing resource table's
-        // global value string pool.
-        TYPE_STRING = 0x03,
-        // The 'data' holds a single-precision floating point number.
-        TYPE_FLOAT = 0x04,
-        // The 'data' holds a complex number encoding a dimension value,
-        // such as "100in".
-        TYPE_DIMENSION = 0x05,
-        // The 'data' holds a complex number encoding a fraction of a
-        // container.
-        TYPE_FRACTION = 0x06,
-
-        // Beginning of integer flavors...
-        TYPE_FIRST_INT = 0x10,
-
-        // The 'data' is a raw integer value of the form n..n.
-        TYPE_INT_DEC = 0x10,
-        // The 'data' is a raw integer value of the form 0xn..n.
-        TYPE_INT_HEX = 0x11,
-        // The 'data' is either 0 or 1, for input "false" or "true" respectively.
-        TYPE_INT_BOOLEAN = 0x12,
-
-        // Beginning of color integer flavors...
-        TYPE_FIRST_COLOR_INT = 0x1c,
-
-        // The 'data' is a raw integer value of the form #aarrggbb.
-        TYPE_INT_COLOR_ARGB8 = 0x1c,
-        // The 'data' is a raw integer value of the form #rrggbb.
-        TYPE_INT_COLOR_RGB8 = 0x1d,
-        // The 'data' is a raw integer value of the form #argb.
-        TYPE_INT_COLOR_ARGB4 = 0x1e,
-        // The 'data' is a raw integer value of the form #rgb.
-        TYPE_INT_COLOR_RGB4 = 0x1f,
-
-        // ...end of integer flavors.
-        TYPE_LAST_COLOR_INT = 0x1f,
-
-        // ...end of integer flavors.
-        TYPE_LAST_INT = 0x1f
-    };
-    uint8_t dataType;
-
-    // Structure of complex data values (TYPE_UNIT and TYPE_FRACTION)
-    enum {
-        // Where the unit type information is.  This gives us 16 possible
-        // types, as defined below.
-        COMPLEX_UNIT_SHIFT = 0,
-        COMPLEX_UNIT_MASK = 0xf,
-
-        // TYPE_DIMENSION: Value is raw pixels.
-        COMPLEX_UNIT_PX = 0,
-        // TYPE_DIMENSION: Value is Device Independent Pixels.
-        COMPLEX_UNIT_DIP = 1,
-        // TYPE_DIMENSION: Value is a Scaled device independent Pixels.
-        COMPLEX_UNIT_SP = 2,
-        // TYPE_DIMENSION: Value is in points.
-        COMPLEX_UNIT_PT = 3,
-        // TYPE_DIMENSION: Value is in inches.
-        COMPLEX_UNIT_IN = 4,
-        // TYPE_DIMENSION: Value is in millimeters.
-        COMPLEX_UNIT_MM = 5,
-
-        // TYPE_FRACTION: A basic fraction of the overall size.
-        COMPLEX_UNIT_FRACTION = 0,
-        // TYPE_FRACTION: A fraction of the parent size.
-        COMPLEX_UNIT_FRACTION_PARENT = 1,
-
-        // Where the radix information is, telling where the decimal place
-        // appears in the mantissa.  This give us 4 possible fixed point
-        // representations as defined below.
-        COMPLEX_RADIX_SHIFT = 4,
-        COMPLEX_RADIX_MASK = 0x3,
-
-        // The mantissa is an integral number -- i.e., 0xnnnnnn.0
-        COMPLEX_RADIX_23p0 = 0,
-        // The mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn
-        COMPLEX_RADIX_16p7 = 1,
-        // The mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn
-        COMPLEX_RADIX_8p15 = 2,
-        // The mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn
-        COMPLEX_RADIX_0p23 = 3,
-
-        // Where the actual value is.  This gives us 23 bits of
-        // precision.  The top bit is the sign.
-        COMPLEX_MANTISSA_SHIFT = 8,
-        COMPLEX_MANTISSA_MASK = 0xffffff
-    };
-
-    // The data for this item, as interpreted according to dataType.
-    uint32_t data;
-
-    void copyFrom_dtoh(const Res_value& src);
-};
-
-/**
- *  This is a reference to a unique entry (a ResTable_entry structure)
- *  in a resource table.  The value is structured as: 0xpptteeee,
- *  where pp is the package index, tt is the type index in that
- *  package, and eeee is the entry index in that type.  The package
- *  and type values start at 1 for the first item, to help catch cases
- *  where they have not been supplied.
- */
-struct ResTable_ref
-{
-    uint32_t ident;
-};
-
-/**
- * Reference to a string in a string pool.
- */
-struct ResStringPool_ref
-{
-    // Index into the string pool table (uint32_t-offset from the indices
-    // immediately after ResStringPool_header) at which to find the location
-    // of the string data in the pool.
-    uint32_t index;
-};
-
-/** ********************************************************************
- *  String Pool
- *
- *  A set of strings that can be references by others through a
- *  ResStringPool_ref.
- *
- *********************************************************************** */
-
-/**
- * Definition for a pool of strings.  The data of this chunk is an
- * array of uint32_t providing indices into the pool, relative to
- * stringsStart.  At stringsStart are all of the UTF-16 strings
- * concatenated together; each starts with a uint16_t of the string's
- * length and each ends with a 0x0000 terminator.  If a string is >
- * 32767 characters, the high bit of the length is set meaning to take
- * those 15 bits as a high word and it will be followed by another
- * uint16_t containing the low word.
- *
- * If styleCount is not zero, then immediately following the array of
- * uint32_t indices into the string table is another array of indices
- * into a style table starting at stylesStart.  Each entry in the
- * style table is an array of ResStringPool_span structures.
- */
-struct ResStringPool_header
-{
-    struct ResChunk_header header;
-
-    // Number of strings in this pool (number of uint32_t indices that follow
-    // in the data).
-    uint32_t stringCount;
-
-    // Number of style span arrays in the pool (number of uint32_t indices
-    // follow the string indices).
-    uint32_t styleCount;
-
-    // Flags.
-    enum {
-        // If set, the string index is sorted by the string values (based
-        // on strcmp16()).
-        SORTED_FLAG = 1<<0,
-
-        // String pool is encoded in UTF-8
-        UTF8_FLAG = 1<<8
-    };
-    uint32_t flags;
-
-    // Index from header of the string data.
-    uint32_t stringsStart;
-
-    // Index from header of the style data.
-    uint32_t stylesStart;
-};
-
-/**
- * This structure defines a span of style information associated with
- * a string in the pool.
- */
-struct ResStringPool_span
-{
-    enum {
-        END = 0xFFFFFFFF
-    };
-
-    // This is the name of the span -- that is, the name of the XML
-    // tag that defined it.  The special value END (0xFFFFFFFF) indicates
-    // the end of an array of spans.
-    ResStringPool_ref name;
-
-    // The range of characters in the string that this span applies to.
-    uint32_t firstChar, lastChar;
-};
-
-/**
- * Convenience class for accessing data in a ResStringPool resource.
- */
-class ResStringPool
-{
-public:
-    ResStringPool();
-    ResStringPool(const void* data, size_t size, bool copyData=false);
-    ~ResStringPool();
-
-    status_t setTo(const void* data, size_t size, bool copyData=false);
-
-    status_t getError() const;
-
-    void uninit();
-
-    // Return string entry as UTF16; if the pool is UTF8, the string will
-    // be converted before returning.
-    inline const char16_t* stringAt(const ResStringPool_ref& ref, size_t* outLen) const {
-        return stringAt(ref.index, outLen);
-    }
-    const char16_t* stringAt(size_t idx, size_t* outLen) const;
-
-    // Note: returns null if the string pool is not UTF8.
-    const char* string8At(size_t idx, size_t* outLen) const;
-
-    // Return string whether the pool is UTF8 or UTF16.  Does not allow you
-    // to distinguish null.
-    const String8 string8ObjectAt(size_t idx) const;
-
-    const ResStringPool_span* styleAt(const ResStringPool_ref& ref) const;
-    const ResStringPool_span* styleAt(size_t idx) const;
-
-    ssize_t indexOfString(const char16_t* str, size_t strLen) const;
-
-    size_t size() const;
-    size_t styleCount() const;
-    size_t bytes() const;
-
-    bool isSorted() const;
-    bool isUTF8() const;
-
-private:
-    status_t                    mError;
-    void*                       mOwnedData;
-    const ResStringPool_header* mHeader;
-    size_t                      mSize;
-    mutable Mutex               mDecodeLock;
-    const uint32_t*             mEntries;
-    const uint32_t*             mEntryStyles;
-    const void*                 mStrings;
-    char16_t mutable**          mCache;
-    uint32_t                    mStringPoolSize;    // number of uint16_t
-    const uint32_t*             mStyles;
-    uint32_t                    mStylePoolSize;    // number of uint32_t
-};
-
-/** ********************************************************************
- *  XML Tree
- *
- *  Binary representation of an XML document.  This is designed to
- *  express everything in an XML document, in a form that is much
- *  easier to parse on the device.
- *
- *********************************************************************** */
-
-/**
- * XML tree header.  This appears at the front of an XML tree,
- * describing its content.  It is followed by a flat array of
- * ResXMLTree_node structures; the hierarchy of the XML document
- * is described by the occurrance of RES_XML_START_ELEMENT_TYPE
- * and corresponding RES_XML_END_ELEMENT_TYPE nodes in the array.
- */
-struct ResXMLTree_header
-{
-    struct ResChunk_header header;
-};
-
-/**
- * Basic XML tree node.  A single item in the XML document.  Extended info
- * about the node can be found after header.headerSize.
- */
-struct ResXMLTree_node
-{
-    struct ResChunk_header header;
-
-    // Line number in original source file at which this element appeared.
-    uint32_t lineNumber;
-
-    // Optional XML comment that was associated with this element; -1 if none.
-    struct ResStringPool_ref comment;
-};
-
-/**
- * Extended XML tree node for CDATA tags -- includes the CDATA string.
- * Appears header.headerSize bytes after a ResXMLTree_node.
- */
-struct ResXMLTree_cdataExt
-{
-    // The raw CDATA character data.
-    struct ResStringPool_ref data;
-    
-    // The typed value of the character data if this is a CDATA node.
-    struct Res_value typedData;
-};
-
-/**
- * Extended XML tree node for namespace start/end nodes.
- * Appears header.headerSize bytes after a ResXMLTree_node.
- */
-struct ResXMLTree_namespaceExt
-{
-    // The prefix of the namespace.
-    struct ResStringPool_ref prefix;
-    
-    // The URI of the namespace.
-    struct ResStringPool_ref uri;
-};
-
-/**
- * Extended XML tree node for element start/end nodes.
- * Appears header.headerSize bytes after a ResXMLTree_node.
- */
-struct ResXMLTree_endElementExt
-{
-    // String of the full namespace of this element.
-    struct ResStringPool_ref ns;
-    
-    // String name of this node if it is an ELEMENT; the raw
-    // character data if this is a CDATA node.
-    struct ResStringPool_ref name;
-};
-
-/**
- * Extended XML tree node for start tags -- includes attribute
- * information.
- * Appears header.headerSize bytes after a ResXMLTree_node.
- */
-struct ResXMLTree_attrExt
-{
-    // String of the full namespace of this element.
-    struct ResStringPool_ref ns;
-    
-    // String name of this node if it is an ELEMENT; the raw
-    // character data if this is a CDATA node.
-    struct ResStringPool_ref name;
-    
-    // Byte offset from the start of this structure where the attributes start.
-    uint16_t attributeStart;
-    
-    // Size of the ResXMLTree_attribute structures that follow.
-    uint16_t attributeSize;
-    
-    // Number of attributes associated with an ELEMENT.  These are
-    // available as an array of ResXMLTree_attribute structures
-    // immediately following this node.
-    uint16_t attributeCount;
-    
-    // Index (1-based) of the "id" attribute. 0 if none.
-    uint16_t idIndex;
-    
-    // Index (1-based) of the "class" attribute. 0 if none.
-    uint16_t classIndex;
-    
-    // Index (1-based) of the "style" attribute. 0 if none.
-    uint16_t styleIndex;
-};
-
-struct ResXMLTree_attribute
-{
-    // Namespace of this attribute.
-    struct ResStringPool_ref ns;
-    
-    // Name of this attribute.
-    struct ResStringPool_ref name;
-
-    // The original raw string value of this attribute.
-    struct ResStringPool_ref rawValue;
-    
-    // Processesd typed value of this attribute.
-    struct Res_value typedValue;
-};
-
-class ResXMLTree;
-
-class ResXMLParser
-{
-public:
-    ResXMLParser(const ResXMLTree& tree);
-
-    enum event_code_t {
-        BAD_DOCUMENT = -1,
-        START_DOCUMENT = 0,
-        END_DOCUMENT = 1,
-        
-        FIRST_CHUNK_CODE = RES_XML_FIRST_CHUNK_TYPE, 
-        
-        START_NAMESPACE = RES_XML_START_NAMESPACE_TYPE,
-        END_NAMESPACE = RES_XML_END_NAMESPACE_TYPE,
-        START_TAG = RES_XML_START_ELEMENT_TYPE,
-        END_TAG = RES_XML_END_ELEMENT_TYPE,
-        TEXT = RES_XML_CDATA_TYPE
-    };
-
-    struct ResXMLPosition
-    {
-        event_code_t                eventCode;
-        const ResXMLTree_node*      curNode;
-        const void*                 curExt;
-    };
-
-    void restart();
-
-    const ResStringPool& getStrings() const;
-
-    event_code_t getEventType() const;
-    // Note, unlike XmlPullParser, the first call to next() will return
-    // START_TAG of the first element.
-    event_code_t next();
-
-    // These are available for all nodes:
-    int32_t getCommentID() const;
-    const uint16_t* getComment(size_t* outLen) const;
-    uint32_t getLineNumber() const;
-    
-    // This is available for TEXT:
-    int32_t getTextID() const;
-    const uint16_t* getText(size_t* outLen) const;
-    ssize_t getTextValue(Res_value* outValue) const;
-    
-    // These are available for START_NAMESPACE and END_NAMESPACE:
-    int32_t getNamespacePrefixID() const;
-    const uint16_t* getNamespacePrefix(size_t* outLen) const;
-    int32_t getNamespaceUriID() const;
-    const uint16_t* getNamespaceUri(size_t* outLen) const;
-    
-    // These are available for START_TAG and END_TAG:
-    int32_t getElementNamespaceID() const;
-    const uint16_t* getElementNamespace(size_t* outLen) const;
-    int32_t getElementNameID() const;
-    const uint16_t* getElementName(size_t* outLen) const;
-    
-    // Remaining methods are for retrieving information about attributes
-    // associated with a START_TAG:
-    
-    size_t getAttributeCount() const;
-    
-    // Returns -1 if no namespace, -2 if idx out of range.
-    int32_t getAttributeNamespaceID(size_t idx) const;
-    const uint16_t* getAttributeNamespace(size_t idx, size_t* outLen) const;
-
-    int32_t getAttributeNameID(size_t idx) const;
-    const uint16_t* getAttributeName(size_t idx, size_t* outLen) const;
-    uint32_t getAttributeNameResID(size_t idx) const;
-
-    // These will work only if the underlying string pool is UTF-8.
-    const char* getAttributeNamespace8(size_t idx, size_t* outLen) const;
-    const char* getAttributeName8(size_t idx, size_t* outLen) const;
-
-    int32_t getAttributeValueStringID(size_t idx) const;
-    const uint16_t* getAttributeStringValue(size_t idx, size_t* outLen) const;
-    
-    int32_t getAttributeDataType(size_t idx) const;
-    int32_t getAttributeData(size_t idx) const;
-    ssize_t getAttributeValue(size_t idx, Res_value* outValue) const;
-
-    ssize_t indexOfAttribute(const char* ns, const char* attr) const;
-    ssize_t indexOfAttribute(const char16_t* ns, size_t nsLen,
-                             const char16_t* attr, size_t attrLen) const;
-
-    ssize_t indexOfID() const;
-    ssize_t indexOfClass() const;
-    ssize_t indexOfStyle() const;
-
-    void getPosition(ResXMLPosition* pos) const;
-    void setPosition(const ResXMLPosition& pos);
-
-private:
-    friend class ResXMLTree;
-    
-    event_code_t nextNode();
-
-    const ResXMLTree&           mTree;
-    event_code_t                mEventCode;
-    const ResXMLTree_node*      mCurNode;
-    const void*                 mCurExt;
-};
-
-/**
- * Convenience class for accessing data in a ResXMLTree resource.
- */
-class ResXMLTree : public ResXMLParser
-{
-public:
-    ResXMLTree();
-    ResXMLTree(const void* data, size_t size, bool copyData=false);
-    ~ResXMLTree();
-
-    status_t setTo(const void* data, size_t size, bool copyData=false);
-
-    status_t getError() const;
-
-    void uninit();
-
-private:
-    friend class ResXMLParser;
-
-    status_t validateNode(const ResXMLTree_node* node) const;
-
-    status_t                    mError;
-    void*                       mOwnedData;
-    const ResXMLTree_header*    mHeader;
-    size_t                      mSize;
-    const uint8_t*              mDataEnd;
-    ResStringPool               mStrings;
-    const uint32_t*             mResIds;
-    size_t                      mNumResIds;
-    const ResXMLTree_node*      mRootNode;
-    const void*                 mRootExt;
-    event_code_t                mRootCode;
-};
-
-/** ********************************************************************
- *  RESOURCE TABLE
- *
- *********************************************************************** */
-
-/**
- * Header for a resource table.  Its data contains a series of
- * additional chunks:
- *   * A ResStringPool_header containing all table values.  This string pool
- *     contains all of the string values in the entire resource table (not
- *     the names of entries or type identifiers however).
- *   * One or more ResTable_package chunks.
- *
- * Specific entries within a resource table can be uniquely identified
- * with a single integer as defined by the ResTable_ref structure.
- */
-struct ResTable_header
-{
-    struct ResChunk_header header;
-
-    // The number of ResTable_package structures.
-    uint32_t packageCount;
-};
-
-/**
- * A collection of resource data types within a package.  Followed by
- * one or more ResTable_type and ResTable_typeSpec structures containing the
- * entry values for each resource type.
- */
-struct ResTable_package
-{
-    struct ResChunk_header header;
-
-    // If this is a base package, its ID.  Package IDs start
-    // at 1 (corresponding to the value of the package bits in a
-    // resource identifier).  0 means this is not a base package.
-    uint32_t id;
-
-    // Actual name of this package, \0-terminated.
-    char16_t name[128];
-
-    // Offset to a ResStringPool_header defining the resource
-    // type symbol table.  If zero, this package is inheriting from
-    // another base package (overriding specific values in it).
-    uint32_t typeStrings;
-
-    // Last index into typeStrings that is for public use by others.
-    uint32_t lastPublicType;
-
-    // Offset to a ResStringPool_header defining the resource
-    // key symbol table.  If zero, this package is inheriting from
-    // another base package (overriding specific values in it).
-    uint32_t keyStrings;
-
-    // Last index into keyStrings that is for public use by others.
-    uint32_t lastPublicKey;
-};
-
-/**
- * Describes a particular resource configuration.
- */
-struct ResTable_config
-{
-    // Number of bytes in this structure.
-    uint32_t size;
-    
-    union {
-        struct {
-            // Mobile country code (from SIM).  0 means "any".
-            uint16_t mcc;
-            // Mobile network code (from SIM).  0 means "any".
-            uint16_t mnc;
-        };
-        uint32_t imsi;
-    };
-    
-    union {
-        struct {
-            // \0\0 means "any".  Otherwise, en, fr, etc.
-            char language[2];
-            
-            // \0\0 means "any".  Otherwise, US, CA, etc.
-            char country[2];
-        };
-        uint32_t locale;
-    };
-    
-    enum {
-        ORIENTATION_ANY  = ACONFIGURATION_ORIENTATION_ANY,
-        ORIENTATION_PORT = ACONFIGURATION_ORIENTATION_PORT,
-        ORIENTATION_LAND = ACONFIGURATION_ORIENTATION_LAND,
-        ORIENTATION_SQUARE = ACONFIGURATION_ORIENTATION_SQUARE,
-    };
-    
-    enum {
-        TOUCHSCREEN_ANY  = ACONFIGURATION_TOUCHSCREEN_ANY,
-        TOUCHSCREEN_NOTOUCH  = ACONFIGURATION_TOUCHSCREEN_NOTOUCH,
-        TOUCHSCREEN_STYLUS  = ACONFIGURATION_TOUCHSCREEN_STYLUS,
-        TOUCHSCREEN_FINGER  = ACONFIGURATION_TOUCHSCREEN_FINGER,
-    };
-    
-    enum {
-        DENSITY_DEFAULT = ACONFIGURATION_DENSITY_DEFAULT,
-        DENSITY_LOW = ACONFIGURATION_DENSITY_LOW,
-        DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM,
-        DENSITY_TV = ACONFIGURATION_DENSITY_TV,
-        DENSITY_HIGH = ACONFIGURATION_DENSITY_HIGH,
-        DENSITY_XHIGH = ACONFIGURATION_DENSITY_XHIGH,
-        DENSITY_XXHIGH = ACONFIGURATION_DENSITY_XXHIGH,
-        DENSITY_XXXHIGH = ACONFIGURATION_DENSITY_XXXHIGH,
-        DENSITY_NONE = ACONFIGURATION_DENSITY_NONE
-    };
-    
-    union {
-        struct {
-            uint8_t orientation;
-            uint8_t touchscreen;
-            uint16_t density;
-        };
-        uint32_t screenType;
-    };
-    
-    enum {
-        KEYBOARD_ANY  = ACONFIGURATION_KEYBOARD_ANY,
-        KEYBOARD_NOKEYS  = ACONFIGURATION_KEYBOARD_NOKEYS,
-        KEYBOARD_QWERTY  = ACONFIGURATION_KEYBOARD_QWERTY,
-        KEYBOARD_12KEY  = ACONFIGURATION_KEYBOARD_12KEY,
-    };
-    
-    enum {
-        NAVIGATION_ANY  = ACONFIGURATION_NAVIGATION_ANY,
-        NAVIGATION_NONAV  = ACONFIGURATION_NAVIGATION_NONAV,
-        NAVIGATION_DPAD  = ACONFIGURATION_NAVIGATION_DPAD,
-        NAVIGATION_TRACKBALL  = ACONFIGURATION_NAVIGATION_TRACKBALL,
-        NAVIGATION_WHEEL  = ACONFIGURATION_NAVIGATION_WHEEL,
-    };
-    
-    enum {
-        MASK_KEYSHIDDEN = 0x0003,
-        KEYSHIDDEN_ANY = ACONFIGURATION_KEYSHIDDEN_ANY,
-        KEYSHIDDEN_NO = ACONFIGURATION_KEYSHIDDEN_NO,
-        KEYSHIDDEN_YES = ACONFIGURATION_KEYSHIDDEN_YES,
-        KEYSHIDDEN_SOFT = ACONFIGURATION_KEYSHIDDEN_SOFT,
-    };
-    
-    enum {
-        MASK_NAVHIDDEN = 0x000c,
-        SHIFT_NAVHIDDEN = 2,
-        NAVHIDDEN_ANY = ACONFIGURATION_NAVHIDDEN_ANY << SHIFT_NAVHIDDEN,
-        NAVHIDDEN_NO = ACONFIGURATION_NAVHIDDEN_NO << SHIFT_NAVHIDDEN,
-        NAVHIDDEN_YES = ACONFIGURATION_NAVHIDDEN_YES << SHIFT_NAVHIDDEN,
-    };
-    
-    union {
-        struct {
-            uint8_t keyboard;
-            uint8_t navigation;
-            uint8_t inputFlags;
-            uint8_t inputPad0;
-        };
-        uint32_t input;
-    };
-    
-    enum {
-        SCREENWIDTH_ANY = 0
-    };
-    
-    enum {
-        SCREENHEIGHT_ANY = 0
-    };
-    
-    union {
-        struct {
-            uint16_t screenWidth;
-            uint16_t screenHeight;
-        };
-        uint32_t screenSize;
-    };
-    
-    enum {
-        SDKVERSION_ANY = 0
-    };
-    
-    enum {
-        MINORVERSION_ANY = 0
-    };
-    
-    union {
-        struct {
-            uint16_t sdkVersion;
-            // For now minorVersion must always be 0!!!  Its meaning
-            // is currently undefined.
-            uint16_t minorVersion;
-        };
-        uint32_t version;
-    };
-    
-    enum {
-        // screenLayout bits for screen size class.
-        MASK_SCREENSIZE = 0x0f,
-        SCREENSIZE_ANY = ACONFIGURATION_SCREENSIZE_ANY,
-        SCREENSIZE_SMALL = ACONFIGURATION_SCREENSIZE_SMALL,
-        SCREENSIZE_NORMAL = ACONFIGURATION_SCREENSIZE_NORMAL,
-        SCREENSIZE_LARGE = ACONFIGURATION_SCREENSIZE_LARGE,
-        SCREENSIZE_XLARGE = ACONFIGURATION_SCREENSIZE_XLARGE,
-        
-        // screenLayout bits for wide/long screen variation.
-        MASK_SCREENLONG = 0x30,
-        SHIFT_SCREENLONG = 4,
-        SCREENLONG_ANY = ACONFIGURATION_SCREENLONG_ANY << SHIFT_SCREENLONG,
-        SCREENLONG_NO = ACONFIGURATION_SCREENLONG_NO << SHIFT_SCREENLONG,
-        SCREENLONG_YES = ACONFIGURATION_SCREENLONG_YES << SHIFT_SCREENLONG,
-
-        // screenLayout bits for layout direction.
-        MASK_LAYOUTDIR = 0xC0,
-        SHIFT_LAYOUTDIR = 6,
-        LAYOUTDIR_ANY = ACONFIGURATION_LAYOUTDIR_ANY << SHIFT_LAYOUTDIR,
-        LAYOUTDIR_LTR = ACONFIGURATION_LAYOUTDIR_LTR << SHIFT_LAYOUTDIR,
-        LAYOUTDIR_RTL = ACONFIGURATION_LAYOUTDIR_RTL << SHIFT_LAYOUTDIR,
-    };
-    
-    enum {
-        // uiMode bits for the mode type.
-        MASK_UI_MODE_TYPE = 0x0f,
-        UI_MODE_TYPE_ANY = ACONFIGURATION_UI_MODE_TYPE_ANY,
-        UI_MODE_TYPE_NORMAL = ACONFIGURATION_UI_MODE_TYPE_NORMAL,
-        UI_MODE_TYPE_DESK = ACONFIGURATION_UI_MODE_TYPE_DESK,
-        UI_MODE_TYPE_CAR = ACONFIGURATION_UI_MODE_TYPE_CAR,
-        UI_MODE_TYPE_TELEVISION = ACONFIGURATION_UI_MODE_TYPE_TELEVISION,
-        UI_MODE_TYPE_APPLIANCE = ACONFIGURATION_UI_MODE_TYPE_APPLIANCE,
-
-        // uiMode bits for the night switch.
-        MASK_UI_MODE_NIGHT = 0x30,
-        SHIFT_UI_MODE_NIGHT = 4,
-        UI_MODE_NIGHT_ANY = ACONFIGURATION_UI_MODE_NIGHT_ANY << SHIFT_UI_MODE_NIGHT,
-        UI_MODE_NIGHT_NO = ACONFIGURATION_UI_MODE_NIGHT_NO << SHIFT_UI_MODE_NIGHT,
-        UI_MODE_NIGHT_YES = ACONFIGURATION_UI_MODE_NIGHT_YES << SHIFT_UI_MODE_NIGHT,
-    };
-
-    union {
-        struct {
-            uint8_t screenLayout;
-            uint8_t uiMode;
-            uint16_t smallestScreenWidthDp;
-        };
-        uint32_t screenConfig;
-    };
-    
-    union {
-        struct {
-            uint16_t screenWidthDp;
-            uint16_t screenHeightDp;
-        };
-        uint32_t screenSizeDp;
-    };
-
-    void copyFromDeviceNoSwap(const ResTable_config& o);
-    
-    void copyFromDtoH(const ResTable_config& o);
-    
-    void swapHtoD();
-
-    int compare(const ResTable_config& o) const;
-    int compareLogical(const ResTable_config& o) const;
-
-    // Flags indicating a set of config values.  These flag constants must
-    // match the corresponding ones in android.content.pm.ActivityInfo and
-    // attrs_manifest.xml.
-    enum {
-        CONFIG_MCC = ACONFIGURATION_MCC,
-        CONFIG_MNC = ACONFIGURATION_MCC,
-        CONFIG_LOCALE = ACONFIGURATION_LOCALE,
-        CONFIG_TOUCHSCREEN = ACONFIGURATION_TOUCHSCREEN,
-        CONFIG_KEYBOARD = ACONFIGURATION_KEYBOARD,
-        CONFIG_KEYBOARD_HIDDEN = ACONFIGURATION_KEYBOARD_HIDDEN,
-        CONFIG_NAVIGATION = ACONFIGURATION_NAVIGATION,
-        CONFIG_ORIENTATION = ACONFIGURATION_ORIENTATION,
-        CONFIG_DENSITY = ACONFIGURATION_DENSITY,
-        CONFIG_SCREEN_SIZE = ACONFIGURATION_SCREEN_SIZE,
-        CONFIG_SMALLEST_SCREEN_SIZE = ACONFIGURATION_SMALLEST_SCREEN_SIZE,
-        CONFIG_VERSION = ACONFIGURATION_VERSION,
-        CONFIG_SCREEN_LAYOUT = ACONFIGURATION_SCREEN_LAYOUT,
-        CONFIG_UI_MODE = ACONFIGURATION_UI_MODE,
-        CONFIG_LAYOUTDIR = ACONFIGURATION_LAYOUTDIR,
-    };
-    
-    // Compare two configuration, returning CONFIG_* flags set for each value
-    // that is different.
-    int diff(const ResTable_config& o) const;
-    
-    // Return true if 'this' is more specific than 'o'.
-    bool isMoreSpecificThan(const ResTable_config& o) const;
-
-    // Return true if 'this' is a better match than 'o' for the 'requested'
-    // configuration.  This assumes that match() has already been used to
-    // remove any configurations that don't match the requested configuration
-    // at all; if they are not first filtered, non-matching results can be
-    // considered better than matching ones.
-    // The general rule per attribute: if the request cares about an attribute
-    // (it normally does), if the two (this and o) are equal it's a tie.  If
-    // they are not equal then one must be generic because only generic and
-    // '==requested' will pass the match() call.  So if this is not generic,
-    // it wins.  If this IS generic, o wins (return false).
-    bool isBetterThan(const ResTable_config& o, const ResTable_config* requested) const;
-
-    // Return true if 'this' can be considered a match for the parameters in 
-    // 'settings'.
-    // Note this is asymetric.  A default piece of data will match every request
-    // but a request for the default should not match odd specifics
-    // (ie, request with no mcc should not match a particular mcc's data)
-    // settings is the requested settings
-    bool match(const ResTable_config& settings) const;
-
-    void getLocale(char str[6]) const;
-
-    String8 toString() const;
-};
-
-/**
- * A specification of the resources defined by a particular type.
- *
- * There should be one of these chunks for each resource type.
- *
- * This structure is followed by an array of integers providing the set of
- * configuration change flags (ResTable_config::CONFIG_*) that have multiple
- * resources for that configuration.  In addition, the high bit is set if that
- * resource has been made public.
- */
-struct ResTable_typeSpec
-{
-    struct ResChunk_header header;
-
-    // The type identifier this chunk is holding.  Type IDs start
-    // at 1 (corresponding to the value of the type bits in a
-    // resource identifier).  0 is invalid.
-    uint8_t id;
-    
-    // Must be 0.
-    uint8_t res0;
-    // Must be 0.
-    uint16_t res1;
-    
-    // Number of uint32_t entry configuration masks that follow.
-    uint32_t entryCount;
-
-    enum {
-        // Additional flag indicating an entry is public.
-        SPEC_PUBLIC = 0x40000000
-    };
-};
-
-/**
- * A collection of resource entries for a particular resource data
- * type. Followed by an array of uint32_t defining the resource
- * values, corresponding to the array of type strings in the
- * ResTable_package::typeStrings string block. Each of these hold an
- * index from entriesStart; a value of NO_ENTRY means that entry is
- * not defined.
- *
- * There may be multiple of these chunks for a particular resource type,
- * supply different configuration variations for the resource values of
- * that type.
- *
- * It would be nice to have an additional ordered index of entries, so
- * we can do a binary search if trying to find a resource by string name.
- */
-struct ResTable_type
-{
-    struct ResChunk_header header;
-
-    enum {
-        NO_ENTRY = 0xFFFFFFFF
-    };
-    
-    // The type identifier this chunk is holding.  Type IDs start
-    // at 1 (corresponding to the value of the type bits in a
-    // resource identifier).  0 is invalid.
-    uint8_t id;
-    
-    // Must be 0.
-    uint8_t res0;
-    // Must be 0.
-    uint16_t res1;
-    
-    // Number of uint32_t entry indices that follow.
-    uint32_t entryCount;
-
-    // Offset from header where ResTable_entry data starts.
-    uint32_t entriesStart;
-    
-    // Configuration this collection of entries is designed for.
-    ResTable_config config;
-};
-
-/**
- * This is the beginning of information about an entry in the resource
- * table.  It holds the reference to the name of this entry, and is
- * immediately followed by one of:
- *   * A Res_value structure, if FLAG_COMPLEX is -not- set.
- *   * An array of ResTable_map structures, if FLAG_COMPLEX is set.
- *     These supply a set of name/value mappings of data.
- */
-struct ResTable_entry
-{
-    // Number of bytes in this structure.
-    uint16_t size;
-
-    enum {
-        // If set, this is a complex entry, holding a set of name/value
-        // mappings.  It is followed by an array of ResTable_map structures.
-        FLAG_COMPLEX = 0x0001,
-        // If set, this resource has been declared public, so libraries
-        // are allowed to reference it.
-        FLAG_PUBLIC = 0x0002
-    };
-    uint16_t flags;
-    
-    // Reference into ResTable_package::keyStrings identifying this entry.
-    struct ResStringPool_ref key;
-};
-
-/**
- * Extended form of a ResTable_entry for map entries, defining a parent map
- * resource from which to inherit values.
- */
-struct ResTable_map_entry : public ResTable_entry
-{
-    // Resource identifier of the parent mapping, or 0 if there is none.
-    ResTable_ref parent;
-    // Number of name/value pairs that follow for FLAG_COMPLEX.
-    uint32_t count;
-};
-
-/**
- * A single name/value mapping that is part of a complex resource
- * entry.
- */
-struct ResTable_map
-{
-    // The resource identifier defining this mapping's name.  For attribute
-    // resources, 'name' can be one of the following special resource types
-    // to supply meta-data about the attribute; for all other resource types
-    // it must be an attribute resource.
-    ResTable_ref name;
-
-    // Special values for 'name' when defining attribute resources.
-    enum {
-        // This entry holds the attribute's type code.
-        ATTR_TYPE = Res_MAKEINTERNAL(0),
-
-        // For integral attributes, this is the minimum value it can hold.
-        ATTR_MIN = Res_MAKEINTERNAL(1),
-
-        // For integral attributes, this is the maximum value it can hold.
-        ATTR_MAX = Res_MAKEINTERNAL(2),
-
-        // Localization of this resource is can be encouraged or required with
-        // an aapt flag if this is set
-        ATTR_L10N = Res_MAKEINTERNAL(3),
-
-        // for plural support, see android.content.res.PluralRules#attrForQuantity(int)
-        ATTR_OTHER = Res_MAKEINTERNAL(4),
-        ATTR_ZERO = Res_MAKEINTERNAL(5),
-        ATTR_ONE = Res_MAKEINTERNAL(6),
-        ATTR_TWO = Res_MAKEINTERNAL(7),
-        ATTR_FEW = Res_MAKEINTERNAL(8),
-        ATTR_MANY = Res_MAKEINTERNAL(9)
-        
-    };
-
-    // Bit mask of allowed types, for use with ATTR_TYPE.
-    enum {
-        // No type has been defined for this attribute, use generic
-        // type handling.  The low 16 bits are for types that can be
-        // handled generically; the upper 16 require additional information
-        // in the bag so can not be handled generically for TYPE_ANY.
-        TYPE_ANY = 0x0000FFFF,
-
-        // Attribute holds a references to another resource.
-        TYPE_REFERENCE = 1<<0,
-
-        // Attribute holds a generic string.
-        TYPE_STRING = 1<<1,
-
-        // Attribute holds an integer value.  ATTR_MIN and ATTR_MIN can
-        // optionally specify a constrained range of possible integer values.
-        TYPE_INTEGER = 1<<2,
-
-        // Attribute holds a boolean integer.
-        TYPE_BOOLEAN = 1<<3,
-
-        // Attribute holds a color value.
-        TYPE_COLOR = 1<<4,
-
-        // Attribute holds a floating point value.
-        TYPE_FLOAT = 1<<5,
-
-        // Attribute holds a dimension value, such as "20px".
-        TYPE_DIMENSION = 1<<6,
-
-        // Attribute holds a fraction value, such as "20%".
-        TYPE_FRACTION = 1<<7,
-
-        // Attribute holds an enumeration.  The enumeration values are
-        // supplied as additional entries in the map.
-        TYPE_ENUM = 1<<16,
-
-        // Attribute holds a bitmaks of flags.  The flag bit values are
-        // supplied as additional entries in the map.
-        TYPE_FLAGS = 1<<17
-    };
-
-    // Enum of localization modes, for use with ATTR_L10N.
-    enum {
-        L10N_NOT_REQUIRED = 0,
-        L10N_SUGGESTED    = 1
-    };
-    
-    // This mapping's value.
-    Res_value value;
-};
-
-/**
- * Convenience class for accessing data in a ResTable resource.
- */
-class ResTable
-{
-public:
-    ResTable();
-    ResTable(const void* data, size_t size, void* cookie,
-             bool copyData=false);
-    ~ResTable();
-
-    status_t add(const void* data, size_t size, void* cookie,
-                 bool copyData=false, const void* idmap = NULL);
-    status_t add(Asset* asset, void* cookie,
-                 bool copyData=false, const void* idmap = NULL);
-    status_t add(ResTable* src);
-
-    status_t getError() const;
-
-    void uninit();
-
-    struct resource_name
-    {
-        const char16_t* package;
-        size_t packageLen;
-        const char16_t* type;
-        const char* type8;
-        size_t typeLen;
-        const char16_t* name;
-        const char* name8;
-        size_t nameLen;
-    };
-
-    bool getResourceName(uint32_t resID, bool allowUtf8, resource_name* outName) const;
-
-    /**
-     * Retrieve the value of a resource.  If the resource is found, returns a
-     * value >= 0 indicating the table it is in (for use with
-     * getTableStringBlock() and getTableCookie()) and fills in 'outValue'.  If
-     * not found, returns a negative error code.
-     *
-     * Note that this function does not do reference traversal.  If you want
-     * to follow references to other resources to get the "real" value to
-     * use, you need to call resolveReference() after this function.
-     *
-     * @param resID The desired resoruce identifier.
-     * @param outValue Filled in with the resource data that was found.
-     *
-     * @return ssize_t Either a >= 0 table index or a negative error code.
-     */
-    ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag = false,
-                    uint16_t density = 0,
-                    uint32_t* outSpecFlags = NULL,
-                    ResTable_config* outConfig = NULL) const;
-
-    inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue,
-            uint32_t* outSpecFlags=NULL) const {
-        return getResource(res.ident, outValue, false, 0, outSpecFlags, NULL);
-    }
-
-    ssize_t resolveReference(Res_value* inOutValue,
-                             ssize_t blockIndex,
-                             uint32_t* outLastRef = NULL,
-                             uint32_t* inoutTypeSpecFlags = NULL,
-                             ResTable_config* outConfig = NULL) const;
-
-    enum {
-        TMP_BUFFER_SIZE = 16
-    };
-    const char16_t* valueToString(const Res_value* value, size_t stringBlock,
-                                  char16_t tmpBuffer[TMP_BUFFER_SIZE],
-                                  size_t* outLen);
-
-    struct bag_entry {
-        ssize_t stringBlock;
-        ResTable_map map;
-    };
-
-    /**
-     * Retrieve the bag of a resource.  If the resoruce is found, returns the
-     * number of bags it contains and 'outBag' points to an array of their
-     * values.  If not found, a negative error code is returned.
-     *
-     * Note that this function -does- do reference traversal of the bag data.
-     *
-     * @param resID The desired resource identifier.
-     * @param outBag Filled inm with a pointer to the bag mappings.
-     *
-     * @return ssize_t Either a >= 0 bag count of negative error code.
-     */
-    ssize_t lockBag(uint32_t resID, const bag_entry** outBag) const;
-
-    void unlockBag(const bag_entry* bag) const;
-
-    void lock() const;
-
-    ssize_t getBagLocked(uint32_t resID, const bag_entry** outBag,
-            uint32_t* outTypeSpecFlags=NULL) const;
-
-    void unlock() const;
-
-    class Theme {
-    public:
-        Theme(const ResTable& table);
-        ~Theme();
-
-        inline const ResTable& getResTable() const { return mTable; }
-
-        status_t applyStyle(uint32_t resID, bool force=false);
-        status_t setTo(const Theme& other);
-
-        /**
-         * Retrieve a value in the theme.  If the theme defines this
-         * value, returns a value >= 0 indicating the table it is in
-         * (for use with getTableStringBlock() and getTableCookie) and
-         * fills in 'outValue'.  If not found, returns a negative error
-         * code.
-         *
-         * Note that this function does not do reference traversal.  If you want
-         * to follow references to other resources to get the "real" value to
-         * use, you need to call resolveReference() after this function.
-         *
-         * @param resID A resource identifier naming the desired theme
-         *              attribute.
-         * @param outValue Filled in with the theme value that was
-         *                 found.
-         *
-         * @return ssize_t Either a >= 0 table index or a negative error code.
-         */
-        ssize_t getAttribute(uint32_t resID, Res_value* outValue,
-                uint32_t* outTypeSpecFlags = NULL) const;
-
-        /**
-         * This is like ResTable::resolveReference(), but also takes
-         * care of resolving attribute references to the theme.
-         */
-        ssize_t resolveAttributeReference(Res_value* inOutValue,
-                ssize_t blockIndex, uint32_t* outLastRef = NULL,
-                uint32_t* inoutTypeSpecFlags = NULL,
-                ResTable_config* inoutConfig = NULL) const;
-
-        void dumpToLog() const;
-        
-    private:
-        Theme(const Theme&);
-        Theme& operator=(const Theme&);
-
-        struct theme_entry {
-            ssize_t stringBlock;
-            uint32_t typeSpecFlags;
-            Res_value value;
-        };
-        struct type_info {
-            size_t numEntries;
-            theme_entry* entries;
-        };
-        struct package_info {
-            size_t numTypes;
-            type_info types[];
-        };
-
-        void free_package(package_info* pi);
-        package_info* copy_package(package_info* pi);
-
-        const ResTable& mTable;
-        package_info*   mPackages[Res_MAXPACKAGE];
-    };
-
-    void setParameters(const ResTable_config* params);
-    void getParameters(ResTable_config* params) const;
-
-    // Retrieve an identifier (which can be passed to getResource)
-    // for a given resource name.  The 'name' can be fully qualified
-    // (<package>:<type>.<basename>) or the package or type components
-    // can be dropped if default values are supplied here.
-    //
-    // Returns 0 if no such resource was found, else a valid resource ID.
-    uint32_t identifierForName(const char16_t* name, size_t nameLen,
-                               const char16_t* type = 0, size_t typeLen = 0,
-                               const char16_t* defPackage = 0,
-                               size_t defPackageLen = 0,
-                               uint32_t* outTypeSpecFlags = NULL) const;
-
-    static bool expandResourceRef(const uint16_t* refStr, size_t refLen,
-                                  String16* outPackage,
-                                  String16* outType,
-                                  String16* outName,
-                                  const String16* defType = NULL,
-                                  const String16* defPackage = NULL,
-                                  const char** outErrorMsg = NULL,
-                                  bool* outPublicOnly = NULL);
-
-    static bool stringToInt(const char16_t* s, size_t len, Res_value* outValue);
-    static bool stringToFloat(const char16_t* s, size_t len, Res_value* outValue);
-
-    // Used with stringToValue.
-    class Accessor
-    {
-    public:
-        inline virtual ~Accessor() { }
-
-        virtual uint32_t getCustomResource(const String16& package,
-                                           const String16& type,
-                                           const String16& name) const = 0;
-        virtual uint32_t getCustomResourceWithCreation(const String16& package,
-                                                       const String16& type,
-                                                       const String16& name,
-                                                       const bool createIfNeeded = false) = 0;
-        virtual uint32_t getRemappedPackage(uint32_t origPackage) const = 0;
-        virtual bool getAttributeType(uint32_t attrID, uint32_t* outType) = 0;
-        virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin) = 0;
-        virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax) = 0;
-        virtual bool getAttributeEnum(uint32_t attrID,
-                                      const char16_t* name, size_t nameLen,
-                                      Res_value* outValue) = 0;
-        virtual bool getAttributeFlags(uint32_t attrID,
-                                       const char16_t* name, size_t nameLen,
-                                       Res_value* outValue) = 0;
-        virtual uint32_t getAttributeL10N(uint32_t attrID) = 0;
-        virtual bool getLocalizationSetting() = 0;
-        virtual void reportError(void* accessorCookie, const char* fmt, ...) = 0;
-    };
-
-    // Convert a string to a resource value.  Handles standard "@res",
-    // "#color", "123", and "0x1bd" types; performs escaping of strings.
-    // The resulting value is placed in 'outValue'; if it is a string type,
-    // 'outString' receives the string.  If 'attrID' is supplied, the value is
-    // type checked against this attribute and it is used to perform enum
-    // evaluation.  If 'acccessor' is supplied, it will be used to attempt to
-    // resolve resources that do not exist in this ResTable.  If 'attrType' is
-    // supplied, the value will be type checked for this format if 'attrID'
-    // is not supplied or found.
-    bool stringToValue(Res_value* outValue, String16* outString,
-                       const char16_t* s, size_t len,
-                       bool preserveSpaces, bool coerceType,
-                       uint32_t attrID = 0,
-                       const String16* defType = NULL,
-                       const String16* defPackage = NULL,
-                       Accessor* accessor = NULL,
-                       void* accessorCookie = NULL,
-                       uint32_t attrType = ResTable_map::TYPE_ANY,
-                       bool enforcePrivate = true) const;
-
-    // Perform processing of escapes and quotes in a string.
-    static bool collectString(String16* outString,
-                              const char16_t* s, size_t len,
-                              bool preserveSpaces,
-                              const char** outErrorMsg = NULL,
-                              bool append = false);
-
-    size_t getBasePackageCount() const;
-    const char16_t* getBasePackageName(size_t idx) const;
-    uint32_t getBasePackageId(size_t idx) const;
-
-    // Return the number of resource tables that the object contains.
-    size_t getTableCount() const;
-    // Return the values string pool for the resource table at the given
-    // index.  This string pool contains all of the strings for values
-    // contained in the resource table -- that is the item values themselves,
-    // but not the names their entries or types.
-    const ResStringPool* getTableStringBlock(size_t index) const;
-    // Return unique cookie identifier for the given resource table.
-    void* getTableCookie(size_t index) const;
-
-    // Return the configurations (ResTable_config) that we know about
-    void getConfigurations(Vector<ResTable_config>* configs) const;
-
-    void getLocales(Vector<String8>* locales) const;
-
-    // Generate an idmap.
-    //
-    // Return value: on success: NO_ERROR; caller is responsible for free-ing
-    // outData (using free(3)). On failure, any status_t value other than
-    // NO_ERROR; the caller should not free outData.
-    status_t createIdmap(const ResTable& overlay, uint32_t originalCrc, uint32_t overlayCrc,
-                         void** outData, size_t* outSize) const;
-
-    enum {
-        IDMAP_HEADER_SIZE_BYTES = 3 * sizeof(uint32_t),
-    };
-    // Retrieve idmap meta-data.
-    //
-    // This function only requires the idmap header (the first
-    // IDMAP_HEADER_SIZE_BYTES) bytes of an idmap file.
-    static bool getIdmapInfo(const void* idmap, size_t size,
-                             uint32_t* pOriginalCrc, uint32_t* pOverlayCrc);
-
-    void print(bool inclValues) const;
-    static String8 normalizeForOutput(const char* input);
-
-private:
-    struct Header;
-    struct Type;
-    struct Package;
-    struct PackageGroup;
-    struct bag_set;
-
-    status_t add(const void* data, size_t size, void* cookie,
-                 Asset* asset, bool copyData, const Asset* idmap);
-
-    ssize_t getResourcePackageIndex(uint32_t resID) const;
-    ssize_t getEntry(
-        const Package* package, int typeIndex, int entryIndex,
-        const ResTable_config* config,
-        const ResTable_type** outType, const ResTable_entry** outEntry,
-        const Type** outTypeClass) const;
-    status_t parsePackage(
-        const ResTable_package* const pkg, const Header* const header, uint32_t idmap_id);
-
-    void print_value(const Package* pkg, const Res_value& value) const;
-    
-    mutable Mutex               mLock;
-
-    status_t                    mError;
-
-    ResTable_config             mParams;
-
-    // Array of all resource tables.
-    Vector<Header*>             mHeaders;
-
-    // Array of packages in all resource tables.
-    Vector<PackageGroup*>       mPackageGroups;
-
-    // Mapping from resource package IDs to indices into the internal
-    // package array.
-    uint8_t                     mPackageMap[256];
-};
-
-}   // namespace android
-
-#endif // _LIBS_UTILS_RESOURCE_TYPES_H
diff --git a/include/androidfw/StreamingZipInflater.h b/include/androidfw/StreamingZipInflater.h
deleted file mode 100644
index 3ace5d5..0000000
--- a/include/androidfw/StreamingZipInflater.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __LIBS_STREAMINGZIPINFLATER_H
-#define __LIBS_STREAMINGZIPINFLATER_H
-
-#include <unistd.h>
-#include <inttypes.h>
-#include <zlib.h>
-
-#include <utils/Compat.h>
-
-namespace android {
-
-class StreamingZipInflater {
-public:
-    static const size_t INPUT_CHUNK_SIZE = 64 * 1024;
-    static const size_t OUTPUT_CHUNK_SIZE = 64 * 1024;
-
-    // Flavor that pages in the compressed data from a fd
-    StreamingZipInflater(int fd, off64_t compDataStart, size_t uncompSize, size_t compSize);
-
-    // Flavor that gets the compressed data from an in-memory buffer
-    StreamingZipInflater(class FileMap* dataMap, size_t uncompSize);
-
-    ~StreamingZipInflater();
-
-    // read 'count' bytes of uncompressed data from the current position.  outBuf may
-    // be NULL, in which case the data is consumed and discarded.
-    ssize_t read(void* outBuf, size_t count);
-
-    // seeking backwards requires uncompressing fom the beginning, so is very
-    // expensive.  seeking forwards only requires uncompressing from the current
-    // position to the destination.
-    off64_t seekAbsolute(off64_t absoluteInputPosition);
-
-private:
-    void initInflateState();
-    int readNextChunk();
-
-    // where to find the uncompressed data
-    int mFd;
-    off64_t mInFileStart;         // where the compressed data lives in the file
-    class FileMap* mDataMap;
-
-    z_stream mInflateState;
-    bool mStreamNeedsInit;
-
-    // output invariants for this asset
-    uint8_t* mOutBuf;           // output buf for decompressed bytes
-    size_t mOutBufSize;         // allocated size of mOutBuf
-    size_t mOutTotalSize;       // total uncompressed size of the blob
-
-    // current output state bookkeeping
-    off64_t mOutCurPosition;      // current position in total offset
-    size_t mOutLastDecoded;     // last decoded byte + 1 in mOutbuf
-    size_t mOutDeliverable;     // next undelivered byte of decoded output in mOutBuf
-
-    // input invariants
-    uint8_t* mInBuf;
-    size_t mInBufSize;          // allocated size of mInBuf;
-    size_t mInTotalSize;        // total size of compressed data for this blob
-
-    // input state bookkeeping
-    size_t mInNextChunkOffset;  // offset from start of blob at which the next input chunk lies
-    // the z_stream contains state about input block consumption
-};
-
-}
-
-#endif
diff --git a/include/androidfw/ZipFileRO.h b/include/androidfw/ZipFileRO.h
deleted file mode 100644
index 547e36a..0000000
--- a/include/androidfw/ZipFileRO.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * Read-only access to Zip archives, with minimal heap allocation.
- *
- * This is similar to the more-complete ZipFile class, but no attempt
- * has been made to make them interchangeable.  This class operates under
- * a very different set of assumptions and constraints.
- *
- * One such assumption is that if you're getting file descriptors for
- * use with this class as a child of a fork() operation, you must be on
- * a pread() to guarantee correct operation. This is because pread() can
- * atomically read at a file offset without worrying about a lock around an
- * lseek() + read() pair.
- */
-#ifndef __LIBS_ZIPFILERO_H
-#define __LIBS_ZIPFILERO_H
-
-#include <utils/Compat.h>
-#include <utils/Errors.h>
-#include <utils/FileMap.h>
-#include <utils/threads.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-namespace android {
-
-/*
- * Trivial typedef to ensure that ZipEntryRO is not treated as a simple
- * integer.  We use NULL to indicate an invalid value.
- */
-typedef void* ZipEntryRO;
-
-/*
- * Open a Zip archive for reading.
- *
- * We want "open" and "find entry by name" to be fast operations, and we
- * want to use as little memory as possible.  We memory-map the file,
- * and load a hash table with pointers to the filenames (which aren't
- * null-terminated).  The other fields are at a fixed offset from the
- * filename, so we don't need to extract those (but we do need to byte-read
- * and endian-swap them every time we want them).
- *
- * To speed comparisons when doing a lookup by name, we could make the mapping
- * "private" (copy-on-write) and null-terminate the filenames after verifying
- * the record structure.  However, this requires a private mapping of
- * every page that the Central Directory touches.  Easier to tuck a copy
- * of the string length into the hash table entry.
- *
- * NOTE: If this is used on file descriptors inherited from a fork() operation,
- * you must be on a platform that implements pread() to guarantee correctness
- * on the shared file descriptors.
- */
-class ZipFileRO {
-public:
-    ZipFileRO()
-        : mFd(-1), mFileName(NULL), mFileLength(-1),
-          mDirectoryMap(NULL),
-          mNumEntries(-1), mDirectoryOffset(-1),
-          mHashTableSize(-1), mHashTable(NULL)
-        {}
-
-    ~ZipFileRO();
-
-    /*
-     * Open an archive.
-     */
-    status_t open(const char* zipFileName);
-
-    /*
-     * Find an entry, by name.  Returns the entry identifier, or NULL if
-     * not found.
-     *
-     * If two entries have the same name, one will be chosen at semi-random.
-     */
-    ZipEntryRO findEntryByName(const char* fileName) const;
-
-    /*
-     * Return the #of entries in the Zip archive.
-     */
-    int getNumEntries(void) const {
-        return mNumEntries;
-    }
-
-    /*
-     * Return the Nth entry.  Zip file entries are not stored in sorted
-     * order, and updated entries may appear at the end, so anyone walking
-     * the archive needs to avoid making ordering assumptions.  We take
-     * that further by returning the Nth non-empty entry in the hash table
-     * rather than the Nth entry in the archive.
-     *
-     * Valid values are [0..numEntries).
-     *
-     * [This is currently O(n).  If it needs to be fast we can allocate an
-     * additional data structure or provide an iterator interface.]
-     */
-    ZipEntryRO findEntryByIndex(int idx) const;
-
-    /*
-     * Copy the filename into the supplied buffer.  Returns 0 on success,
-     * -1 if "entry" is invalid, or the filename length if it didn't fit.  The
-     * length, and the returned string, include the null-termination.
-     */
-    int getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen) const;
-
-    /*
-     * Get the vital stats for an entry.  Pass in NULL pointers for anything
-     * you don't need.
-     *
-     * "*pOffset" holds the Zip file offset of the entry's data.
-     *
-     * Returns "false" if "entry" is bogus or if the data in the Zip file
-     * appears to be bad.
-     */
-    bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
-        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const;
-
-    /*
-     * Create a new FileMap object that maps a subset of the archive.  For
-     * an uncompressed entry this effectively provides a pointer to the
-     * actual data, for a compressed entry this provides the input buffer
-     * for inflate().
-     */
-    FileMap* createEntryFileMap(ZipEntryRO entry) const;
-
-    /*
-     * Uncompress the data into a buffer.  Depending on the compression
-     * format, this is either an "inflate" operation or a memcpy.
-     *
-     * Use "uncompLen" from getEntryInfo() to determine the required
-     * buffer size.
-     *
-     * Returns "true" on success.
-     */
-    bool uncompressEntry(ZipEntryRO entry, void* buffer) const;
-
-    /*
-     * Uncompress the data to an open file descriptor.
-     */
-    bool uncompressEntry(ZipEntryRO entry, int fd) const;
-
-    /* Zip compression methods we support */
-    enum {
-        kCompressStored     = 0,        // no compression
-        kCompressDeflated   = 8,        // standard deflate
-    };
-
-    /*
-     * Utility function: uncompress deflated data, buffer to buffer.
-     */
-    static bool inflateBuffer(void* outBuf, const void* inBuf,
-        size_t uncompLen, size_t compLen);
-
-    /*
-     * Utility function: uncompress deflated data, buffer to fd.
-     */
-    static bool inflateBuffer(int fd, const void* inBuf,
-        size_t uncompLen, size_t compLen);
-
-    /*
-     * Utility function to convert ZIP's time format to a timespec struct.
-     */
-    static inline void zipTimeToTimespec(long when, struct tm* timespec) {
-        const long date = when >> 16;
-        timespec->tm_year = ((date >> 9) & 0x7F) + 80; // Zip is years since 1980
-        timespec->tm_mon = (date >> 5) & 0x0F;
-        timespec->tm_mday = date & 0x1F;
-
-        timespec->tm_hour = (when >> 11) & 0x1F;
-        timespec->tm_min = (when >> 5) & 0x3F;
-        timespec->tm_sec = (when & 0x1F) << 1;
-    }
-
-    /*
-     * Some basic functions for raw data manipulation.  "LE" means
-     * Little Endian.
-     */
-    static inline unsigned short get2LE(const unsigned char* buf) {
-        return buf[0] | (buf[1] << 8);
-    }
-    static inline unsigned long get4LE(const unsigned char* buf) {
-        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
-    }
-
-private:
-    /* these are private and not defined */ 
-    ZipFileRO(const ZipFileRO& src);
-    ZipFileRO& operator=(const ZipFileRO& src);
-
-    /* locate and parse the central directory */
-    bool mapCentralDirectory(void);
-
-    /* parse the archive, prepping internal structures */
-    bool parseZipArchive(void);
-
-    /* add a new entry to the hash table */
-    void addToHash(const char* str, int strLen, unsigned int hash);
-
-    /* compute string hash code */
-    static unsigned int computeHash(const char* str, int len);
-
-    /* convert a ZipEntryRO back to a hash table index */
-    int entryToIndex(const ZipEntryRO entry) const;
-
-    /*
-     * One entry in the hash table.
-     */
-    typedef struct HashEntry {
-        const char*     name;
-        unsigned short  nameLen;
-        //unsigned int    hash;
-    } HashEntry;
-
-    /* open Zip archive */
-    int         mFd;
-
-    /* Lock for handling the file descriptor (seeks, etc) */
-    mutable Mutex mFdLock;
-
-    /* zip file name */
-    char*       mFileName;
-
-    /* length of file */
-    size_t      mFileLength;
-
-    /* mapped file */
-    FileMap*    mDirectoryMap;
-
-    /* number of entries in the Zip archive */
-    int         mNumEntries;
-
-    /* CD directory offset in the Zip archive */
-    off64_t     mDirectoryOffset;
-
-    /*
-     * We know how many entries are in the Zip archive, so we have a
-     * fixed-size hash table.  We probe for an empty slot.
-     */
-    int         mHashTableSize;
-    HashEntry*  mHashTable;
-};
-
-}; // namespace android
-
-#endif /*__LIBS_ZIPFILERO_H*/
diff --git a/include/androidfw/ZipUtils.h b/include/androidfw/ZipUtils.h
deleted file mode 100644
index 42c42b6..0000000
--- a/include/androidfw/ZipUtils.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Miscellaneous zip/gzip utility functions.
-//
-#ifndef __LIBS_ZIPUTILS_H
-#define __LIBS_ZIPUTILS_H
-
-#include <stdio.h>
-
-namespace android {
-
-/*
- * Container class for utility functions, primarily for namespace reasons.
- */
-class ZipUtils {
-public:
-    /*
-     * General utility function for uncompressing "deflate" data from a file
-     * to a buffer.
-     */
-    static bool inflateToBuffer(int fd, void* buf, long uncompressedLen,
-        long compressedLen);
-    static bool inflateToBuffer(FILE* fp, void* buf, long uncompressedLen,
-        long compressedLen);
-
-    /*
-     * Someday we might want to make this generic and handle bzip2 ".bz2"
-     * files too.
-     *
-     * We could declare gzip to be a sub-class of zip that has exactly
-     * one always-compressed entry, but we currently want to treat Zip
-     * and gzip as distinct, so there's no value.
-     *
-     * The zlib library has some gzip utilities, but it has no interface
-     * for extracting the uncompressed length of the file (you do *not*
-     * want to gzseek to the end).
-     *
-     * Pass in a seeked file pointer for the gzip file.  If this is a gzip
-     * file, we set our return values appropriately and return "true" with
-     * the file seeked to the start of the compressed data.
-     */
-    static bool examineGzip(FILE* fp, int* pCompressionMethod,
-        long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32);
-
-private:
-    ZipUtils() {}
-    ~ZipUtils() {}
-};
-
-}; // namespace android
-
-#endif /*__LIBS_ZIPUTILS_H*/
diff --git a/include/androidfw/misc.h b/include/androidfw/misc.h
deleted file mode 100644
index 5a5a0e2..0000000
--- a/include/androidfw/misc.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 <sys/types.h>
-
-//
-// Handy utility functions and portability code.
-//
-#ifndef _LIBS_ANDROID_FW_MISC_H
-#define _LIBS_ANDROID_FW_MISC_H
-
-namespace android {
-
-/*
- * Some utility functions for working with files.  These could be made
- * part of a "File" class.
- */
-typedef enum FileType {
-    kFileTypeUnknown = 0,
-    kFileTypeNonexistent,       // i.e. ENOENT
-    kFileTypeRegular,
-    kFileTypeDirectory,
-    kFileTypeCharDev,
-    kFileTypeBlockDev,
-    kFileTypeFifo,
-    kFileTypeSymlink,
-    kFileTypeSocket,
-} FileType;
-/* get the file's type; follows symlinks */
-FileType getFileType(const char* fileName);
-/* get the file's modification date; returns -1 w/errno set on failure */
-time_t getFileModDate(const char* fileName);
-
-}; // namespace android
-
-#endif // _LIBS_ANDROID_FW_MISC_H
diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/AndroidKeyPairGenerator.java
index 1ab0aeb..458a46c 100644
--- a/keystore/java/android/security/AndroidKeyPairGenerator.java
+++ b/keystore/java/android/security/AndroidKeyPairGenerator.java
@@ -35,7 +35,6 @@
 import java.security.cert.X509Certificate;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.DSAParameterSpec;
-import java.security.spec.ECParameterSpec;
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.RSAKeyGenParameterSpec;
 import java.security.spec.X509EncodedKeySpec;
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index 767647c..af76d9d 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -27,7 +27,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.io.ObjectOutputStream;
 import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.Writer;
diff --git a/keystore/java/android/security/KeyChainAliasCallback.java b/keystore/java/android/security/KeyChainAliasCallback.java
index fc9e64b..2500863 100644
--- a/keystore/java/android/security/KeyChainAliasCallback.java
+++ b/keystore/java/android/security/KeyChainAliasCallback.java
@@ -15,10 +15,6 @@
  */
 package android.security;
 
-import android.content.Intent;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
 /**
  * The KeyChainAliasCallback is the callback for {@link
  * KeyChain#choosePrivateKeyAlias}.
diff --git a/keystore/java/android/security/KeyStoreParameter.java b/keystore/java/android/security/KeyStoreParameter.java
index 621a605..b71efc4 100644
--- a/keystore/java/android/security/KeyStoreParameter.java
+++ b/keystore/java/android/security/KeyStoreParameter.java
@@ -17,12 +17,9 @@
 package android.security;
 
 import android.content.Context;
-import android.security.KeyPairGeneratorSpec.Builder;
 
 import java.security.KeyPairGenerator;
-import java.security.PrivateKey;
 import java.security.KeyStore.ProtectionParameter;
-import java.security.cert.Certificate;
 
 /**
  * This provides the optional parameters that can be specified for
diff --git a/keystore/java/android/security/SystemKeyStore.java b/keystore/java/android/security/SystemKeyStore.java
index bca8f68..e07eaa2 100644
--- a/keystore/java/android/security/SystemKeyStore.java
+++ b/keystore/java/android/security/SystemKeyStore.java
@@ -18,10 +18,8 @@
 
 import android.os.Environment;
 import android.os.FileUtils;
-import android.os.Process;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.security.NoSuchAlgorithmException;
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
deleted file mode 100644
index d80612b..0000000
--- a/libs/androidfw/Android.mk
+++ /dev/null
@@ -1,93 +0,0 @@
-# Copyright (C) 2010 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-# libandroidfw is partially built for the host (used by obbtool and others)
-# These files are common to host and target builds.
-
-commonSources := \
-    Asset.cpp \
-    AssetDir.cpp \
-    AssetManager.cpp \
-    misc.cpp \
-    ObbFile.cpp \
-    ResourceTypes.cpp \
-    StreamingZipInflater.cpp \
-    ZipFileRO.cpp \
-    ZipUtils.cpp
-
-deviceSources := \
-    $(commonSources) \
-    BackupData.cpp \
-    BackupHelpers.cpp \
-    CursorWindow.cpp
-
-hostSources := \
-    $(commonSources)
-
-# For the host
-# =====================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= $(hostSources)
-
-LOCAL_MODULE:= libandroidfw
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
-
-LOCAL_C_INCLUDES := \
-	external/zlib
-
-LOCAL_STATIC_LIBRARIES := liblog
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-
-# For the device
-# =====================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= $(deviceSources)
-
-LOCAL_SHARED_LIBRARIES := \
-	libbinder \
-	liblog \
-	libcutils \
-	libutils \
-	libz
-
-LOCAL_C_INCLUDES := \
-    external/icu4c/common \
-	external/zlib
-
-LOCAL_MODULE:= libandroidfw
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-# Include subdirectory makefiles
-# ============================================================
-
-# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
-# team really wants is to build the stuff defined by this makefile.
-ifeq (,$(ONE_SHOT_MAKEFILE))
-include $(call first-makefiles-under,$(LOCAL_PATH))
-endif
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp
deleted file mode 100644
index cb7628d..0000000
--- a/libs/androidfw/Asset.cpp
+++ /dev/null
@@ -1,897 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Provide access to a read-only asset.
-//
-
-#define LOG_TAG "asset"
-//#define NDEBUG 0
-
-#include <androidfw/Asset.h>
-#include <androidfw/StreamingZipInflater.h>
-#include <androidfw/ZipFileRO.h>
-#include <androidfw/ZipUtils.h>
-#include <utils/Atomic.h>
-#include <utils/FileMap.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <memory.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-using namespace android;
-
-#ifndef O_BINARY
-# define O_BINARY 0
-#endif
-
-static Mutex gAssetLock;
-static int32_t gCount = 0;
-static Asset* gHead = NULL;
-static Asset* gTail = NULL;
-
-int32_t Asset::getGlobalCount()
-{
-    AutoMutex _l(gAssetLock);
-    return gCount;
-}
-
-String8 Asset::getAssetAllocations()
-{
-    AutoMutex _l(gAssetLock);
-    String8 res;
-    Asset* cur = gHead;
-    while (cur != NULL) {
-        if (cur->isAllocated()) {
-            res.append("    ");
-            res.append(cur->getAssetSource());
-            off64_t size = (cur->getLength()+512)/1024;
-            char buf[64];
-            sprintf(buf, ": %dK\n", (int)size);
-            res.append(buf);
-        }
-        cur = cur->mNext;
-    }
-    
-    return res;
-}
-
-Asset::Asset(void)
-    : mAccessMode(ACCESS_UNKNOWN)
-{
-    AutoMutex _l(gAssetLock);
-    gCount++;
-    mNext = mPrev = NULL;
-    if (gTail == NULL) {
-        gHead = gTail = this;
-  	} else {
-  	    mPrev = gTail;
-  	    gTail->mNext = this;
-  	    gTail = this;
-  	}
-    //ALOGI("Creating Asset %p #%d\n", this, gCount);
-}
-
-Asset::~Asset(void)
-{
-    AutoMutex _l(gAssetLock);
-	gCount--;
-    if (gHead == this) {
-        gHead = mNext;
-    }
-    if (gTail == this) {
-        gTail = mPrev;
-    }
-    if (mNext != NULL) {
-        mNext->mPrev = mPrev;
-    }
-    if (mPrev != NULL) {
-        mPrev->mNext = mNext;
-    }
-    mNext = mPrev = NULL;
-    //ALOGI("Destroying Asset in %p #%d\n", this, gCount);
-}
-
-/*
- * Create a new Asset from a file on disk.  There is a fair chance that
- * the file doesn't actually exist.
- *
- * We can use "mode" to decide how we want to go about it.
- */
-/*static*/ Asset* Asset::createFromFile(const char* fileName, AccessMode mode)
-{
-    _FileAsset* pAsset;
-    status_t result;
-    off64_t length;
-    int fd;
-
-    fd = open(fileName, O_RDONLY | O_BINARY);
-    if (fd < 0)
-        return NULL;
-
-    /*
-     * Under Linux, the lseek fails if we actually opened a directory.  To
-     * be correct we should test the file type explicitly, but since we
-     * always open things read-only it doesn't really matter, so there's
-     * no value in incurring the extra overhead of an fstat() call.
-     */
-    // TODO(kroot): replace this with fstat despite the plea above.
-#if 1
-    length = lseek64(fd, 0, SEEK_END);
-    if (length < 0) {
-        ::close(fd);
-        return NULL;
-    }
-    (void) lseek64(fd, 0, SEEK_SET);
-#else
-    struct stat st;
-    if (fstat(fd, &st) < 0) {
-        ::close(fd);
-        return NULL;
-    }
-
-    if (!S_ISREG(st.st_mode)) {
-        ::close(fd);
-        return NULL;
-    }
-#endif
-
-    pAsset = new _FileAsset;
-    result = pAsset->openChunk(fileName, fd, 0, length);
-    if (result != NO_ERROR) {
-        delete pAsset;
-        return NULL;
-    }
-
-    pAsset->mAccessMode = mode;
-    return pAsset;
-}
-
-
-/*
- * Create a new Asset from a compressed file on disk.  There is a fair chance
- * that the file doesn't actually exist.
- *
- * We currently support gzip files.  We might want to handle .bz2 someday.
- */
-/*static*/ Asset* Asset::createFromCompressedFile(const char* fileName,
-    AccessMode mode)
-{
-    _CompressedAsset* pAsset;
-    status_t result;
-    off64_t fileLen;
-    bool scanResult;
-    long offset;
-    int method;
-    long uncompressedLen, compressedLen;
-    int fd;
-
-    fd = open(fileName, O_RDONLY | O_BINARY);
-    if (fd < 0)
-        return NULL;
-
-    fileLen = lseek(fd, 0, SEEK_END);
-    if (fileLen < 0) {
-        ::close(fd);
-        return NULL;
-    }
-    (void) lseek(fd, 0, SEEK_SET);
-
-    /* want buffered I/O for the file scan; must dup so fclose() is safe */
-    FILE* fp = fdopen(dup(fd), "rb");
-    if (fp == NULL) {
-        ::close(fd);
-        return NULL;
-    }
-
-    unsigned long crc32;
-    scanResult = ZipUtils::examineGzip(fp, &method, &uncompressedLen,
-                    &compressedLen, &crc32);
-    offset = ftell(fp);
-    fclose(fp);
-    if (!scanResult) {
-        ALOGD("File '%s' is not in gzip format\n", fileName);
-        ::close(fd);
-        return NULL;
-    }
-
-    pAsset = new _CompressedAsset;
-    result = pAsset->openChunk(fd, offset, method, uncompressedLen,
-                compressedLen);
-    if (result != NO_ERROR) {
-        delete pAsset;
-        return NULL;
-    }
-
-    pAsset->mAccessMode = mode;
-    return pAsset;
-}
-
-
-#if 0
-/*
- * Create a new Asset from part of an open file.
- */
-/*static*/ Asset* Asset::createFromFileSegment(int fd, off64_t offset,
-    size_t length, AccessMode mode)
-{
-    _FileAsset* pAsset;
-    status_t result;
-
-    pAsset = new _FileAsset;
-    result = pAsset->openChunk(NULL, fd, offset, length);
-    if (result != NO_ERROR)
-        return NULL;
-
-    pAsset->mAccessMode = mode;
-    return pAsset;
-}
-
-/*
- * Create a new Asset from compressed data in an open file.
- */
-/*static*/ Asset* Asset::createFromCompressedData(int fd, off64_t offset,
-    int compressionMethod, size_t uncompressedLen, size_t compressedLen,
-    AccessMode mode)
-{
-    _CompressedAsset* pAsset;
-    status_t result;
-
-    pAsset = new _CompressedAsset;
-    result = pAsset->openChunk(fd, offset, compressionMethod,
-                uncompressedLen, compressedLen);
-    if (result != NO_ERROR)
-        return NULL;
-
-    pAsset->mAccessMode = mode;
-    return pAsset;
-}
-#endif
-
-/*
- * Create a new Asset from a memory mapping.
- */
-/*static*/ Asset* Asset::createFromUncompressedMap(FileMap* dataMap,
-    AccessMode mode)
-{
-    _FileAsset* pAsset;
-    status_t result;
-
-    pAsset = new _FileAsset;
-    result = pAsset->openChunk(dataMap);
-    if (result != NO_ERROR)
-        return NULL;
-
-    pAsset->mAccessMode = mode;
-    return pAsset;
-}
-
-/*
- * Create a new Asset from compressed data in a memory mapping.
- */
-/*static*/ Asset* Asset::createFromCompressedMap(FileMap* dataMap,
-    int method, size_t uncompressedLen, AccessMode mode)
-{
-    _CompressedAsset* pAsset;
-    status_t result;
-
-    pAsset = new _CompressedAsset;
-    result = pAsset->openChunk(dataMap, method, uncompressedLen);
-    if (result != NO_ERROR)
-        return NULL;
-
-    pAsset->mAccessMode = mode;
-    return pAsset;
-}
-
-
-/*
- * Do generic seek() housekeeping.  Pass in the offset/whence values from
- * the seek request, along with the current chunk offset and the chunk
- * length.
- *
- * Returns the new chunk offset, or -1 if the seek is illegal.
- */
-off64_t Asset::handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn)
-{
-    off64_t newOffset;
-
-    switch (whence) {
-    case SEEK_SET:
-        newOffset = offset;
-        break;
-    case SEEK_CUR:
-        newOffset = curPosn + offset;
-        break;
-    case SEEK_END:
-        newOffset = maxPosn + offset;
-        break;
-    default:
-        ALOGW("unexpected whence %d\n", whence);
-        // this was happening due to an off64_t size mismatch
-        assert(false);
-        return (off64_t) -1;
-    }
-
-    if (newOffset < 0 || newOffset > maxPosn) {
-        ALOGW("seek out of range: want %ld, end=%ld\n",
-            (long) newOffset, (long) maxPosn);
-        return (off64_t) -1;
-    }
-
-    return newOffset;
-}
-
-
-/*
- * ===========================================================================
- *      _FileAsset
- * ===========================================================================
- */
-
-/*
- * Constructor.
- */
-_FileAsset::_FileAsset(void)
-    : mStart(0), mLength(0), mOffset(0), mFp(NULL), mFileName(NULL), mMap(NULL), mBuf(NULL)
-{
-}
-
-/*
- * Destructor.  Release resources.
- */
-_FileAsset::~_FileAsset(void)
-{
-    close();
-}
-
-/*
- * Operate on a chunk of an uncompressed file.
- *
- * Zero-length chunks are allowed.
- */
-status_t _FileAsset::openChunk(const char* fileName, int fd, off64_t offset, size_t length)
-{
-    assert(mFp == NULL);    // no reopen
-    assert(mMap == NULL);
-    assert(fd >= 0);
-    assert(offset >= 0);
-
-    /*
-     * Seek to end to get file length.
-     */
-    off64_t fileLength;
-    fileLength = lseek64(fd, 0, SEEK_END);
-    if (fileLength == (off64_t) -1) {
-        // probably a bad file descriptor
-        ALOGD("failed lseek (errno=%d)\n", errno);
-        return UNKNOWN_ERROR;
-    }
-
-    if ((off64_t) (offset + length) > fileLength) {
-        ALOGD("start (%ld) + len (%ld) > end (%ld)\n",
-            (long) offset, (long) length, (long) fileLength);
-        return BAD_INDEX;
-    }
-
-    /* after fdopen, the fd will be closed on fclose() */
-    mFp = fdopen(fd, "rb");
-    if (mFp == NULL)
-        return UNKNOWN_ERROR;
-
-    mStart = offset;
-    mLength = length;
-    assert(mOffset == 0);
-
-    /* seek the FILE* to the start of chunk */
-    if (fseek(mFp, mStart, SEEK_SET) != 0) {
-        assert(false);
-    }
-
-    mFileName = fileName != NULL ? strdup(fileName) : NULL;
-    
-    return NO_ERROR;
-}
-
-/*
- * Create the chunk from the map.
- */
-status_t _FileAsset::openChunk(FileMap* dataMap)
-{
-    assert(mFp == NULL);    // no reopen
-    assert(mMap == NULL);
-    assert(dataMap != NULL);
-
-    mMap = dataMap;
-    mStart = -1;            // not used
-    mLength = dataMap->getDataLength();
-    assert(mOffset == 0);
-
-    return NO_ERROR;
-}
-
-/*
- * Read a chunk of data.
- */
-ssize_t _FileAsset::read(void* buf, size_t count)
-{
-    size_t maxLen;
-    size_t actual;
-
-    assert(mOffset >= 0 && mOffset <= mLength);
-
-    if (getAccessMode() == ACCESS_BUFFER) {
-        /*
-         * On first access, read or map the entire file.  The caller has
-         * requested buffer access, either because they're going to be
-         * using the buffer or because what they're doing has appropriate
-         * performance needs and access patterns.
-         */
-        if (mBuf == NULL)
-            getBuffer(false);
-    }
-
-    /* adjust count if we're near EOF */
-    maxLen = mLength - mOffset;
-    if (count > maxLen)
-        count = maxLen;
-
-    if (!count)
-        return 0;
-
-    if (mMap != NULL) {
-        /* copy from mapped area */
-        //printf("map read\n");
-        memcpy(buf, (char*)mMap->getDataPtr() + mOffset, count);
-        actual = count;
-    } else if (mBuf != NULL) {
-        /* copy from buffer */
-        //printf("buf read\n");
-        memcpy(buf, (char*)mBuf + mOffset, count);
-        actual = count;
-    } else {
-        /* read from the file */
-        //printf("file read\n");
-        if (ftell(mFp) != mStart + mOffset) {
-            ALOGE("Hosed: %ld != %ld+%ld\n",
-                ftell(mFp), (long) mStart, (long) mOffset);
-            assert(false);
-        }
-
-        /*
-         * This returns 0 on error or eof.  We need to use ferror() or feof()
-         * to tell the difference, but we don't currently have those on the
-         * device.  However, we know how much data is *supposed* to be in the
-         * file, so if we don't read the full amount we know something is
-         * hosed.
-         */
-        actual = fread(buf, 1, count, mFp);
-        if (actual == 0)        // something failed -- I/O error?
-            return -1;
-
-        assert(actual == count);
-    }
-
-    mOffset += actual;
-    return actual;
-}
-
-/*
- * Seek to a new position.
- */
-off64_t _FileAsset::seek(off64_t offset, int whence)
-{
-    off64_t newPosn;
-    off64_t actualOffset;
-
-    // compute new position within chunk
-    newPosn = handleSeek(offset, whence, mOffset, mLength);
-    if (newPosn == (off64_t) -1)
-        return newPosn;
-
-    actualOffset = mStart + newPosn;
-
-    if (mFp != NULL) {
-        if (fseek(mFp, (long) actualOffset, SEEK_SET) != 0)
-            return (off64_t) -1;
-    }
-
-    mOffset = actualOffset - mStart;
-    return mOffset;
-}
-
-/*
- * Close the asset.
- */
-void _FileAsset::close(void)
-{
-    if (mMap != NULL) {
-        mMap->release();
-        mMap = NULL;
-    }
-    if (mBuf != NULL) {
-        delete[] mBuf;
-        mBuf = NULL;
-    }
-
-    if (mFileName != NULL) {
-        free(mFileName);
-        mFileName = NULL;
-    }
-    
-    if (mFp != NULL) {
-        // can only be NULL when called from destructor
-        // (otherwise we would never return this object)
-        fclose(mFp);
-        mFp = NULL;
-    }
-}
-
-/*
- * Return a read-only pointer to a buffer.
- *
- * We can either read the whole thing in or map the relevant piece of
- * the source file.  Ideally a map would be established at a higher
- * level and we'd be using a different object, but we didn't, so we
- * deal with it here.
- */
-const void* _FileAsset::getBuffer(bool wordAligned)
-{
-    /* subsequent requests just use what we did previously */
-    if (mBuf != NULL)
-        return mBuf;
-    if (mMap != NULL) {
-        if (!wordAligned) {
-            return  mMap->getDataPtr();
-        }
-        return ensureAlignment(mMap);
-    }
-
-    assert(mFp != NULL);
-
-    if (mLength < kReadVsMapThreshold) {
-        unsigned char* buf;
-        long allocLen;
-
-        /* zero-length files are allowed; not sure about zero-len allocs */
-        /* (works fine with gcc + x86linux) */
-        allocLen = mLength;
-        if (mLength == 0)
-            allocLen = 1;
-
-        buf = new unsigned char[allocLen];
-        if (buf == NULL) {
-            ALOGE("alloc of %ld bytes failed\n", (long) allocLen);
-            return NULL;
-        }
-
-        ALOGV("Asset %p allocating buffer size %d (smaller than threshold)", this, (int)allocLen);
-        if (mLength > 0) {
-            long oldPosn = ftell(mFp);
-            fseek(mFp, mStart, SEEK_SET);
-            if (fread(buf, 1, mLength, mFp) != (size_t) mLength) {
-                ALOGE("failed reading %ld bytes\n", (long) mLength);
-                delete[] buf;
-                return NULL;
-            }
-            fseek(mFp, oldPosn, SEEK_SET);
-        }
-
-        ALOGV(" getBuffer: loaded into buffer\n");
-
-        mBuf = buf;
-        return mBuf;
-    } else {
-        FileMap* map;
-
-        map = new FileMap;
-        if (!map->create(NULL, fileno(mFp), mStart, mLength, true)) {
-            map->release();
-            return NULL;
-        }
-
-        ALOGV(" getBuffer: mapped\n");
-
-        mMap = map;
-        if (!wordAligned) {
-            return  mMap->getDataPtr();
-        }
-        return ensureAlignment(mMap);
-    }
-}
-
-int _FileAsset::openFileDescriptor(off64_t* outStart, off64_t* outLength) const
-{
-    if (mMap != NULL) {
-        const char* fname = mMap->getFileName();
-        if (fname == NULL) {
-            fname = mFileName;
-        }
-        if (fname == NULL) {
-            return -1;
-        }
-        *outStart = mMap->getDataOffset();
-        *outLength = mMap->getDataLength();
-        return open(fname, O_RDONLY | O_BINARY);
-    }
-    if (mFileName == NULL) {
-        return -1;
-    }
-    *outStart = mStart;
-    *outLength = mLength;
-    return open(mFileName, O_RDONLY | O_BINARY);
-}
-
-const void* _FileAsset::ensureAlignment(FileMap* map)
-{
-    void* data = map->getDataPtr();
-    if ((((size_t)data)&0x3) == 0) {
-        // We can return this directly if it is aligned on a word
-        // boundary.
-        ALOGV("Returning aligned FileAsset %p (%s).", this,
-                getAssetSource());
-        return data;
-    }
-    // If not aligned on a word boundary, then we need to copy it into
-    // our own buffer.
-    ALOGV("Copying FileAsset %p (%s) to buffer size %d to make it aligned.", this,
-            getAssetSource(), (int)mLength);
-    unsigned char* buf = new unsigned char[mLength];
-    if (buf == NULL) {
-        ALOGE("alloc of %ld bytes failed\n", (long) mLength);
-        return NULL;
-    }
-    memcpy(buf, data, mLength);
-    mBuf = buf;
-    return buf;
-}
-
-/*
- * ===========================================================================
- *      _CompressedAsset
- * ===========================================================================
- */
-
-/*
- * Constructor.
- */
-_CompressedAsset::_CompressedAsset(void)
-    : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0),
-      mMap(NULL), mFd(-1), mZipInflater(NULL), mBuf(NULL)
-{
-}
-
-/*
- * Destructor.  Release resources.
- */
-_CompressedAsset::~_CompressedAsset(void)
-{
-    close();
-}
-
-/*
- * Open a chunk of compressed data inside a file.
- *
- * This currently just sets up some values and returns.  On the first
- * read, we expand the entire file into a buffer and return data from it.
- */
-status_t _CompressedAsset::openChunk(int fd, off64_t offset,
-    int compressionMethod, size_t uncompressedLen, size_t compressedLen)
-{
-    assert(mFd < 0);        // no re-open
-    assert(mMap == NULL);
-    assert(fd >= 0);
-    assert(offset >= 0);
-    assert(compressedLen > 0);
-
-    if (compressionMethod != ZipFileRO::kCompressDeflated) {
-        assert(false);
-        return UNKNOWN_ERROR;
-    }
-
-    mStart = offset;
-    mCompressedLen = compressedLen;
-    mUncompressedLen = uncompressedLen;
-    assert(mOffset == 0);
-    mFd = fd;
-    assert(mBuf == NULL);
-
-    if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) {
-        mZipInflater = new StreamingZipInflater(mFd, offset, uncompressedLen, compressedLen);
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Open a chunk of compressed data in a mapped region.
- *
- * Nothing is expanded until the first read call.
- */
-status_t _CompressedAsset::openChunk(FileMap* dataMap, int compressionMethod,
-    size_t uncompressedLen)
-{
-    assert(mFd < 0);        // no re-open
-    assert(mMap == NULL);
-    assert(dataMap != NULL);
-
-    if (compressionMethod != ZipFileRO::kCompressDeflated) {
-        assert(false);
-        return UNKNOWN_ERROR;
-    }
-
-    mMap = dataMap;
-    mStart = -1;        // not used
-    mCompressedLen = dataMap->getDataLength();
-    mUncompressedLen = uncompressedLen;
-    assert(mOffset == 0);
-
-    if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) {
-        mZipInflater = new StreamingZipInflater(dataMap, uncompressedLen);
-    }
-    return NO_ERROR;
-}
-
-/*
- * Read data from a chunk of compressed data.
- *
- * [For now, that's just copying data out of a buffer.]
- */
-ssize_t _CompressedAsset::read(void* buf, size_t count)
-{
-    size_t maxLen;
-    size_t actual;
-
-    assert(mOffset >= 0 && mOffset <= mUncompressedLen);
-
-    /* If we're relying on a streaming inflater, go through that */
-    if (mZipInflater) {
-        actual = mZipInflater->read(buf, count);
-    } else {
-        if (mBuf == NULL) {
-            if (getBuffer(false) == NULL)
-                return -1;
-        }
-        assert(mBuf != NULL);
-
-        /* adjust count if we're near EOF */
-        maxLen = mUncompressedLen - mOffset;
-        if (count > maxLen)
-            count = maxLen;
-
-        if (!count)
-            return 0;
-
-        /* copy from buffer */
-        //printf("comp buf read\n");
-        memcpy(buf, (char*)mBuf + mOffset, count);
-        actual = count;
-    }
-
-    mOffset += actual;
-    return actual;
-}
-
-/*
- * Handle a seek request.
- *
- * If we're working in a streaming mode, this is going to be fairly
- * expensive, because it requires plowing through a bunch of compressed
- * data.
- */
-off64_t _CompressedAsset::seek(off64_t offset, int whence)
-{
-    off64_t newPosn;
-
-    // compute new position within chunk
-    newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen);
-    if (newPosn == (off64_t) -1)
-        return newPosn;
-
-    if (mZipInflater) {
-        mZipInflater->seekAbsolute(newPosn);
-    }
-    mOffset = newPosn;
-    return mOffset;
-}
-
-/*
- * Close the asset.
- */
-void _CompressedAsset::close(void)
-{
-    if (mMap != NULL) {
-        mMap->release();
-        mMap = NULL;
-    }
-
-    delete[] mBuf;
-    mBuf = NULL;
-
-    delete mZipInflater;
-    mZipInflater = NULL;
-
-    if (mFd > 0) {
-        ::close(mFd);
-        mFd = -1;
-    }
-}
-
-/*
- * Get a pointer to a read-only buffer of data.
- *
- * The first time this is called, we expand the compressed data into a
- * buffer.
- */
-const void* _CompressedAsset::getBuffer(bool wordAligned)
-{
-    unsigned char* buf = NULL;
-
-    if (mBuf != NULL)
-        return mBuf;
-
-    /*
-     * Allocate a buffer and read the file into it.
-     */
-    buf = new unsigned char[mUncompressedLen];
-    if (buf == NULL) {
-        ALOGW("alloc %ld bytes failed\n", (long) mUncompressedLen);
-        goto bail;
-    }
-
-    if (mMap != NULL) {
-        if (!ZipFileRO::inflateBuffer(buf, mMap->getDataPtr(),
-                mUncompressedLen, mCompressedLen))
-            goto bail;
-    } else {
-        assert(mFd >= 0);
-
-        /*
-         * Seek to the start of the compressed data.
-         */
-        if (lseek(mFd, mStart, SEEK_SET) != mStart)
-            goto bail;
-
-        /*
-         * Expand the data into it.
-         */
-        if (!ZipUtils::inflateToBuffer(mFd, buf, mUncompressedLen,
-                mCompressedLen))
-            goto bail;
-    }
-
-    /*
-     * Success - now that we have the full asset in RAM we
-     * no longer need the streaming inflater
-     */
-    delete mZipInflater;
-    mZipInflater = NULL;
-
-    mBuf = buf;
-    buf = NULL;
-
-bail:
-    delete[] buf;
-    return mBuf;
-}
-
diff --git a/libs/androidfw/AssetDir.cpp b/libs/androidfw/AssetDir.cpp
deleted file mode 100644
index 475f521..0000000
--- a/libs/androidfw/AssetDir.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Provide access to a virtual directory in "asset space".  Most of the
-// implementation is in the header file or in friend functions in
-// AssetManager.
-//
-#include <androidfw/AssetDir.h>
-
-using namespace android;
-
-
-/*
- * Find a matching entry in a vector of FileInfo.  Because it's sorted, we
- * can use a binary search.
- *
- * Assumes the vector is sorted in ascending order.
- */
-/*static*/ int AssetDir::FileInfo::findEntry(const SortedVector<FileInfo>* pVector,
-    const String8& fileName)
-{
-    FileInfo tmpInfo;
-
-    tmpInfo.setFileName(fileName);
-    return pVector->indexOf(tmpInfo);
-
-#if 0  // don't need this after all (uses 1/2 compares of SortedVector though)
-    int lo, hi, cur;
-
-    lo = 0;
-    hi = pVector->size() -1;
-    while (lo <= hi) {
-        int cmp;
-
-        cur = (hi + lo) / 2;
-        cmp = strcmp(pVector->itemAt(cur).getFileName(), fileName);
-        if (cmp == 0) {
-            /* match, bail */
-            return cur;
-        } else if (cmp < 0) {
-            /* too low */
-            lo = cur + 1;
-        } else {
-            /* too high */
-            hi = cur -1;
-        }
-    }
-
-    return -1;
-#endif
-}
-
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
deleted file mode 100644
index 6667daf..0000000
--- a/libs/androidfw/AssetManager.cpp
+++ /dev/null
@@ -1,2034 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Provide access to read-only assets.
-//
-
-#define LOG_TAG "asset"
-#define ATRACE_TAG ATRACE_TAG_RESOURCES
-//#define LOG_NDEBUG 0
-
-#include <androidfw/Asset.h>
-#include <androidfw/AssetDir.h>
-#include <androidfw/AssetManager.h>
-#include <androidfw/misc.h>
-#include <androidfw/ResourceTypes.h>
-#include <androidfw/ZipFileRO.h>
-#include <utils/Atomic.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-#include <utils/Timers.h>
-#ifdef HAVE_ANDROID_OS
-#include <cutils/trace.h>
-#endif
-
-#include <assert.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <strings.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#ifndef TEMP_FAILURE_RETRY
-/* Used to retry syscalls that can return EINTR. */
-#define TEMP_FAILURE_RETRY(exp) ({         \
-    typeof (exp) _rc;                      \
-    do {                                   \
-        _rc = (exp);                       \
-    } while (_rc == -1 && errno == EINTR); \
-    _rc; })
-#endif
-
-#ifdef HAVE_ANDROID_OS
-#define MY_TRACE_BEGIN(x) ATRACE_BEGIN(x)
-#define MY_TRACE_END() ATRACE_END()
-#else
-#define MY_TRACE_BEGIN(x)
-#define MY_TRACE_END()
-#endif
-
-using namespace android;
-
-/*
- * Names for default app, locale, and vendor.  We might want to change
- * these to be an actual locale, e.g. always use en-US as the default.
- */
-static const char* kDefaultLocale = "default";
-static const char* kDefaultVendor = "default";
-static const char* kAssetsRoot = "assets";
-static const char* kAppZipName = NULL; //"classes.jar";
-static const char* kSystemAssets = "framework/framework-res.apk";
-static const char* kIdmapCacheDir = "resource-cache";
-
-static const char* kExcludeExtension = ".EXCLUDE";
-
-static Asset* const kExcludedAsset = (Asset*) 0xd000000d;
-
-static volatile int32_t gCount = 0;
-
-namespace {
-    // Transform string /a/b/c.apk to /data/resource-cache/a@b@c.apk@idmap
-    String8 idmapPathForPackagePath(const String8& pkgPath)
-    {
-        const char* root = getenv("ANDROID_DATA");
-        LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_DATA not set");
-        String8 path(root);
-        path.appendPath(kIdmapCacheDir);
-
-        char buf[256]; // 256 chars should be enough for anyone...
-        strncpy(buf, pkgPath.string(), 255);
-        buf[255] = '\0';
-        char* filename = buf;
-        while (*filename && *filename == '/') {
-            ++filename;
-        }
-        char* p = filename;
-        while (*p) {
-            if (*p == '/') {
-                *p = '@';
-            }
-            ++p;
-        }
-        path.appendPath(filename);
-        path.append("@idmap");
-
-        return path;
-    }
-
-    /*
-     * Like strdup(), but uses C++ "new" operator instead of malloc.
-     */
-    static char* strdupNew(const char* str)
-    {
-        char* newStr;
-        int len;
-
-        if (str == NULL)
-            return NULL;
-
-        len = strlen(str);
-        newStr = new char[len+1];
-        memcpy(newStr, str, len+1);
-
-        return newStr;
-    }
-}
-
-/*
- * ===========================================================================
- *      AssetManager
- * ===========================================================================
- */
-
-int32_t AssetManager::getGlobalCount()
-{
-    return gCount;
-}
-
-AssetManager::AssetManager(CacheMode cacheMode)
-    : mLocale(NULL), mVendor(NULL),
-      mResources(NULL), mConfig(new ResTable_config),
-      mCacheMode(cacheMode), mCacheValid(false)
-{
-    int count = android_atomic_inc(&gCount)+1;
-    //ALOGI("Creating AssetManager %p #%d\n", this, count);
-    memset(mConfig, 0, sizeof(ResTable_config));
-}
-
-AssetManager::~AssetManager(void)
-{
-    int count = android_atomic_dec(&gCount);
-    //ALOGI("Destroying AssetManager in %p #%d\n", this, count);
-
-    delete mConfig;
-    delete mResources;
-
-    // don't have a String class yet, so make sure we clean up
-    delete[] mLocale;
-    delete[] mVendor;
-}
-
-bool AssetManager::addAssetPath(const String8& path, void** cookie)
-{
-    AutoMutex _l(mLock);
-
-    asset_path ap;
-
-    String8 realPath(path);
-    if (kAppZipName) {
-        realPath.appendPath(kAppZipName);
-    }
-    ap.type = ::getFileType(realPath.string());
-    if (ap.type == kFileTypeRegular) {
-        ap.path = realPath;
-    } else {
-        ap.path = path;
-        ap.type = ::getFileType(path.string());
-        if (ap.type != kFileTypeDirectory && ap.type != kFileTypeRegular) {
-            ALOGW("Asset path %s is neither a directory nor file (type=%d).",
-                 path.string(), (int)ap.type);
-            return false;
-        }
-    }
-
-    // Skip if we have it already.
-    for (size_t i=0; i<mAssetPaths.size(); i++) {
-        if (mAssetPaths[i].path == ap.path) {
-            if (cookie) {
-                *cookie = (void*)(i+1);
-            }
-            return true;
-        }
-    }
-
-    ALOGV("In %p Asset %s path: %s", this,
-         ap.type == kFileTypeDirectory ? "dir" : "zip", ap.path.string());
-
-    mAssetPaths.add(ap);
-
-    // new paths are always added at the end
-    if (cookie) {
-        *cookie = (void*)mAssetPaths.size();
-    }
-
-    // add overlay packages for /system/framework; apps are handled by the
-    // (Java) package manager
-    if (strncmp(path.string(), "/system/framework/", 18) == 0) {
-        // When there is an environment variable for /vendor, this
-        // should be changed to something similar to how ANDROID_ROOT
-        // and ANDROID_DATA are used in this file.
-        String8 overlayPath("/vendor/overlay/framework/");
-        overlayPath.append(path.getPathLeaf());
-        if (TEMP_FAILURE_RETRY(access(overlayPath.string(), R_OK)) == 0) {
-            asset_path oap;
-            oap.path = overlayPath;
-            oap.type = ::getFileType(overlayPath.string());
-            bool addOverlay = (oap.type == kFileTypeRegular); // only .apks supported as overlay
-            if (addOverlay) {
-                oap.idmap = idmapPathForPackagePath(overlayPath);
-
-                if (isIdmapStaleLocked(ap.path, oap.path, oap.idmap)) {
-                    addOverlay = createIdmapFileLocked(ap.path, oap.path, oap.idmap);
-                }
-            }
-            if (addOverlay) {
-                mAssetPaths.add(oap);
-            } else {
-                ALOGW("failed to add overlay package %s\n", overlayPath.string());
-            }
-        }
-    }
-
-    return true;
-}
-
-bool AssetManager::isIdmapStaleLocked(const String8& originalPath, const String8& overlayPath,
-                                      const String8& idmapPath)
-{
-    struct stat st;
-    if (TEMP_FAILURE_RETRY(stat(idmapPath.string(), &st)) == -1) {
-        if (errno == ENOENT) {
-            return true; // non-existing idmap is always stale
-        } else {
-            ALOGW("failed to stat file %s: %s\n", idmapPath.string(), strerror(errno));
-            return false;
-        }
-    }
-    if (st.st_size < ResTable::IDMAP_HEADER_SIZE_BYTES) {
-        ALOGW("file %s has unexpectedly small size=%zd\n", idmapPath.string(), (size_t)st.st_size);
-        return false;
-    }
-    int fd = TEMP_FAILURE_RETRY(::open(idmapPath.string(), O_RDONLY));
-    if (fd == -1) {
-        ALOGW("failed to open file %s: %s\n", idmapPath.string(), strerror(errno));
-        return false;
-    }
-    char buf[ResTable::IDMAP_HEADER_SIZE_BYTES];
-    ssize_t bytesLeft = ResTable::IDMAP_HEADER_SIZE_BYTES;
-    for (;;) {
-        ssize_t r = TEMP_FAILURE_RETRY(read(fd, buf + ResTable::IDMAP_HEADER_SIZE_BYTES - bytesLeft,
-                                            bytesLeft));
-        if (r < 0) {
-            TEMP_FAILURE_RETRY(close(fd));
-            return false;
-        }
-        bytesLeft -= r;
-        if (bytesLeft == 0) {
-            break;
-        }
-    }
-    TEMP_FAILURE_RETRY(close(fd));
-
-    uint32_t cachedOriginalCrc, cachedOverlayCrc;
-    if (!ResTable::getIdmapInfo(buf, ResTable::IDMAP_HEADER_SIZE_BYTES,
-                                &cachedOriginalCrc, &cachedOverlayCrc)) {
-        return false;
-    }
-
-    uint32_t actualOriginalCrc, actualOverlayCrc;
-    if (!getZipEntryCrcLocked(originalPath, "resources.arsc", &actualOriginalCrc)) {
-        return false;
-    }
-    if (!getZipEntryCrcLocked(overlayPath, "resources.arsc", &actualOverlayCrc)) {
-        return false;
-    }
-    return cachedOriginalCrc != actualOriginalCrc || cachedOverlayCrc != actualOverlayCrc;
-}
-
-bool AssetManager::getZipEntryCrcLocked(const String8& zipPath, const char* entryFilename,
-                                        uint32_t* pCrc)
-{
-    asset_path ap;
-    ap.path = zipPath;
-    const ZipFileRO* zip = getZipFileLocked(ap);
-    if (zip == NULL) {
-        return false;
-    }
-    const ZipEntryRO entry = zip->findEntryByName(entryFilename);
-    if (entry == NULL) {
-        return false;
-    }
-    if (!zip->getEntryInfo(entry, NULL, NULL, NULL, NULL, NULL, (long*)pCrc)) {
-        return false;
-    }
-    return true;
-}
-
-bool AssetManager::createIdmapFileLocked(const String8& originalPath, const String8& overlayPath,
-                                         const String8& idmapPath)
-{
-    ALOGD("%s: originalPath=%s overlayPath=%s idmapPath=%s\n",
-         __FUNCTION__, originalPath.string(), overlayPath.string(), idmapPath.string());
-    ResTable tables[2];
-    const String8* paths[2] = { &originalPath, &overlayPath };
-    uint32_t originalCrc, overlayCrc;
-    bool retval = false;
-    ssize_t offset = 0;
-    int fd = 0;
-    uint32_t* data = NULL;
-    size_t size;
-
-    for (int i = 0; i < 2; ++i) {
-        asset_path ap;
-        ap.type = kFileTypeRegular;
-        ap.path = *paths[i];
-        Asset* ass = openNonAssetInPathLocked("resources.arsc", Asset::ACCESS_BUFFER, ap);
-        if (ass == NULL) {
-            ALOGW("failed to find resources.arsc in %s\n", ap.path.string());
-            goto error;
-        }
-        tables[i].add(ass, (void*)1, false);
-    }
-
-    if (!getZipEntryCrcLocked(originalPath, "resources.arsc", &originalCrc)) {
-        ALOGW("failed to retrieve crc for resources.arsc in %s\n", originalPath.string());
-        goto error;
-    }
-    if (!getZipEntryCrcLocked(overlayPath, "resources.arsc", &overlayCrc)) {
-        ALOGW("failed to retrieve crc for resources.arsc in %s\n", overlayPath.string());
-        goto error;
-    }
-
-    if (tables[0].createIdmap(tables[1], originalCrc, overlayCrc,
-                              (void**)&data, &size) != NO_ERROR) {
-        ALOGW("failed to generate idmap data for file %s\n", idmapPath.string());
-        goto error;
-    }
-
-    // This should be abstracted (eg replaced by a stand-alone
-    // application like dexopt, triggered by something equivalent to
-    // installd).
-    fd = TEMP_FAILURE_RETRY(::open(idmapPath.string(), O_WRONLY | O_CREAT | O_TRUNC, 0644));
-    if (fd == -1) {
-        ALOGW("failed to write idmap file %s (open: %s)\n", idmapPath.string(), strerror(errno));
-        goto error_free;
-    }
-    for (;;) {
-        ssize_t written = TEMP_FAILURE_RETRY(write(fd, data + offset, size));
-        if (written < 0) {
-            ALOGW("failed to write idmap file %s (write: %s)\n", idmapPath.string(),
-                 strerror(errno));
-            goto error_close;
-        }
-        size -= (size_t)written;
-        offset += written;
-        if (size == 0) {
-            break;
-        }
-    }
-
-    retval = true;
-error_close:
-    TEMP_FAILURE_RETRY(close(fd));
-error_free:
-    free(data);
-error:
-    return retval;
-}
-
-bool AssetManager::addDefaultAssets()
-{
-    const char* root = getenv("ANDROID_ROOT");
-    LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_ROOT not set");
-
-    String8 path(root);
-    path.appendPath(kSystemAssets);
-
-    return addAssetPath(path, NULL);
-}
-
-void* AssetManager::nextAssetPath(void* cookie) const
-{
-    AutoMutex _l(mLock);
-    size_t next = ((size_t)cookie)+1;
-    return next > mAssetPaths.size() ? NULL : (void*)next;
-}
-
-String8 AssetManager::getAssetPath(void* cookie) const
-{
-    AutoMutex _l(mLock);
-    const size_t which = ((size_t)cookie)-1;
-    if (which < mAssetPaths.size()) {
-        return mAssetPaths[which].path;
-    }
-    return String8();
-}
-
-/*
- * Set the current locale.  Use NULL to indicate no locale.
- *
- * Close and reopen Zip archives as appropriate, and reset cached
- * information in the locale-specific sections of the tree.
- */
-void AssetManager::setLocale(const char* locale)
-{
-    AutoMutex _l(mLock);
-    setLocaleLocked(locale);
-}
-
-void AssetManager::setLocaleLocked(const char* locale)
-{
-    if (mLocale != NULL) {
-        /* previously set, purge cached data */
-        purgeFileNameCacheLocked();
-        //mZipSet.purgeLocale();
-        delete[] mLocale;
-    }
-    mLocale = strdupNew(locale);
-    
-    updateResourceParamsLocked();
-}
-
-/*
- * Set the current vendor.  Use NULL to indicate no vendor.
- *
- * Close and reopen Zip archives as appropriate, and reset cached
- * information in the vendor-specific sections of the tree.
- */
-void AssetManager::setVendor(const char* vendor)
-{
-    AutoMutex _l(mLock);
-
-    if (mVendor != NULL) {
-        /* previously set, purge cached data */
-        purgeFileNameCacheLocked();
-        //mZipSet.purgeVendor();
-        delete[] mVendor;
-    }
-    mVendor = strdupNew(vendor);
-}
-
-void AssetManager::setConfiguration(const ResTable_config& config, const char* locale)
-{
-    AutoMutex _l(mLock);
-    *mConfig = config;
-    if (locale) {
-        setLocaleLocked(locale);
-    } else if (config.language[0] != 0) {
-        char spec[9];
-        spec[0] = config.language[0];
-        spec[1] = config.language[1];
-        if (config.country[0] != 0) {
-            spec[2] = '_';
-            spec[3] = config.country[0];
-            spec[4] = config.country[1];
-            spec[5] = 0;
-        } else {
-            spec[3] = 0;
-        }
-        setLocaleLocked(spec);
-    } else {
-        updateResourceParamsLocked();
-    }
-}
-
-void AssetManager::getConfiguration(ResTable_config* outConfig) const
-{
-    AutoMutex _l(mLock);
-    *outConfig = *mConfig;
-}
-
-/*
- * Open an asset.
- *
- * The data could be;
- *  - In a file on disk (assetBase + fileName).
- *  - In a compressed file on disk (assetBase + fileName.gz).
- *  - In a Zip archive, uncompressed or compressed.
- *
- * It can be in a number of different directories and Zip archives.
- * The search order is:
- *  - [appname]
- *    - locale + vendor
- *    - "default" + vendor
- *    - locale + "default"
- *    - "default + "default"
- *  - "common"
- *    - (same as above)
- *
- * To find a particular file, we have to try up to eight paths with
- * all three forms of data.
- *
- * We should probably reject requests for "illegal" filenames, e.g. those
- * with illegal characters or "../" backward relative paths.
- */
-Asset* AssetManager::open(const char* fileName, AccessMode mode)
-{
-    AutoMutex _l(mLock);
-
-    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-
-
-    if (mCacheMode != CACHE_OFF && !mCacheValid)
-        loadFileNameCacheLocked();
-
-    String8 assetName(kAssetsRoot);
-    assetName.appendPath(fileName);
-
-    /*
-     * For each top-level asset path, search for the asset.
-     */
-
-    size_t i = mAssetPaths.size();
-    while (i > 0) {
-        i--;
-        ALOGV("Looking for asset '%s' in '%s'\n",
-                assetName.string(), mAssetPaths.itemAt(i).path.string());
-        Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i));
-        if (pAsset != NULL) {
-            return pAsset != kExcludedAsset ? pAsset : NULL;
-        }
-    }
-
-    return NULL;
-}
-
-/*
- * Open a non-asset file as if it were an asset.
- *
- * The "fileName" is the partial path starting from the application
- * name.
- */
-Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode)
-{
-    AutoMutex _l(mLock);
-
-    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-
-
-    if (mCacheMode != CACHE_OFF && !mCacheValid)
-        loadFileNameCacheLocked();
-
-    /*
-     * For each top-level asset path, search for the asset.
-     */
-
-    size_t i = mAssetPaths.size();
-    while (i > 0) {
-        i--;
-        ALOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string());
-        Asset* pAsset = openNonAssetInPathLocked(
-            fileName, mode, mAssetPaths.itemAt(i));
-        if (pAsset != NULL) {
-            return pAsset != kExcludedAsset ? pAsset : NULL;
-        }
-    }
-
-    return NULL;
-}
-
-Asset* AssetManager::openNonAsset(void* cookie, const char* fileName, AccessMode mode)
-{
-    const size_t which = ((size_t)cookie)-1;
-
-    AutoMutex _l(mLock);
-
-    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-
-
-    if (mCacheMode != CACHE_OFF && !mCacheValid)
-        loadFileNameCacheLocked();
-
-    if (which < mAssetPaths.size()) {
-        ALOGV("Looking for non-asset '%s' in '%s'\n", fileName,
-                mAssetPaths.itemAt(which).path.string());
-        Asset* pAsset = openNonAssetInPathLocked(
-            fileName, mode, mAssetPaths.itemAt(which));
-        if (pAsset != NULL) {
-            return pAsset != kExcludedAsset ? pAsset : NULL;
-        }
-    }
-
-    return NULL;
-}
-
-/*
- * Get the type of a file in the asset namespace.
- *
- * This currently only works for regular files.  All others (including
- * directories) will return kFileTypeNonexistent.
- */
-FileType AssetManager::getFileType(const char* fileName)
-{
-    Asset* pAsset = NULL;
-
-    /*
-     * Open the asset.  This is less efficient than simply finding the
-     * file, but it's not too bad (we don't uncompress or mmap data until
-     * the first read() call).
-     */
-    pAsset = open(fileName, Asset::ACCESS_STREAMING);
-    delete pAsset;
-
-    if (pAsset == NULL)
-        return kFileTypeNonexistent;
-    else
-        return kFileTypeRegular;
-}
-
-const ResTable* AssetManager::getResTable(bool required) const
-{
-    ResTable* rt = mResources;
-    if (rt) {
-        return rt;
-    }
-
-    // Iterate through all asset packages, collecting resources from each.
-
-    AutoMutex _l(mLock);
-
-    if (mResources != NULL) {
-        return mResources;
-    }
-
-    if (required) {
-        LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-    }
-
-    if (mCacheMode != CACHE_OFF && !mCacheValid)
-        const_cast<AssetManager*>(this)->loadFileNameCacheLocked();
-
-    const size_t N = mAssetPaths.size();
-    for (size_t i=0; i<N; i++) {
-        Asset* ass = NULL;
-        ResTable* sharedRes = NULL;
-        bool shared = true;
-        const asset_path& ap = mAssetPaths.itemAt(i);
-        MY_TRACE_BEGIN(ap.path.string());
-        Asset* idmap = openIdmapLocked(ap);
-        ALOGV("Looking for resource asset in '%s'\n", ap.path.string());
-        if (ap.type != kFileTypeDirectory) {
-            if (i == 0) {
-                // The first item is typically the framework resources,
-                // which we want to avoid parsing every time.
-                sharedRes = const_cast<AssetManager*>(this)->
-                    mZipSet.getZipResourceTable(ap.path);
-            }
-            if (sharedRes == NULL) {
-                ass = const_cast<AssetManager*>(this)->
-                    mZipSet.getZipResourceTableAsset(ap.path);
-                if (ass == NULL) {
-                    ALOGV("loading resource table %s\n", ap.path.string());
-                    ass = const_cast<AssetManager*>(this)->
-                        openNonAssetInPathLocked("resources.arsc",
-                                                 Asset::ACCESS_BUFFER,
-                                                 ap);
-                    if (ass != NULL && ass != kExcludedAsset) {
-                        ass = const_cast<AssetManager*>(this)->
-                            mZipSet.setZipResourceTableAsset(ap.path, ass);
-                    }
-                }
-                
-                if (i == 0 && ass != NULL) {
-                    // If this is the first resource table in the asset
-                    // manager, then we are going to cache it so that we
-                    // can quickly copy it out for others.
-                    ALOGV("Creating shared resources for %s", ap.path.string());
-                    sharedRes = new ResTable();
-                    sharedRes->add(ass, (void*)(i+1), false, idmap);
-                    sharedRes = const_cast<AssetManager*>(this)->
-                        mZipSet.setZipResourceTable(ap.path, sharedRes);
-                }
-            }
-        } else {
-            ALOGV("loading resource table %s\n", ap.path.string());
-            Asset* ass = const_cast<AssetManager*>(this)->
-                openNonAssetInPathLocked("resources.arsc",
-                                         Asset::ACCESS_BUFFER,
-                                         ap);
-            shared = false;
-        }
-        if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) {
-            if (rt == NULL) {
-                mResources = rt = new ResTable();
-                updateResourceParamsLocked();
-            }
-            ALOGV("Installing resource asset %p in to table %p\n", ass, mResources);
-            if (sharedRes != NULL) {
-                ALOGV("Copying existing resources for %s", ap.path.string());
-                rt->add(sharedRes);
-            } else {
-                ALOGV("Parsing resources for %s", ap.path.string());
-                rt->add(ass, (void*)(i+1), !shared, idmap);
-            }
-
-            if (!shared) {
-                delete ass;
-            }
-        }
-        if (idmap != NULL) {
-            delete idmap;
-        }
-        MY_TRACE_END();
-    }
-
-    if (required && !rt) ALOGW("Unable to find resources file resources.arsc");
-    if (!rt) {
-        mResources = rt = new ResTable();
-    }
-    return rt;
-}
-
-void AssetManager::updateResourceParamsLocked() const
-{
-    ResTable* res = mResources;
-    if (!res) {
-        return;
-    }
-
-    size_t llen = mLocale ? strlen(mLocale) : 0;
-    mConfig->language[0] = 0;
-    mConfig->language[1] = 0;
-    mConfig->country[0] = 0;
-    mConfig->country[1] = 0;
-    if (llen >= 2) {
-        mConfig->language[0] = mLocale[0];
-        mConfig->language[1] = mLocale[1];
-    }
-    if (llen >= 5) {
-        mConfig->country[0] = mLocale[3];
-        mConfig->country[1] = mLocale[4];
-    }
-    mConfig->size = sizeof(*mConfig);
-
-    res->setParameters(mConfig);
-}
-
-Asset* AssetManager::openIdmapLocked(const struct asset_path& ap) const
-{
-    Asset* ass = NULL;
-    if (ap.idmap.size() != 0) {
-        ass = const_cast<AssetManager*>(this)->
-            openAssetFromFileLocked(ap.idmap, Asset::ACCESS_BUFFER);
-        if (ass) {
-            ALOGV("loading idmap %s\n", ap.idmap.string());
-        } else {
-            ALOGW("failed to load idmap %s\n", ap.idmap.string());
-        }
-    }
-    return ass;
-}
-
-const ResTable& AssetManager::getResources(bool required) const
-{
-    const ResTable* rt = getResTable(required);
-    return *rt;
-}
-
-bool AssetManager::isUpToDate()
-{
-    AutoMutex _l(mLock);
-    return mZipSet.isUpToDate();
-}
-
-void AssetManager::getLocales(Vector<String8>* locales) const
-{
-    ResTable* res = mResources;
-    if (res != NULL) {
-        res->getLocales(locales);
-    }
-}
-
-/*
- * Open a non-asset file as if it were an asset, searching for it in the
- * specified app.
- *
- * Pass in a NULL values for "appName" if the common app directory should
- * be used.
- */
-Asset* AssetManager::openNonAssetInPathLocked(const char* fileName, AccessMode mode,
-    const asset_path& ap)
-{
-    Asset* pAsset = NULL;
-
-    /* look at the filesystem on disk */
-    if (ap.type == kFileTypeDirectory) {
-        String8 path(ap.path);
-        path.appendPath(fileName);
-
-        pAsset = openAssetFromFileLocked(path, mode);
-
-        if (pAsset == NULL) {
-            /* try again, this time with ".gz" */
-            path.append(".gz");
-            pAsset = openAssetFromFileLocked(path, mode);
-        }
-
-        if (pAsset != NULL) {
-            //printf("FOUND NA '%s' on disk\n", fileName);
-            pAsset->setAssetSource(path);
-        }
-
-    /* look inside the zip file */
-    } else {
-        String8 path(fileName);
-
-        /* check the appropriate Zip file */
-        ZipFileRO* pZip;
-        ZipEntryRO entry;
-
-        pZip = getZipFileLocked(ap);
-        if (pZip != NULL) {
-            //printf("GOT zip, checking NA '%s'\n", (const char*) path);
-            entry = pZip->findEntryByName(path.string());
-            if (entry != NULL) {
-                //printf("FOUND NA in Zip file for %s\n", appName ? appName : kAppCommon);
-                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
-            }
-        }
-
-        if (pAsset != NULL) {
-            /* create a "source" name, for debug/display */
-            pAsset->setAssetSource(
-                    createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()), String8(""),
-                                                String8(fileName)));
-        }
-    }
-
-    return pAsset;
-}
-
-/*
- * Open an asset, searching for it in the directory hierarchy for the
- * specified app.
- *
- * Pass in a NULL values for "appName" if the common app directory should
- * be used.
- */
-Asset* AssetManager::openInPathLocked(const char* fileName, AccessMode mode,
-    const asset_path& ap)
-{
-    Asset* pAsset = NULL;
-
-    /*
-     * Try various combinations of locale and vendor.
-     */
-    if (mLocale != NULL && mVendor != NULL)
-        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, mVendor);
-    if (pAsset == NULL && mVendor != NULL)
-        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, mVendor);
-    if (pAsset == NULL && mLocale != NULL)
-        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, NULL);
-    if (pAsset == NULL)
-        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, NULL);
-
-    return pAsset;
-}
-
-/*
- * Open an asset, searching for it in the directory hierarchy for the
- * specified locale and vendor.
- *
- * We also search in "app.jar".
- *
- * Pass in NULL values for "appName", "locale", and "vendor" if the
- * defaults should be used.
- */
-Asset* AssetManager::openInLocaleVendorLocked(const char* fileName, AccessMode mode,
-    const asset_path& ap, const char* locale, const char* vendor)
-{
-    Asset* pAsset = NULL;
-
-    if (ap.type == kFileTypeDirectory) {
-        if (mCacheMode == CACHE_OFF) {
-            /* look at the filesystem on disk */
-            String8 path(createPathNameLocked(ap, locale, vendor));
-            path.appendPath(fileName);
-    
-            String8 excludeName(path);
-            excludeName.append(kExcludeExtension);
-            if (::getFileType(excludeName.string()) != kFileTypeNonexistent) {
-                /* say no more */
-                //printf("+++ excluding '%s'\n", (const char*) excludeName);
-                return kExcludedAsset;
-            }
-    
-            pAsset = openAssetFromFileLocked(path, mode);
-    
-            if (pAsset == NULL) {
-                /* try again, this time with ".gz" */
-                path.append(".gz");
-                pAsset = openAssetFromFileLocked(path, mode);
-            }
-    
-            if (pAsset != NULL)
-                pAsset->setAssetSource(path);
-        } else {
-            /* find in cache */
-            String8 path(createPathNameLocked(ap, locale, vendor));
-            path.appendPath(fileName);
-    
-            AssetDir::FileInfo tmpInfo;
-            bool found = false;
-    
-            String8 excludeName(path);
-            excludeName.append(kExcludeExtension);
-    
-            if (mCache.indexOf(excludeName) != NAME_NOT_FOUND) {
-                /* go no farther */
-                //printf("+++ Excluding '%s'\n", (const char*) excludeName);
-                return kExcludedAsset;
-            }
-
-            /*
-             * File compression extensions (".gz") don't get stored in the
-             * name cache, so we have to try both here.
-             */
-            if (mCache.indexOf(path) != NAME_NOT_FOUND) {
-                found = true;
-                pAsset = openAssetFromFileLocked(path, mode);
-                if (pAsset == NULL) {
-                    /* try again, this time with ".gz" */
-                    path.append(".gz");
-                    pAsset = openAssetFromFileLocked(path, mode);
-                }
-            }
-
-            if (pAsset != NULL)
-                pAsset->setAssetSource(path);
-
-            /*
-             * Don't continue the search into the Zip files.  Our cached info
-             * said it was a file on disk; to be consistent with openDir()
-             * we want to return the loose asset.  If the cached file gets
-             * removed, we fail.
-             *
-             * The alternative is to update our cache when files get deleted,
-             * or make some sort of "best effort" promise, but for now I'm
-             * taking the hard line.
-             */
-            if (found) {
-                if (pAsset == NULL)
-                    ALOGD("Expected file not found: '%s'\n", path.string());
-                return pAsset;
-            }
-        }
-    }
-
-    /*
-     * Either it wasn't found on disk or on the cached view of the disk.
-     * Dig through the currently-opened set of Zip files.  If caching
-     * is disabled, the Zip file may get reopened.
-     */
-    if (pAsset == NULL && ap.type == kFileTypeRegular) {
-        String8 path;
-
-        path.appendPath((locale != NULL) ? locale : kDefaultLocale);
-        path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);
-        path.appendPath(fileName);
-
-        /* check the appropriate Zip file */
-        ZipFileRO* pZip;
-        ZipEntryRO entry;
-
-        pZip = getZipFileLocked(ap);
-        if (pZip != NULL) {
-            //printf("GOT zip, checking '%s'\n", (const char*) path);
-            entry = pZip->findEntryByName(path.string());
-            if (entry != NULL) {
-                //printf("FOUND in Zip file for %s/%s-%s\n",
-                //    appName, locale, vendor);
-                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
-            }
-        }
-
-        if (pAsset != NULL) {
-            /* create a "source" name, for debug/display */
-            pAsset->setAssetSource(createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()),
-                                                             String8(""), String8(fileName)));
-        }
-    }
-
-    return pAsset;
-}
-
-/*
- * Create a "source name" for a file from a Zip archive.
- */
-String8 AssetManager::createZipSourceNameLocked(const String8& zipFileName,
-    const String8& dirName, const String8& fileName)
-{
-    String8 sourceName("zip:");
-    sourceName.append(zipFileName);
-    sourceName.append(":");
-    if (dirName.length() > 0) {
-        sourceName.appendPath(dirName);
-    }
-    sourceName.appendPath(fileName);
-    return sourceName;
-}
-
-/*
- * Create a path to a loose asset (asset-base/app/locale/vendor).
- */
-String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* locale,
-    const char* vendor)
-{
-    String8 path(ap.path);
-    path.appendPath((locale != NULL) ? locale : kDefaultLocale);
-    path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);
-    return path;
-}
-
-/*
- * Create a path to a loose asset (asset-base/app/rootDir).
- */
-String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* rootDir)
-{
-    String8 path(ap.path);
-    if (rootDir != NULL) path.appendPath(rootDir);
-    return path;
-}
-
-/*
- * Return a pointer to one of our open Zip archives.  Returns NULL if no
- * matching Zip file exists.
- *
- * Right now we have 2 possible Zip files (1 each in app/"common").
- *
- * If caching is set to CACHE_OFF, to get the expected behavior we
- * need to reopen the Zip file on every request.  That would be silly
- * and expensive, so instead we just check the file modification date.
- *
- * Pass in NULL values for "appName", "locale", and "vendor" if the
- * generics should be used.
- */
-ZipFileRO* AssetManager::getZipFileLocked(const asset_path& ap)
-{
-    ALOGV("getZipFileLocked() in %p\n", this);
-
-    return mZipSet.getZip(ap.path);
-}
-
-/*
- * Try to open an asset from a file on disk.
- *
- * If the file is compressed with gzip, we seek to the start of the
- * deflated data and pass that in (just like we would for a Zip archive).
- *
- * For uncompressed data, we may already have an mmap()ed version sitting
- * around.  If so, we want to hand that to the Asset instead.
- *
- * This returns NULL if the file doesn't exist, couldn't be opened, or
- * claims to be a ".gz" but isn't.
- */
-Asset* AssetManager::openAssetFromFileLocked(const String8& pathName,
-    AccessMode mode)
-{
-    Asset* pAsset = NULL;
-
-    if (strcasecmp(pathName.getPathExtension().string(), ".gz") == 0) {
-        //printf("TRYING '%s'\n", (const char*) pathName);
-        pAsset = Asset::createFromCompressedFile(pathName.string(), mode);
-    } else {
-        //printf("TRYING '%s'\n", (const char*) pathName);
-        pAsset = Asset::createFromFile(pathName.string(), mode);
-    }
-
-    return pAsset;
-}
-
-/*
- * Given an entry in a Zip archive, create a new Asset object.
- *
- * If the entry is uncompressed, we may want to create or share a
- * slice of shared memory.
- */
-Asset* AssetManager::openAssetFromZipLocked(const ZipFileRO* pZipFile,
-    const ZipEntryRO entry, AccessMode mode, const String8& entryName)
-{
-    Asset* pAsset = NULL;
-
-    // TODO: look for previously-created shared memory slice?
-    int method;
-    size_t uncompressedLen;
-
-    //printf("USING Zip '%s'\n", pEntry->getFileName());
-
-    //pZipFile->getEntryInfo(entry, &method, &uncompressedLen, &compressedLen,
-    //    &offset);
-    if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL,
-            NULL, NULL))
-    {
-        ALOGW("getEntryInfo failed\n");
-        return NULL;
-    }
-
-    FileMap* dataMap = pZipFile->createEntryFileMap(entry);
-    if (dataMap == NULL) {
-        ALOGW("create map from entry failed\n");
-        return NULL;
-    }
-
-    if (method == ZipFileRO::kCompressStored) {
-        pAsset = Asset::createFromUncompressedMap(dataMap, mode);
-        ALOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.string(),
-                dataMap->getFileName(), mode, pAsset);
-    } else {
-        pAsset = Asset::createFromCompressedMap(dataMap, method,
-            uncompressedLen, mode);
-        ALOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.string(),
-                dataMap->getFileName(), mode, pAsset);
-    }
-    if (pAsset == NULL) {
-        /* unexpected */
-        ALOGW("create from segment failed\n");
-    }
-
-    return pAsset;
-}
-
-
-
-/*
- * Open a directory in the asset namespace.
- *
- * An "asset directory" is simply the combination of all files in all
- * locations, with ".gz" stripped for loose files.  With app, locale, and
- * vendor defined, we have 8 directories and 2 Zip archives to scan.
- *
- * Pass in "" for the root dir.
- */
-AssetDir* AssetManager::openDir(const char* dirName)
-{
-    AutoMutex _l(mLock);
-
-    AssetDir* pDir = NULL;
-    SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;
-
-    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-    assert(dirName != NULL);
-
-    //printf("+++ openDir(%s) in '%s'\n", dirName, (const char*) mAssetBase);
-
-    if (mCacheMode != CACHE_OFF && !mCacheValid)
-        loadFileNameCacheLocked();
-
-    pDir = new AssetDir;
-
-    /*
-     * Scan the various directories, merging what we find into a single
-     * vector.  We want to scan them in reverse priority order so that
-     * the ".EXCLUDE" processing works correctly.  Also, if we decide we
-     * want to remember where the file is coming from, we'll get the right
-     * version.
-     *
-     * We start with Zip archives, then do loose files.
-     */
-    pMergedInfo = new SortedVector<AssetDir::FileInfo>;
-
-    size_t i = mAssetPaths.size();
-    while (i > 0) {
-        i--;
-        const asset_path& ap = mAssetPaths.itemAt(i);
-        if (ap.type == kFileTypeRegular) {
-            ALOGV("Adding directory %s from zip %s", dirName, ap.path.string());
-            scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);
-        } else {
-            ALOGV("Adding directory %s from dir %s", dirName, ap.path.string());
-            scanAndMergeDirLocked(pMergedInfo, ap, kAssetsRoot, dirName);
-        }
-    }
-
-#if 0
-    printf("FILE LIST:\n");
-    for (i = 0; i < (size_t) pMergedInfo->size(); i++) {
-        printf(" %d: (%d) '%s'\n", i,
-            pMergedInfo->itemAt(i).getFileType(),
-            (const char*) pMergedInfo->itemAt(i).getFileName());
-    }
-#endif
-
-    pDir->setFileList(pMergedInfo);
-    return pDir;
-}
-
-/*
- * Open a directory in the non-asset namespace.
- *
- * An "asset directory" is simply the combination of all files in all
- * locations, with ".gz" stripped for loose files.  With app, locale, and
- * vendor defined, we have 8 directories and 2 Zip archives to scan.
- *
- * Pass in "" for the root dir.
- */
-AssetDir* AssetManager::openNonAssetDir(void* cookie, const char* dirName)
-{
-    AutoMutex _l(mLock);
-
-    AssetDir* pDir = NULL;
-    SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;
-
-    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-    assert(dirName != NULL);
-
-    //printf("+++ openDir(%s) in '%s'\n", dirName, (const char*) mAssetBase);
-
-    if (mCacheMode != CACHE_OFF && !mCacheValid)
-        loadFileNameCacheLocked();
-
-    pDir = new AssetDir;
-
-    pMergedInfo = new SortedVector<AssetDir::FileInfo>;
-
-    const size_t which = ((size_t)cookie)-1;
-
-    if (which < mAssetPaths.size()) {
-        const asset_path& ap = mAssetPaths.itemAt(which);
-        if (ap.type == kFileTypeRegular) {
-            ALOGV("Adding directory %s from zip %s", dirName, ap.path.string());
-            scanAndMergeZipLocked(pMergedInfo, ap, NULL, dirName);
-        } else {
-            ALOGV("Adding directory %s from dir %s", dirName, ap.path.string());
-            scanAndMergeDirLocked(pMergedInfo, ap, NULL, dirName);
-        }
-    }
-
-#if 0
-    printf("FILE LIST:\n");
-    for (i = 0; i < (size_t) pMergedInfo->size(); i++) {
-        printf(" %d: (%d) '%s'\n", i,
-            pMergedInfo->itemAt(i).getFileType(),
-            (const char*) pMergedInfo->itemAt(i).getFileName());
-    }
-#endif
-
-    pDir->setFileList(pMergedInfo);
-    return pDir;
-}
-
-/*
- * Scan the contents of the specified directory and merge them into the
- * "pMergedInfo" vector, removing previous entries if we find "exclude"
- * directives.
- *
- * Returns "false" if we found nothing to contribute.
- */
-bool AssetManager::scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
-    const asset_path& ap, const char* rootDir, const char* dirName)
-{
-    SortedVector<AssetDir::FileInfo>* pContents;
-    String8 path;
-
-    assert(pMergedInfo != NULL);
-
-    //printf("scanAndMergeDir: %s %s %s %s\n", appName, locale, vendor,dirName);
-
-    if (mCacheValid) {
-        int i, start, count;
-
-        pContents = new SortedVector<AssetDir::FileInfo>;
-
-        /*
-         * Get the basic partial path and find it in the cache.  That's
-         * the start point for the search.
-         */
-        path = createPathNameLocked(ap, rootDir);
-        if (dirName[0] != '\0')
-            path.appendPath(dirName);
-
-        start = mCache.indexOf(path);
-        if (start == NAME_NOT_FOUND) {
-            //printf("+++ not found in cache: dir '%s'\n", (const char*) path);
-            delete pContents;
-            return false;
-        }
-
-        /*
-         * The match string looks like "common/default/default/foo/bar/".
-         * The '/' on the end ensures that we don't match on the directory
-         * itself or on ".../foo/barfy/".
-         */
-        path.append("/");
-
-        count = mCache.size();
-
-        /*
-         * Pick out the stuff in the current dir by examining the pathname.
-         * It needs to match the partial pathname prefix, and not have a '/'
-         * (fssep) anywhere after the prefix.
-         */
-        for (i = start+1; i < count; i++) {
-            if (mCache[i].getFileName().length() > path.length() &&
-                strncmp(mCache[i].getFileName().string(), path.string(), path.length()) == 0)
-            {
-                const char* name = mCache[i].getFileName().string();
-                // XXX THIS IS BROKEN!  Looks like we need to store the full
-                // path prefix separately from the file path.
-                if (strchr(name + path.length(), '/') == NULL) {
-                    /* grab it, reducing path to just the filename component */
-                    AssetDir::FileInfo tmp = mCache[i];
-                    tmp.setFileName(tmp.getFileName().getPathLeaf());
-                    pContents->add(tmp);
-                }
-            } else {
-                /* no longer in the dir or its subdirs */
-                break;
-            }
-
-        }
-    } else {
-        path = createPathNameLocked(ap, rootDir);
-        if (dirName[0] != '\0')
-            path.appendPath(dirName);
-        pContents = scanDirLocked(path);
-        if (pContents == NULL)
-            return false;
-    }
-
-    // if we wanted to do an incremental cache fill, we would do it here
-
-    /*
-     * Process "exclude" directives.  If we find a filename that ends with
-     * ".EXCLUDE", we look for a matching entry in the "merged" set, and
-     * remove it if we find it.  We also delete the "exclude" entry.
-     */
-    int i, count, exclExtLen;
-
-    count = pContents->size();
-    exclExtLen = strlen(kExcludeExtension);
-    for (i = 0; i < count; i++) {
-        const char* name;
-        int nameLen;
-
-        name = pContents->itemAt(i).getFileName().string();
-        nameLen = strlen(name);
-        if (nameLen > exclExtLen &&
-            strcmp(name + (nameLen - exclExtLen), kExcludeExtension) == 0)
-        {
-            String8 match(name, nameLen - exclExtLen);
-            int matchIdx;
-
-            matchIdx = AssetDir::FileInfo::findEntry(pMergedInfo, match);
-            if (matchIdx > 0) {
-                ALOGV("Excluding '%s' [%s]\n",
-                    pMergedInfo->itemAt(matchIdx).getFileName().string(),
-                    pMergedInfo->itemAt(matchIdx).getSourceName().string());
-                pMergedInfo->removeAt(matchIdx);
-            } else {
-                //printf("+++ no match on '%s'\n", (const char*) match);
-            }
-
-            ALOGD("HEY: size=%d removing %d\n", (int)pContents->size(), i);
-            pContents->removeAt(i);
-            i--;        // adjust "for" loop
-            count--;    //  and loop limit
-        }
-    }
-
-    mergeInfoLocked(pMergedInfo, pContents);
-
-    delete pContents;
-
-    return true;
-}
-
-/*
- * Scan the contents of the specified directory, and stuff what we find
- * into a newly-allocated vector.
- *
- * Files ending in ".gz" will have their extensions removed.
- *
- * We should probably think about skipping files with "illegal" names,
- * e.g. illegal characters (/\:) or excessive length.
- *
- * Returns NULL if the specified directory doesn't exist.
- */
-SortedVector<AssetDir::FileInfo>* AssetManager::scanDirLocked(const String8& path)
-{
-    SortedVector<AssetDir::FileInfo>* pContents = NULL;
-    DIR* dir;
-    struct dirent* entry;
-    FileType fileType;
-
-    ALOGV("Scanning dir '%s'\n", path.string());
-
-    dir = opendir(path.string());
-    if (dir == NULL)
-        return NULL;
-
-    pContents = new SortedVector<AssetDir::FileInfo>;
-
-    while (1) {
-        entry = readdir(dir);
-        if (entry == NULL)
-            break;
-
-        if (strcmp(entry->d_name, ".") == 0 ||
-            strcmp(entry->d_name, "..") == 0)
-            continue;
-
-#ifdef _DIRENT_HAVE_D_TYPE
-        if (entry->d_type == DT_REG)
-            fileType = kFileTypeRegular;
-        else if (entry->d_type == DT_DIR)
-            fileType = kFileTypeDirectory;
-        else
-            fileType = kFileTypeUnknown;
-#else
-        // stat the file
-        fileType = ::getFileType(path.appendPathCopy(entry->d_name).string());
-#endif
-
-        if (fileType != kFileTypeRegular && fileType != kFileTypeDirectory)
-            continue;
-
-        AssetDir::FileInfo info;
-        info.set(String8(entry->d_name), fileType);
-        if (strcasecmp(info.getFileName().getPathExtension().string(), ".gz") == 0)
-            info.setFileName(info.getFileName().getBasePath());
-        info.setSourceName(path.appendPathCopy(info.getFileName()));
-        pContents->add(info);
-    }
-
-    closedir(dir);
-    return pContents;
-}
-
-/*
- * Scan the contents out of the specified Zip archive, and merge what we
- * find into "pMergedInfo".  If the Zip archive in question doesn't exist,
- * we return immediately.
- *
- * Returns "false" if we found nothing to contribute.
- */
-bool AssetManager::scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
-    const asset_path& ap, const char* rootDir, const char* baseDirName)
-{
-    ZipFileRO* pZip;
-    Vector<String8> dirs;
-    AssetDir::FileInfo info;
-    SortedVector<AssetDir::FileInfo> contents;
-    String8 sourceName, zipName, dirName;
-
-    pZip = mZipSet.getZip(ap.path);
-    if (pZip == NULL) {
-        ALOGW("Failure opening zip %s\n", ap.path.string());
-        return false;
-    }
-
-    zipName = ZipSet::getPathName(ap.path.string());
-
-    /* convert "sounds" to "rootDir/sounds" */
-    if (rootDir != NULL) dirName = rootDir;
-    dirName.appendPath(baseDirName);
-
-    /*
-     * Scan through the list of files, looking for a match.  The files in
-     * the Zip table of contents are not in sorted order, so we have to
-     * process the entire list.  We're looking for a string that begins
-     * with the characters in "dirName", is followed by a '/', and has no
-     * subsequent '/' in the stuff that follows.
-     *
-     * What makes this especially fun is that directories are not stored
-     * explicitly in Zip archives, so we have to infer them from context.
-     * When we see "sounds/foo.wav" we have to leave a note to ourselves
-     * to insert a directory called "sounds" into the list.  We store
-     * these in temporary vector so that we only return each one once.
-     *
-     * Name comparisons are case-sensitive to match UNIX filesystem
-     * semantics.
-     */
-    int dirNameLen = dirName.length();
-    for (int i = 0; i < pZip->getNumEntries(); i++) {
-        ZipEntryRO entry;
-        char nameBuf[256];
-
-        entry = pZip->findEntryByIndex(i);
-        if (pZip->getEntryFileName(entry, nameBuf, sizeof(nameBuf)) != 0) {
-            // TODO: fix this if we expect to have long names
-            ALOGE("ARGH: name too long?\n");
-            continue;
-        }
-        //printf("Comparing %s in %s?\n", nameBuf, dirName.string());
-        if (dirNameLen == 0 ||
-            (strncmp(nameBuf, dirName.string(), dirNameLen) == 0 &&
-             nameBuf[dirNameLen] == '/'))
-        {
-            const char* cp;
-            const char* nextSlash;
-
-            cp = nameBuf + dirNameLen;
-            if (dirNameLen != 0)
-                cp++;       // advance past the '/'
-
-            nextSlash = strchr(cp, '/');
-//xxx this may break if there are bare directory entries
-            if (nextSlash == NULL) {
-                /* this is a file in the requested directory */
-
-                info.set(String8(nameBuf).getPathLeaf(), kFileTypeRegular);
-
-                info.setSourceName(
-                    createZipSourceNameLocked(zipName, dirName, info.getFileName()));
-
-                contents.add(info);
-                //printf("FOUND: file '%s'\n", info.getFileName().string());
-            } else {
-                /* this is a subdir; add it if we don't already have it*/
-                String8 subdirName(cp, nextSlash - cp);
-                size_t j;
-                size_t N = dirs.size();
-
-                for (j = 0; j < N; j++) {
-                    if (subdirName == dirs[j]) {
-                        break;
-                    }
-                }
-                if (j == N) {
-                    dirs.add(subdirName);
-                }
-
-                //printf("FOUND: dir '%s'\n", subdirName.string());
-            }
-        }
-    }
-
-    /*
-     * Add the set of unique directories.
-     */
-    for (int i = 0; i < (int) dirs.size(); i++) {
-        info.set(dirs[i], kFileTypeDirectory);
-        info.setSourceName(
-            createZipSourceNameLocked(zipName, dirName, info.getFileName()));
-        contents.add(info);
-    }
-
-    mergeInfoLocked(pMergedInfo, &contents);
-
-    return true;
-}
-
-
-/*
- * Merge two vectors of FileInfo.
- *
- * The merged contents will be stuffed into *pMergedInfo.
- *
- * If an entry for a file exists in both "pMergedInfo" and "pContents",
- * we use the newer "pContents" entry.
- */
-void AssetManager::mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
-    const SortedVector<AssetDir::FileInfo>* pContents)
-{
-    /*
-     * Merge what we found in this directory with what we found in
-     * other places.
-     *
-     * Two basic approaches:
-     * (1) Create a new array that holds the unique values of the two
-     *     arrays.
-     * (2) Take the elements from pContents and shove them into pMergedInfo.
-     *
-     * Because these are vectors of complex objects, moving elements around
-     * inside the vector requires constructing new objects and allocating
-     * storage for members.  With approach #1, we're always adding to the
-     * end, whereas with #2 we could be inserting multiple elements at the
-     * front of the vector.  Approach #1 requires a full copy of the
-     * contents of pMergedInfo, but approach #2 requires the same copy for
-     * every insertion at the front of pMergedInfo.
-     *
-     * (We should probably use a SortedVector interface that allows us to
-     * just stuff items in, trusting us to maintain the sort order.)
-     */
-    SortedVector<AssetDir::FileInfo>* pNewSorted;
-    int mergeMax, contMax;
-    int mergeIdx, contIdx;
-
-    pNewSorted = new SortedVector<AssetDir::FileInfo>;
-    mergeMax = pMergedInfo->size();
-    contMax = pContents->size();
-    mergeIdx = contIdx = 0;
-
-    while (mergeIdx < mergeMax || contIdx < contMax) {
-        if (mergeIdx == mergeMax) {
-            /* hit end of "merge" list, copy rest of "contents" */
-            pNewSorted->add(pContents->itemAt(contIdx));
-            contIdx++;
-        } else if (contIdx == contMax) {
-            /* hit end of "cont" list, copy rest of "merge" */
-            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));
-            mergeIdx++;
-        } else if (pMergedInfo->itemAt(mergeIdx) == pContents->itemAt(contIdx))
-        {
-            /* items are identical, add newer and advance both indices */
-            pNewSorted->add(pContents->itemAt(contIdx));
-            mergeIdx++;
-            contIdx++;
-        } else if (pMergedInfo->itemAt(mergeIdx) < pContents->itemAt(contIdx))
-        {
-            /* "merge" is lower, add that one */
-            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));
-            mergeIdx++;
-        } else {
-            /* "cont" is lower, add that one */
-            assert(pContents->itemAt(contIdx) < pMergedInfo->itemAt(mergeIdx));
-            pNewSorted->add(pContents->itemAt(contIdx));
-            contIdx++;
-        }
-    }
-
-    /*
-     * Overwrite the "merged" list with the new stuff.
-     */
-    *pMergedInfo = *pNewSorted;
-    delete pNewSorted;
-
-#if 0       // for Vector, rather than SortedVector
-    int i, j;
-    for (i = pContents->size() -1; i >= 0; i--) {
-        bool add = true;
-
-        for (j = pMergedInfo->size() -1; j >= 0; j--) {
-            /* case-sensitive comparisons, to behave like UNIX fs */
-            if (strcmp(pContents->itemAt(i).mFileName,
-                       pMergedInfo->itemAt(j).mFileName) == 0)
-            {
-                /* match, don't add this entry */
-                add = false;
-                break;
-            }
-        }
-
-        if (add)
-            pMergedInfo->add(pContents->itemAt(i));
-    }
-#endif
-}
-
-
-/*
- * Load all files into the file name cache.  We want to do this across
- * all combinations of { appname, locale, vendor }, performing a recursive
- * directory traversal.
- *
- * This is not the most efficient data structure.  Also, gathering the
- * information as we needed it (file-by-file or directory-by-directory)
- * would be faster.  However, on the actual device, 99% of the files will
- * live in Zip archives, so this list will be very small.  The trouble
- * is that we have to check the "loose" files first, so it's important
- * that we don't beat the filesystem silly looking for files that aren't
- * there.
- *
- * Note on thread safety: this is the only function that causes updates
- * to mCache, and anybody who tries to use it will call here if !mCacheValid,
- * so we need to employ a mutex here.
- */
-void AssetManager::loadFileNameCacheLocked(void)
-{
-    assert(!mCacheValid);
-    assert(mCache.size() == 0);
-
-#ifdef DO_TIMINGS   // need to link against -lrt for this now
-    DurationTimer timer;
-    timer.start();
-#endif
-
-    fncScanLocked(&mCache, "");
-
-#ifdef DO_TIMINGS
-    timer.stop();
-    ALOGD("Cache scan took %.3fms\n",
-        timer.durationUsecs() / 1000.0);
-#endif
-
-#if 0
-    int i;
-    printf("CACHED FILE LIST (%d entries):\n", mCache.size());
-    for (i = 0; i < (int) mCache.size(); i++) {
-        printf(" %d: (%d) '%s'\n", i,
-            mCache.itemAt(i).getFileType(),
-            (const char*) mCache.itemAt(i).getFileName());
-    }
-#endif
-
-    mCacheValid = true;
-}
-
-/*
- * Scan up to 8 versions of the specified directory.
- */
-void AssetManager::fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
-    const char* dirName)
-{
-    size_t i = mAssetPaths.size();
-    while (i > 0) {
-        i--;
-        const asset_path& ap = mAssetPaths.itemAt(i);
-        fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, NULL, dirName);
-        if (mLocale != NULL)
-            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, NULL, dirName);
-        if (mVendor != NULL)
-            fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, mVendor, dirName);
-        if (mLocale != NULL && mVendor != NULL)
-            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, mVendor, dirName);
-    }
-}
-
-/*
- * Recursively scan this directory and all subdirs.
- *
- * This is similar to scanAndMergeDir, but we don't remove the .EXCLUDE
- * files, and we prepend the extended partial path to the filenames.
- */
-bool AssetManager::fncScanAndMergeDirLocked(
-    SortedVector<AssetDir::FileInfo>* pMergedInfo,
-    const asset_path& ap, const char* locale, const char* vendor,
-    const char* dirName)
-{
-    SortedVector<AssetDir::FileInfo>* pContents;
-    String8 partialPath;
-    String8 fullPath;
-
-    // XXX This is broken -- the filename cache needs to hold the base
-    // asset path separately from its filename.
-    
-    partialPath = createPathNameLocked(ap, locale, vendor);
-    if (dirName[0] != '\0') {
-        partialPath.appendPath(dirName);
-    }
-
-    fullPath = partialPath;
-    pContents = scanDirLocked(fullPath);
-    if (pContents == NULL) {
-        return false;       // directory did not exist
-    }
-
-    /*
-     * Scan all subdirectories of the current dir, merging what we find
-     * into "pMergedInfo".
-     */
-    for (int i = 0; i < (int) pContents->size(); i++) {
-        if (pContents->itemAt(i).getFileType() == kFileTypeDirectory) {
-            String8 subdir(dirName);
-            subdir.appendPath(pContents->itemAt(i).getFileName());
-
-            fncScanAndMergeDirLocked(pMergedInfo, ap, locale, vendor, subdir.string());
-        }
-    }
-
-    /*
-     * To be consistent, we want entries for the root directory.  If
-     * we're the root, add one now.
-     */
-    if (dirName[0] == '\0') {
-        AssetDir::FileInfo tmpInfo;
-
-        tmpInfo.set(String8(""), kFileTypeDirectory);
-        tmpInfo.setSourceName(createPathNameLocked(ap, locale, vendor));
-        pContents->add(tmpInfo);
-    }
-
-    /*
-     * We want to prepend the extended partial path to every entry in
-     * "pContents".  It's the same value for each entry, so this will
-     * not change the sorting order of the vector contents.
-     */
-    for (int i = 0; i < (int) pContents->size(); i++) {
-        const AssetDir::FileInfo& info = pContents->itemAt(i);
-        pContents->editItemAt(i).setFileName(partialPath.appendPathCopy(info.getFileName()));
-    }
-
-    mergeInfoLocked(pMergedInfo, pContents);
-    return true;
-}
-
-/*
- * Trash the cache.
- */
-void AssetManager::purgeFileNameCacheLocked(void)
-{
-    mCacheValid = false;
-    mCache.clear();
-}
-
-/*
- * ===========================================================================
- *      AssetManager::SharedZip
- * ===========================================================================
- */
-
-
-Mutex AssetManager::SharedZip::gLock;
-DefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen;
-
-AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen)
-    : mPath(path), mZipFile(NULL), mModWhen(modWhen),
-      mResourceTableAsset(NULL), mResourceTable(NULL)
-{
-    //ALOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
-    mZipFile = new ZipFileRO;
-    ALOGV("+++ opening zip '%s'\n", mPath.string());
-    if (mZipFile->open(mPath.string()) != NO_ERROR) {
-        ALOGD("failed to open Zip archive '%s'\n", mPath.string());
-        delete mZipFile;
-        mZipFile = NULL;
-    }
-}
-
-sp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path)
-{
-    AutoMutex _l(gLock);
-    time_t modWhen = getFileModDate(path);
-    sp<SharedZip> zip = gOpen.valueFor(path).promote();
-    if (zip != NULL && zip->mModWhen == modWhen) {
-        return zip;
-    }
-    zip = new SharedZip(path, modWhen);
-    gOpen.add(path, zip);
-    return zip;
-
-}
-
-ZipFileRO* AssetManager::SharedZip::getZip()
-{
-    return mZipFile;
-}
-
-Asset* AssetManager::SharedZip::getResourceTableAsset()
-{
-    ALOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset);
-    return mResourceTableAsset;
-}
-
-Asset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset)
-{
-    {
-        AutoMutex _l(gLock);
-        if (mResourceTableAsset == NULL) {
-            mResourceTableAsset = asset;
-            // This is not thread safe the first time it is called, so
-            // do it here with the global lock held.
-            asset->getBuffer(true);
-            return asset;
-        }
-    }
-    delete asset;
-    return mResourceTableAsset;
-}
-
-ResTable* AssetManager::SharedZip::getResourceTable()
-{
-    ALOGV("Getting from SharedZip %p resource table %p\n", this, mResourceTable);
-    return mResourceTable;
-}
-
-ResTable* AssetManager::SharedZip::setResourceTable(ResTable* res)
-{
-    {
-        AutoMutex _l(gLock);
-        if (mResourceTable == NULL) {
-            mResourceTable = res;
-            return res;
-        }
-    }
-    delete res;
-    return mResourceTable;
-}
-
-bool AssetManager::SharedZip::isUpToDate()
-{
-    time_t modWhen = getFileModDate(mPath.string());
-    return mModWhen == modWhen;
-}
-
-AssetManager::SharedZip::~SharedZip()
-{
-    //ALOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath);
-    if (mResourceTable != NULL) {
-        delete mResourceTable;
-    }
-    if (mResourceTableAsset != NULL) {
-        delete mResourceTableAsset;
-    }
-    if (mZipFile != NULL) {
-        delete mZipFile;
-        ALOGV("Closed '%s'\n", mPath.string());
-    }
-}
-
-/*
- * ===========================================================================
- *      AssetManager::ZipSet
- * ===========================================================================
- */
-
-/*
- * Constructor.
- */
-AssetManager::ZipSet::ZipSet(void)
-{
-}
-
-/*
- * Destructor.  Close any open archives.
- */
-AssetManager::ZipSet::~ZipSet(void)
-{
-    size_t N = mZipFile.size();
-    for (size_t i = 0; i < N; i++)
-        closeZip(i);
-}
-
-/*
- * Close a Zip file and reset the entry.
- */
-void AssetManager::ZipSet::closeZip(int idx)
-{
-    mZipFile.editItemAt(idx) = NULL;
-}
-
-
-/*
- * Retrieve the appropriate Zip file from the set.
- */
-ZipFileRO* AssetManager::ZipSet::getZip(const String8& path)
-{
-    int idx = getIndex(path);
-    sp<SharedZip> zip = mZipFile[idx];
-    if (zip == NULL) {
-        zip = SharedZip::get(path);
-        mZipFile.editItemAt(idx) = zip;
-    }
-    return zip->getZip();
-}
-
-Asset* AssetManager::ZipSet::getZipResourceTableAsset(const String8& path)
-{
-    int idx = getIndex(path);
-    sp<SharedZip> zip = mZipFile[idx];
-    if (zip == NULL) {
-        zip = SharedZip::get(path);
-        mZipFile.editItemAt(idx) = zip;
-    }
-    return zip->getResourceTableAsset();
-}
-
-Asset* AssetManager::ZipSet::setZipResourceTableAsset(const String8& path,
-                                                 Asset* asset)
-{
-    int idx = getIndex(path);
-    sp<SharedZip> zip = mZipFile[idx];
-    // doesn't make sense to call before previously accessing.
-    return zip->setResourceTableAsset(asset);
-}
-
-ResTable* AssetManager::ZipSet::getZipResourceTable(const String8& path)
-{
-    int idx = getIndex(path);
-    sp<SharedZip> zip = mZipFile[idx];
-    if (zip == NULL) {
-        zip = SharedZip::get(path);
-        mZipFile.editItemAt(idx) = zip;
-    }
-    return zip->getResourceTable();
-}
-
-ResTable* AssetManager::ZipSet::setZipResourceTable(const String8& path,
-                                                    ResTable* res)
-{
-    int idx = getIndex(path);
-    sp<SharedZip> zip = mZipFile[idx];
-    // doesn't make sense to call before previously accessing.
-    return zip->setResourceTable(res);
-}
-
-/*
- * Generate the partial pathname for the specified archive.  The caller
- * gets to prepend the asset root directory.
- *
- * Returns something like "common/en-US-noogle.jar".
- */
-/*static*/ String8 AssetManager::ZipSet::getPathName(const char* zipPath)
-{
-    return String8(zipPath);
-}
-
-bool AssetManager::ZipSet::isUpToDate()
-{
-    const size_t N = mZipFile.size();
-    for (size_t i=0; i<N; i++) {
-        if (mZipFile[i] != NULL && !mZipFile[i]->isUpToDate()) {
-            return false;
-        }
-    }
-    return true;
-}
-
-/*
- * Compute the zip file's index.
- *
- * "appName", "locale", and "vendor" should be set to NULL to indicate the
- * default directory.
- */
-int AssetManager::ZipSet::getIndex(const String8& zip) const
-{
-    const size_t N = mZipPath.size();
-    for (size_t i=0; i<N; i++) {
-        if (mZipPath[i] == zip) {
-            return i;
-        }
-    }
-
-    mZipPath.add(zip);
-    mZipFile.add(NULL);
-
-    return mZipPath.size()-1;
-}
diff --git a/libs/androidfw/BackupData.cpp b/libs/androidfw/BackupData.cpp
deleted file mode 100644
index 4e3b522..0000000
--- a/libs/androidfw/BackupData.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "backup_data"
-
-#include <androidfw/BackupHelpers.h>
-#include <utils/ByteOrder.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <cutils/log.h>
-
-namespace android {
-
-static const bool DEBUG = false;
-
-/*
- * File Format (v1):
- *
- * All ints are stored little-endian.
- *
- *  - An app_header_v1 struct.
- *  - The name of the package, utf-8, null terminated, padded to 4-byte boundary.
- *  - A sequence of zero or more key/value paires (entities), each with
- *      - A entity_header_v1 struct
- *      - The key, utf-8, null terminated, padded to 4-byte boundary.
- *      - The value, padded to 4 byte boundary
- */
-
-const static int ROUND_UP[4] = { 0, 3, 2, 1 };
-
-static inline size_t
-round_up(size_t n)
-{
-    return n + ROUND_UP[n % 4];
-}
-
-static inline size_t
-padding_extra(size_t n)
-{
-    return ROUND_UP[n % 4];
-}
-
-BackupDataWriter::BackupDataWriter(int fd)
-    :m_fd(fd),
-     m_status(NO_ERROR),
-     m_pos(0),
-     m_entityCount(0)
-{
-}
-
-BackupDataWriter::~BackupDataWriter()
-{
-}
-
-// Pad out anything they've previously written to the next 4 byte boundary.
-status_t
-BackupDataWriter::write_padding_for(int n)
-{
-    ssize_t amt;
-    ssize_t paddingSize;
-
-    paddingSize = padding_extra(n);
-    if (paddingSize > 0) {
-        uint32_t padding = 0xbcbcbcbc;
-        if (DEBUG) ALOGI("writing %d padding bytes for %d", paddingSize, n);
-        amt = write(m_fd, &padding, paddingSize);
-        if (amt != paddingSize) {
-            m_status = errno;
-            return m_status;
-        }
-        m_pos += amt;
-    }
-    return NO_ERROR;
-}
-
-status_t
-BackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)
-{
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-
-    ssize_t amt;
-
-    amt = write_padding_for(m_pos);
-    if (amt != 0) {
-        return amt;
-    }
-
-    String8 k;
-    if (m_keyPrefix.length() > 0) {
-        k = m_keyPrefix;
-        k += ":";
-        k += key;
-    } else {
-        k = key;
-    }
-    if (DEBUG) {
-        ALOGD("Writing header: prefix='%s' key='%s' dataSize=%d", m_keyPrefix.string(),
-                key.string(), dataSize);
-    }
-
-    entity_header_v1 header;
-    ssize_t keyLen;
-
-    keyLen = k.length();
-
-    header.type = tolel(BACKUP_HEADER_ENTITY_V1);
-    header.keyLen = tolel(keyLen);
-    header.dataSize = tolel(dataSize);
-
-    if (DEBUG) ALOGI("writing entity header, %d bytes", sizeof(entity_header_v1));
-    amt = write(m_fd, &header, sizeof(entity_header_v1));
-    if (amt != sizeof(entity_header_v1)) {
-        m_status = errno;
-        return m_status;
-    }
-    m_pos += amt;
-
-    if (DEBUG) ALOGI("writing entity header key, %d bytes", keyLen+1);
-    amt = write(m_fd, k.string(), keyLen+1);
-    if (amt != keyLen+1) {
-        m_status = errno;
-        return m_status;
-    }
-    m_pos += amt;
-
-    amt = write_padding_for(keyLen+1);
-
-    m_entityCount++;
-
-    return amt;
-}
-
-status_t
-BackupDataWriter::WriteEntityData(const void* data, size_t size)
-{
-    if (DEBUG) ALOGD("Writing data: size=%lu", (unsigned long) size);
-
-    if (m_status != NO_ERROR) {
-        if (DEBUG) {
-            ALOGD("Not writing data - stream in error state %d (%s)", m_status, strerror(m_status));
-        }
-        return m_status;
-    }
-
-    // We don't write padding here, because they're allowed to call this several
-    // times with smaller buffers.  We write it at the end of WriteEntityHeader
-    // instead.
-    ssize_t amt = write(m_fd, data, size);
-    if (amt != (ssize_t)size) {
-        m_status = errno;
-        if (DEBUG) ALOGD("write returned error %d (%s)", m_status, strerror(m_status));
-        return m_status;
-    }
-    m_pos += amt;
-    return NO_ERROR;
-}
-
-void
-BackupDataWriter::SetKeyPrefix(const String8& keyPrefix)
-{
-    m_keyPrefix = keyPrefix;
-}
-
-
-BackupDataReader::BackupDataReader(int fd)
-    :m_fd(fd),
-     m_done(false),
-     m_status(NO_ERROR),
-     m_pos(0),
-     m_entityCount(0)
-{
-    memset(&m_header, 0, sizeof(m_header));
-}
-
-BackupDataReader::~BackupDataReader()
-{
-}
-
-status_t
-BackupDataReader::Status()
-{
-    return m_status;
-}
-
-#define CHECK_SIZE(actual, expected) \
-    do { \
-        if ((actual) != (expected)) { \
-            if ((actual) == 0) { \
-                m_status = EIO; \
-                m_done = true; \
-            } else { \
-                m_status = errno; \
-                ALOGD("CHECK_SIZE(a=%ld e=%ld) failed at line %d m_status='%s'", \
-                    long(actual), long(expected), __LINE__, strerror(m_status)); \
-            } \
-            return m_status; \
-        } \
-    } while(0)
-#define SKIP_PADDING() \
-    do { \
-        status_t err = skip_padding(); \
-        if (err != NO_ERROR) { \
-            ALOGD("SKIP_PADDING FAILED at line %d", __LINE__); \
-            m_status = err; \
-            return err; \
-        } \
-    } while(0)
-
-status_t
-BackupDataReader::ReadNextHeader(bool* done, int* type)
-{
-    *done = m_done;
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-
-    int amt;
-
-    amt = skip_padding();
-    if (amt == EIO) {
-        *done = m_done = true;
-        return NO_ERROR;
-    }
-    else if (amt != NO_ERROR) {
-        return amt;
-    }
-    amt = read(m_fd, &m_header, sizeof(m_header));
-    *done = m_done = (amt == 0);
-    if (*done) {
-        return NO_ERROR;
-    }
-    CHECK_SIZE(amt, sizeof(m_header));
-    m_pos += sizeof(m_header);
-    if (type) {
-        *type = m_header.type;
-    }
-
-    // validate and fix up the fields.
-    m_header.type = fromlel(m_header.type);
-    switch (m_header.type)
-    {
-        case BACKUP_HEADER_ENTITY_V1:
-        {
-            m_header.entity.keyLen = fromlel(m_header.entity.keyLen);
-            if (m_header.entity.keyLen <= 0) {
-                ALOGD("Entity header at %d has keyLen<=0: 0x%08x\n", (int)m_pos,
-                        (int)m_header.entity.keyLen);
-                m_status = EINVAL;
-            }
-            m_header.entity.dataSize = fromlel(m_header.entity.dataSize);
-            m_entityCount++;
-
-            // read the rest of the header (filename)
-            size_t size = m_header.entity.keyLen;
-            char* buf = m_key.lockBuffer(size);
-            if (buf == NULL) {
-                m_status = ENOMEM;
-                return m_status;
-            }
-            int amt = read(m_fd, buf, size+1);
-            CHECK_SIZE(amt, (int)size+1);
-            m_key.unlockBuffer(size);
-            m_pos += size+1;
-            SKIP_PADDING();
-            m_dataEndPos = m_pos + m_header.entity.dataSize;
-
-            break;
-        }
-        default:
-            ALOGD("Chunk header at %d has invalid type: 0x%08x",
-                    (int)(m_pos - sizeof(m_header)), (int)m_header.type);
-            m_status = EINVAL;
-    }
-    
-    return m_status;
-}
-
-bool
-BackupDataReader::HasEntities()
-{
-    return m_status == NO_ERROR && m_header.type == BACKUP_HEADER_ENTITY_V1;
-}
-
-status_t
-BackupDataReader::ReadEntityHeader(String8* key, size_t* dataSize)
-{
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
-        return EINVAL;
-    }
-    *key = m_key;
-    *dataSize = m_header.entity.dataSize;
-    return NO_ERROR;
-}
-
-status_t
-BackupDataReader::SkipEntityData()
-{
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
-        return EINVAL;
-    }
-    if (m_header.entity.dataSize > 0) {
-        int pos = lseek(m_fd, m_dataEndPos, SEEK_SET);
-        if (pos == -1) {
-            return errno;
-        }
-        m_pos = pos;
-    }
-    SKIP_PADDING();
-    return NO_ERROR;
-}
-
-ssize_t
-BackupDataReader::ReadEntityData(void* data, size_t size)
-{
-    if (m_status != NO_ERROR) {
-        return -1;
-    }
-    int remaining = m_dataEndPos - m_pos;
-    //ALOGD("ReadEntityData size=%d m_pos=0x%x m_dataEndPos=0x%x remaining=%d\n",
-    //        size, m_pos, m_dataEndPos, remaining);
-    if (remaining <= 0) {
-        return 0;
-    }
-    if (((int)size) > remaining) {
-        size = remaining;
-    }
-    //ALOGD("   reading %d bytes", size);
-    int amt = read(m_fd, data, size);
-    if (amt < 0) {
-        m_status = errno;
-        return -1;
-    }
-    if (amt == 0) {
-        m_status = EIO;
-        m_done = true;
-    }
-    m_pos += amt;
-    return amt;
-}
-
-status_t
-BackupDataReader::skip_padding()
-{
-    ssize_t amt;
-    ssize_t paddingSize;
-
-    paddingSize = padding_extra(m_pos);
-    if (paddingSize > 0) {
-        uint32_t padding;
-        amt = read(m_fd, &padding, paddingSize);
-        CHECK_SIZE(amt, paddingSize);
-        m_pos += amt;
-    }
-    return NO_ERROR;
-}
-
-
-} // namespace android
diff --git a/libs/androidfw/BackupHelpers.cpp b/libs/androidfw/BackupHelpers.cpp
deleted file mode 100644
index b8d3f48..0000000
--- a/libs/androidfw/BackupHelpers.cpp
+++ /dev/null
@@ -1,1591 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "file_backup_helper"
-
-#include <androidfw/BackupHelpers.h>
-
-#include <utils/KeyedVector.h>
-#include <utils/ByteOrder.h>
-#include <utils/String8.h>
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/stat.h>
-#include <sys/time.h>  // for utimes
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <utime.h>
-#include <fcntl.h>
-#include <zlib.h>
-
-#include <cutils/log.h>
-
-namespace android {
-
-#define MAGIC0 0x70616e53 // Snap
-#define MAGIC1 0x656c6946 // File
-
-/*
- * File entity data format (v1):
- *
- *   - 4-byte version number of the metadata, little endian (0x00000001 for v1)
- *   - 12 bytes of metadata
- *   - the file data itself
- *
- * i.e. a 16-byte metadata header followed by the raw file data.  If the
- * restore code does not recognize the metadata version, it can still
- * interpret the file data itself correctly.
- *
- * file_metadata_v1:
- *
- *   - 4 byte version number === 0x00000001 (little endian)
- *   - 4-byte access mode (little-endian)
- *   - undefined (8 bytes)
- */
-
-struct file_metadata_v1 {
-    int version;
-    int mode;
-    int undefined_1;
-    int undefined_2;
-};
-
-const static int CURRENT_METADATA_VERSION = 1;
-
-#if 1
-#define LOGP(f, x...)
-#else
-#if TEST_BACKUP_HELPERS
-#define LOGP(f, x...) printf(f "\n", x)
-#else
-#define LOGP(x...) ALOGD(x)
-#endif
-#endif
-
-const static int ROUND_UP[4] = { 0, 3, 2, 1 };
-
-static inline int
-round_up(int n)
-{
-    return n + ROUND_UP[n % 4];
-}
-
-static int
-read_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot)
-{
-    int bytesRead = 0;
-    int amt;
-    SnapshotHeader header;
-
-    amt = read(fd, &header, sizeof(header));
-    if (amt != sizeof(header)) {
-        return errno;
-    }
-    bytesRead += amt;
-
-    if (header.magic0 != MAGIC0 || header.magic1 != MAGIC1) {
-        ALOGW("read_snapshot_file header.magic0=0x%08x magic1=0x%08x", header.magic0, header.magic1);
-        return 1;
-    }
-
-    for (int i=0; i<header.fileCount; i++) {
-        FileState file;
-        char filenameBuf[128];
-
-        amt = read(fd, &file, sizeof(FileState));
-        if (amt != sizeof(FileState)) {
-            ALOGW("read_snapshot_file FileState truncated/error with read at %d bytes\n", bytesRead);
-            return 1;
-        }
-        bytesRead += amt;
-
-        // filename is not NULL terminated, but it is padded
-        int nameBufSize = round_up(file.nameLen);
-        char* filename = nameBufSize <= (int)sizeof(filenameBuf)
-                ? filenameBuf
-                : (char*)malloc(nameBufSize);
-        amt = read(fd, filename, nameBufSize);
-        if (amt == nameBufSize) {
-            snapshot->add(String8(filename, file.nameLen), file);
-        }
-        bytesRead += amt;
-        if (filename != filenameBuf) {
-            free(filename);
-        }
-        if (amt != nameBufSize) {
-            ALOGW("read_snapshot_file filename truncated/error with read at %d bytes\n", bytesRead);
-            return 1;
-        }
-    }
-
-    if (header.totalSize != bytesRead) {
-        ALOGW("read_snapshot_file length mismatch: header.totalSize=%d bytesRead=%d\n",
-                header.totalSize, bytesRead);
-        return 1;
-    }
-
-    return 0;
-}
-
-static int
-write_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot)
-{
-    int fileCount = 0;
-    int bytesWritten = sizeof(SnapshotHeader);
-    // preflight size
-    const int N = snapshot.size();
-    for (int i=0; i<N; i++) {
-        const FileRec& g = snapshot.valueAt(i);
-        if (!g.deleted) {
-            const String8& name = snapshot.keyAt(i);
-            bytesWritten += sizeof(FileState) + round_up(name.length());
-            fileCount++;
-        }
-    }
-
-    LOGP("write_snapshot_file fd=%d\n", fd);
-
-    int amt;
-    SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten };
-
-    amt = write(fd, &header, sizeof(header));
-    if (amt != sizeof(header)) {
-        ALOGW("write_snapshot_file error writing header %s", strerror(errno));
-        return errno;
-    }
-
-    for (int i=0; i<N; i++) {
-        FileRec r = snapshot.valueAt(i);
-        if (!r.deleted) {
-            const String8& name = snapshot.keyAt(i);
-            int nameLen = r.s.nameLen = name.length();
-
-            amt = write(fd, &r.s, sizeof(FileState));
-            if (amt != sizeof(FileState)) {
-                ALOGW("write_snapshot_file error writing header %s", strerror(errno));
-                return 1;
-            }
-
-            // filename is not NULL terminated, but it is padded
-            amt = write(fd, name.string(), nameLen);
-            if (amt != nameLen) {
-                ALOGW("write_snapshot_file error writing filename %s", strerror(errno));
-                return 1;
-            }
-            int paddingLen = ROUND_UP[nameLen % 4];
-            if (paddingLen != 0) {
-                int padding = 0xabababab;
-                amt = write(fd, &padding, paddingLen);
-                if (amt != paddingLen) {
-                    ALOGW("write_snapshot_file error writing %d bytes of filename padding %s",
-                            paddingLen, strerror(errno));
-                    return 1;
-                }
-            }
-        }
-    }
-
-    return 0;
-}
-
-static int
-write_delete_file(BackupDataWriter* dataStream, const String8& key)
-{
-    LOGP("write_delete_file %s\n", key.string());
-    return dataStream->WriteEntityHeader(key, -1);
-}
-
-static int
-write_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8& key,
-        char const* realFilename)
-{
-    LOGP("write_update_file %s (%s) : mode 0%o\n", realFilename, key.string(), mode);
-
-    const int bufsize = 4*1024;
-    int err;
-    int amt;
-    int fileSize;
-    int bytesLeft;
-    file_metadata_v1 metadata;
-
-    char* buf = (char*)malloc(bufsize);
-    int crc = crc32(0L, Z_NULL, 0);
-
-
-    fileSize = lseek(fd, 0, SEEK_END);
-    lseek(fd, 0, SEEK_SET);
-
-    if (sizeof(metadata) != 16) {
-        ALOGE("ERROR: metadata block is the wrong size!");
-    }
-
-    bytesLeft = fileSize + sizeof(metadata);
-    err = dataStream->WriteEntityHeader(key, bytesLeft);
-    if (err != 0) {
-        free(buf);
-        return err;
-    }
-
-    // store the file metadata first
-    metadata.version = tolel(CURRENT_METADATA_VERSION);
-    metadata.mode = tolel(mode);
-    metadata.undefined_1 = metadata.undefined_2 = 0;
-    err = dataStream->WriteEntityData(&metadata, sizeof(metadata));
-    if (err != 0) {
-        free(buf);
-        return err;
-    }
-    bytesLeft -= sizeof(metadata); // bytesLeft should == fileSize now
-
-    // now store the file content
-    while ((amt = read(fd, buf, bufsize)) != 0 && bytesLeft > 0) {
-        bytesLeft -= amt;
-        if (bytesLeft < 0) {
-            amt += bytesLeft; // Plus a negative is minus.  Don't write more than we promised.
-        }
-        err = dataStream->WriteEntityData(buf, amt);
-        if (err != 0) {
-            free(buf);
-            return err;
-        }
-    }
-    if (bytesLeft != 0) {
-        if (bytesLeft > 0) {
-            // Pad out the space we promised in the buffer.  We can't corrupt the buffer,
-            // even though the data we're sending is probably bad.
-            memset(buf, 0, bufsize);
-            while (bytesLeft > 0) {
-                amt = bytesLeft < bufsize ? bytesLeft : bufsize;
-                bytesLeft -= amt;
-                err = dataStream->WriteEntityData(buf, amt);
-                if (err != 0) {
-                    free(buf);
-                    return err;
-                }
-            }
-        }
-        ALOGE("write_update_file size mismatch for %s. expected=%d actual=%d."
-                " You aren't doing proper locking!", realFilename, fileSize, fileSize-bytesLeft);
-    }
-
-    free(buf);
-    return NO_ERROR;
-}
-
-static int
-write_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)
-{
-    int err;
-    struct stat st;
-
-    err = stat(realFilename, &st);
-    if (err < 0) {
-        return errno;
-    }
-
-    int fd = open(realFilename, O_RDONLY);
-    if (fd == -1) {
-        return errno;
-    }
-
-    err = write_update_file(dataStream, fd, st.st_mode, key, realFilename);
-    close(fd);
-    return err;
-}
-
-static int
-compute_crc32(int fd)
-{
-    const int bufsize = 4*1024;
-    int amt;
-
-    char* buf = (char*)malloc(bufsize);
-    int crc = crc32(0L, Z_NULL, 0);
-
-    lseek(fd, 0, SEEK_SET);
-
-    while ((amt = read(fd, buf, bufsize)) != 0) {
-        crc = crc32(crc, (Bytef*)buf, amt);
-    }
-
-    free(buf);
-    return crc;
-}
-
-int
-back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
-        char const* const* files, char const* const* keys, int fileCount)
-{
-    int err;
-    KeyedVector<String8,FileState> oldSnapshot;
-    KeyedVector<String8,FileRec> newSnapshot;
-
-    if (oldSnapshotFD != -1) {
-        err = read_snapshot_file(oldSnapshotFD, &oldSnapshot);
-        if (err != 0) {
-            // On an error, treat this as a full backup.
-            oldSnapshot.clear();
-        }
-    }
-
-    for (int i=0; i<fileCount; i++) {
-        String8 key(keys[i]);
-        FileRec r;
-        char const* file = files[i];
-        r.file = file;
-        struct stat st;
-
-        err = stat(file, &st);
-        if (err != 0) {
-            r.deleted = true;
-        } else {
-            r.deleted = false;
-            r.s.modTime_sec = st.st_mtime;
-            r.s.modTime_nsec = 0; // workaround sim breakage
-            //r.s.modTime_nsec = st.st_mtime_nsec;
-            r.s.mode = st.st_mode;
-            r.s.size = st.st_size;
-            // we compute the crc32 later down below, when we already have the file open.
-
-            if (newSnapshot.indexOfKey(key) >= 0) {
-                LOGP("back_up_files key already in use '%s'", key.string());
-                return -1;
-            }
-        }
-        newSnapshot.add(key, r);
-    }
-
-    int n = 0;
-    int N = oldSnapshot.size();
-    int m = 0;
-
-    while (n<N && m<fileCount) {
-        const String8& p = oldSnapshot.keyAt(n);
-        const String8& q = newSnapshot.keyAt(m);
-        FileRec& g = newSnapshot.editValueAt(m);
-        int cmp = p.compare(q);
-        if (g.deleted || cmp < 0) {
-            // file removed
-            LOGP("file removed: %s", p.string());
-            g.deleted = true; // They didn't mention the file, but we noticed that it's gone.
-            dataStream->WriteEntityHeader(p, -1);
-            n++;
-        }
-        else if (cmp > 0) {
-            // file added
-            LOGP("file added: %s", g.file.string());
-            write_update_file(dataStream, q, g.file.string());
-            m++;
-        }
-        else {
-            // both files exist, check them
-            const FileState& f = oldSnapshot.valueAt(n);
-
-            int fd = open(g.file.string(), O_RDONLY);
-            if (fd < 0) {
-                // We can't open the file.  Don't report it as a delete either.  Let the
-                // server keep the old version.  Maybe they'll be able to deal with it
-                // on restore.
-                LOGP("Unable to open file %s - skipping", g.file.string());
-            } else {
-                g.s.crc32 = compute_crc32(fd);
-
-                LOGP("%s", q.string());
-                LOGP("  new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
-                        f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32);
-                LOGP("  old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
-                        g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);
-                if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
-                        || f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {
-                    write_update_file(dataStream, fd, g.s.mode, p, g.file.string());
-                }
-
-                close(fd);
-            }
-            n++;
-            m++;
-        }
-    }
-
-    // these were deleted
-    while (n<N) {
-        dataStream->WriteEntityHeader(oldSnapshot.keyAt(n), -1);
-        n++;
-    }
-
-    // these were added
-    while (m<fileCount) {
-        const String8& q = newSnapshot.keyAt(m);
-        FileRec& g = newSnapshot.editValueAt(m);
-        write_update_file(dataStream, q, g.file.string());
-        m++;
-    }
-
-    err = write_snapshot_file(newSnapshotFD, newSnapshot);
-
-    return 0;
-}
-
-// Utility function, equivalent to stpcpy(): perform a strcpy, but instead of
-// returning the initial dest, return a pointer to the trailing NUL.
-static char* strcpy_ptr(char* dest, const char* str) {
-    if (dest && str) {
-        while ((*dest = *str) != 0) {
-            dest++;
-            str++;
-        }
-    }
-    return dest;
-}
-
-static void calc_tar_checksum(char* buf) {
-    // [ 148 :   8 ] checksum -- to be calculated with this field as space chars
-    memset(buf + 148, ' ', 8);
-
-    uint16_t sum = 0;
-    for (uint8_t* p = (uint8_t*) buf; p < ((uint8_t*)buf) + 512; p++) {
-        sum += *p;
-    }
-
-    // Now write the real checksum value:
-    // [ 148 :   8 ]  checksum: 6 octal digits [leading zeroes], NUL, SPC
-    sprintf(buf + 148, "%06o", sum); // the trailing space is already in place
-}
-
-// Returns number of bytes written
-static int write_pax_header_entry(char* buf, const char* key, const char* value) {
-    // start with the size of "1 key=value\n"
-    int len = strlen(key) + strlen(value) + 4;
-    if (len > 9) len++;
-    if (len > 99) len++;
-    if (len > 999) len++;
-    // since PATH_MAX is 4096 we don't expect to have to generate any single
-    // header entry longer than 9999 characters
-
-    return sprintf(buf, "%d %s=%s\n", len, key, value);
-}
-
-// Wire format to the backup manager service is chunked:  each chunk is prefixed by
-// a 4-byte count of its size.  A chunk size of zero (four zero bytes) indicates EOD.
-void send_tarfile_chunk(BackupDataWriter* writer, const char* buffer, size_t size) {
-    uint32_t chunk_size_no = htonl(size);
-    writer->WriteEntityData(&chunk_size_no, 4);
-    if (size != 0) writer->WriteEntityData(buffer, size);
-}
-
-int write_tarfile(const String8& packageName, const String8& domain,
-        const String8& rootpath, const String8& filepath, BackupDataWriter* writer)
-{
-    // In the output stream everything is stored relative to the root
-    const char* relstart = filepath.string() + rootpath.length();
-    if (*relstart == '/') relstart++;     // won't be true when path == rootpath
-    String8 relpath(relstart);
-
-    // If relpath is empty, it means this is the top of one of the standard named
-    // domain directories, so we should just skip it
-    if (relpath.length() == 0) {
-        return 0;
-    }
-
-    // Too long a name for the ustar format?
-    //    "apps/" + packagename + '/' + domainpath < 155 chars
-    //    relpath < 100 chars
-    bool needExtended = false;
-    if ((5 + packageName.length() + 1 + domain.length() >= 155) || (relpath.length() >= 100)) {
-        needExtended = true;
-    }
-
-    // Non-7bit-clean path also means needing pax extended format
-    if (!needExtended) {
-        for (size_t i = 0; i < filepath.length(); i++) {
-            if ((filepath[i] & 0x80) != 0) {
-                needExtended = true;
-                break;
-            }
-        }
-    }
-
-    int err = 0;
-    struct stat64 s;
-    if (lstat64(filepath.string(), &s) != 0) {
-        err = errno;
-        ALOGE("Error %d (%s) from lstat64(%s)", err, strerror(err), filepath.string());
-        return err;
-    }
-
-    String8 fullname;   // for pax later on
-    String8 prefix;
-
-    const int isdir = S_ISDIR(s.st_mode);
-    if (isdir) s.st_size = 0;   // directories get no actual data in the tar stream
-
-    // !!! TODO: use mmap when possible to avoid churning the buffer cache
-    // !!! TODO: this will break with symlinks; need to use readlink(2)
-    int fd = open(filepath.string(), O_RDONLY);
-    if (fd < 0) {
-        err = errno;
-        ALOGE("Error %d (%s) from open(%s)", err, strerror(err), filepath.string());
-        return err;
-    }
-
-    // read/write up to this much at a time.
-    const size_t BUFSIZE = 32 * 1024;
-    char* buf = (char *)calloc(1,BUFSIZE);
-    char* paxHeader = buf + 512;    // use a different chunk of it as separate scratch
-    char* paxData = buf + 1024;
-
-    if (buf == NULL) {
-        ALOGE("Out of mem allocating transfer buffer");
-        err = ENOMEM;
-        goto done;
-    }
-
-    // Magic fields for the ustar file format
-    strcat(buf + 257, "ustar");
-    strcat(buf + 263, "00");
-
-    // [ 265 : 32 ] user name, ignored on restore
-    // [ 297 : 32 ] group name, ignored on restore
-
-    // [ 100 :   8 ] file mode
-    snprintf(buf + 100, 8, "%06o ", s.st_mode & ~S_IFMT);
-
-    // [ 108 :   8 ] uid -- ignored in Android format; uids are remapped at restore time
-    // [ 116 :   8 ] gid -- ignored in Android format
-    snprintf(buf + 108, 8, "0%lo", s.st_uid);
-    snprintf(buf + 116, 8, "0%lo", s.st_gid);
-
-    // [ 124 :  12 ] file size in bytes
-    if (s.st_size > 077777777777LL) {
-        // very large files need a pax extended size header
-        needExtended = true;
-    }
-    snprintf(buf + 124, 12, "%011llo", (isdir) ? 0LL : s.st_size);
-
-    // [ 136 :  12 ] last mod time as a UTC time_t
-    snprintf(buf + 136, 12, "%0lo", s.st_mtime);
-
-    // [ 156 :   1 ] link/file type
-    uint8_t type;
-    if (isdir) {
-        type = '5';     // tar magic: '5' == directory
-    } else if (S_ISREG(s.st_mode)) {
-        type = '0';     // tar magic: '0' == normal file
-    } else {
-        ALOGW("Error: unknown file mode 0%o [%s]", s.st_mode, filepath.string());
-        goto cleanup;
-    }
-    buf[156] = type;
-
-    // [ 157 : 100 ] name of linked file [not implemented]
-
-    {
-        // Prefix and main relative path.  Path lengths have been preflighted.
-        if (packageName.length() > 0) {
-            prefix = "apps/";
-            prefix += packageName;
-        }
-        if (domain.length() > 0) {
-            prefix.appendPath(domain);
-        }
-
-        // pax extended means we don't put in a prefix field, and put a different
-        // string in the basic name field.  We can also construct the full path name
-        // out of the substrings we've now built.
-        fullname = prefix;
-        fullname.appendPath(relpath);
-
-        // ustar:
-        //    [   0 : 100 ]; file name/path
-        //    [ 345 : 155 ] filename path prefix
-        // We only use the prefix area if fullname won't fit in the path
-        if (fullname.length() > 100) {
-            strncpy(buf, relpath.string(), 100);
-            strncpy(buf + 345, prefix.string(), 155);
-        } else {
-            strncpy(buf, fullname.string(), 100);
-        }
-    }
-
-    // [ 329 : 8 ] and [ 337 : 8 ] devmajor/devminor, not used
-
-    ALOGI("   Name: %s", fullname.string());
-
-    // If we're using a pax extended header, build & write that here; lengths are
-    // already preflighted
-    if (needExtended) {
-        char sizeStr[32];   // big enough for a 64-bit unsigned value in decimal
-        char* p = paxData;
-
-        // construct the pax extended header data block
-        memset(paxData, 0, BUFSIZE - (paxData - buf));
-        int len;
-
-        // size header -- calc len in digits by actually rendering the number
-        // to a string - brute force but simple
-        snprintf(sizeStr, sizeof(sizeStr), "%lld", s.st_size);
-        p += write_pax_header_entry(p, "size", sizeStr);
-
-        // fullname was generated above with the ustar paths
-        p += write_pax_header_entry(p, "path", fullname.string());
-
-        // Now we know how big the pax data is
-        int paxLen = p - paxData;
-
-        // Now build the pax *header* templated on the ustar header
-        memcpy(paxHeader, buf, 512);
-
-        String8 leaf = fullname.getPathLeaf();
-        memset(paxHeader, 0, 100);                  // rewrite the name area
-        snprintf(paxHeader, 100, "PaxHeader/%s", leaf.string());
-        memset(paxHeader + 345, 0, 155);            // rewrite the prefix area
-        strncpy(paxHeader + 345, prefix.string(), 155);
-
-        paxHeader[156] = 'x';                       // mark it as a pax extended header
-
-        // [ 124 :  12 ] size of pax extended header data
-        memset(paxHeader + 124, 0, 12);
-        snprintf(paxHeader + 124, 12, "%011o", p - paxData);
-
-        // Checksum and write the pax block header
-        calc_tar_checksum(paxHeader);
-        send_tarfile_chunk(writer, paxHeader, 512);
-
-        // Now write the pax data itself
-        int paxblocks = (paxLen + 511) / 512;
-        send_tarfile_chunk(writer, paxData, 512 * paxblocks);
-    }
-
-    // Checksum and write the 512-byte ustar file header block to the output
-    calc_tar_checksum(buf);
-    send_tarfile_chunk(writer, buf, 512);
-
-    // Now write the file data itself, for real files.  We honor tar's convention that
-    // only full 512-byte blocks are sent to write().
-    if (!isdir) {
-        off64_t toWrite = s.st_size;
-        while (toWrite > 0) {
-            size_t toRead = (toWrite < BUFSIZE) ? toWrite : BUFSIZE;
-            ssize_t nRead = read(fd, buf, toRead);
-            if (nRead < 0) {
-                err = errno;
-                ALOGE("Unable to read file [%s], err=%d (%s)", filepath.string(),
-                        err, strerror(err));
-                break;
-            } else if (nRead == 0) {
-                ALOGE("EOF but expect %lld more bytes in [%s]", (long long) toWrite,
-                        filepath.string());
-                err = EIO;
-                break;
-            }
-
-            // At EOF we might have a short block; NUL-pad that to a 512-byte multiple.  This
-            // depends on the OS guarantee that for ordinary files, read() will never return
-            // less than the number of bytes requested.
-            ssize_t partial = (nRead+512) % 512;
-            if (partial > 0) {
-                ssize_t remainder = 512 - partial;
-                memset(buf + nRead, 0, remainder);
-                nRead += remainder;
-            }
-            send_tarfile_chunk(writer, buf, nRead);
-            toWrite -= nRead;
-        }
-    }
-
-cleanup:
-    free(buf);
-done:
-    close(fd);
-    return err;
-}
-// end tarfile
-
-
-
-#define RESTORE_BUF_SIZE (8*1024)
-
-RestoreHelperBase::RestoreHelperBase()
-{
-    m_buf = malloc(RESTORE_BUF_SIZE);
-    m_loggedUnknownMetadata = false;
-}
-
-RestoreHelperBase::~RestoreHelperBase()
-{
-    free(m_buf);
-}
-
-status_t
-RestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in)
-{
-    ssize_t err;
-    size_t dataSize;
-    String8 key;
-    int fd;
-    void* buf = m_buf;
-    ssize_t amt;
-    int mode;
-    int crc;
-    struct stat st;
-    FileRec r;
-
-    err = in->ReadEntityHeader(&key, &dataSize);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    // Get the metadata block off the head of the file entity and use that to
-    // set up the output file
-    file_metadata_v1 metadata;
-    amt = in->ReadEntityData(&metadata, sizeof(metadata));
-    if (amt != sizeof(metadata)) {
-        ALOGW("Could not read metadata for %s -- %ld / %s", filename.string(),
-                (long)amt, strerror(errno));
-        return EIO;
-    }
-    metadata.version = fromlel(metadata.version);
-    metadata.mode = fromlel(metadata.mode);
-    if (metadata.version > CURRENT_METADATA_VERSION) {
-        if (!m_loggedUnknownMetadata) {
-            m_loggedUnknownMetadata = true;
-            ALOGW("Restoring file with unsupported metadata version %d (currently %d)",
-                    metadata.version, CURRENT_METADATA_VERSION);
-        }
-    }
-    mode = metadata.mode;
-
-    // Write the file and compute the crc
-    crc = crc32(0L, Z_NULL, 0);
-    fd = open(filename.string(), O_CREAT|O_RDWR|O_TRUNC, mode);
-    if (fd == -1) {
-        ALOGW("Could not open file %s -- %s", filename.string(), strerror(errno));
-        return errno;
-    }
-    
-    while ((amt = in->ReadEntityData(buf, RESTORE_BUF_SIZE)) > 0) {
-        err = write(fd, buf, amt);
-        if (err != amt) {
-            close(fd);
-            ALOGW("Error '%s' writing '%s'", strerror(errno), filename.string());
-            return errno;
-        }
-        crc = crc32(crc, (Bytef*)buf, amt);
-    }
-
-    close(fd);
-
-    // Record for the snapshot
-    err = stat(filename.string(), &st);
-    if (err != 0) {
-        ALOGW("Error stating file that we just created %s", filename.string());
-        return errno;
-    }
-
-    r.file = filename;
-    r.deleted = false;
-    r.s.modTime_sec = st.st_mtime;
-    r.s.modTime_nsec = 0; // workaround sim breakage
-    //r.s.modTime_nsec = st.st_mtime_nsec;
-    r.s.mode = st.st_mode;
-    r.s.size = st.st_size;
-    r.s.crc32 = crc;
-
-    m_files.add(key, r);
-
-    return NO_ERROR;
-}
-
-status_t
-RestoreHelperBase::WriteSnapshot(int fd)
-{
-    return write_snapshot_file(fd, m_files);;
-}
-
-#if TEST_BACKUP_HELPERS
-
-#define SCRATCH_DIR "/data/backup_helper_test/"
-
-static int
-write_text_file(const char* path, const char* data)
-{
-    int amt;
-    int fd;
-    int len;
-
-    fd = creat(path, 0666);
-    if (fd == -1) {
-        fprintf(stderr, "creat %s failed\n", path);
-        return errno;
-    }
-
-    len = strlen(data);
-    amt = write(fd, data, len);
-    if (amt != len) {
-        fprintf(stderr, "error (%s) writing to file %s\n", strerror(errno), path);
-        return errno;
-    }
-
-    close(fd);
-
-    return 0;
-}
-
-static int
-compare_file(const char* path, const unsigned char* data, int len)
-{
-    int fd;
-    int amt;
-
-    fd = open(path, O_RDONLY);
-    if (fd == -1) {
-        fprintf(stderr, "compare_file error (%s) opening %s\n", strerror(errno), path);
-        return errno;
-    }
-
-    unsigned char* contents = (unsigned char*)malloc(len);
-    if (contents == NULL) {
-        fprintf(stderr, "malloc(%d) failed\n", len);
-        return ENOMEM;
-    }
-
-    bool sizesMatch = true;
-    amt = lseek(fd, 0, SEEK_END);
-    if (amt != len) {
-        fprintf(stderr, "compare_file file length should be %d, was %d\n", len, amt);
-        sizesMatch = false;
-    }
-    lseek(fd, 0, SEEK_SET);
-
-    int readLen = amt < len ? amt : len;
-    amt = read(fd, contents, readLen);
-    if (amt != readLen) {
-        fprintf(stderr, "compare_file read expected %d bytes but got %d\n", len, amt);
-    }
-
-    bool contentsMatch = true;
-    for (int i=0; i<readLen; i++) {
-        if (data[i] != contents[i]) {
-            if (contentsMatch) {
-                fprintf(stderr, "compare_file contents are different: (index, expected, actual)\n");
-                contentsMatch = false;
-            }
-            fprintf(stderr, "  [%-2d] %02x %02x\n", i, data[i], contents[i]);
-        }
-    }
-
-    free(contents);
-    return contentsMatch && sizesMatch ? 0 : 1;
-}
-
-int
-backup_helper_test_empty()
-{
-    int err;
-    int fd;
-    KeyedVector<String8,FileRec> snapshot;
-    const char* filename = SCRATCH_DIR "backup_helper_test_empty.snap";
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-
-    // write
-    fd = creat(filename, 0666);
-    if (fd == -1) {
-        fprintf(stderr, "error creating %s\n", filename);
-        return 1;
-    }
-
-    err = write_snapshot_file(fd, snapshot);
-
-    close(fd);
-
-    if (err != 0) {
-        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
-        return err;
-    }
-
-    static const unsigned char correct_data[] = {
-        0x53, 0x6e, 0x61, 0x70,  0x00, 0x00, 0x00, 0x00,
-        0x46, 0x69, 0x6c, 0x65,  0x10, 0x00, 0x00, 0x00
-    };
-
-    err = compare_file(filename, correct_data, sizeof(correct_data));
-    if (err != 0) {
-        return err;
-    }
-
-    // read
-    fd = open(filename, O_RDONLY);
-    if (fd == -1) {
-        fprintf(stderr, "error opening for read %s\n", filename);
-        return 1;
-    }
-
-    KeyedVector<String8,FileState> readSnapshot;
-    err = read_snapshot_file(fd, &readSnapshot);
-    if (err != 0) {
-        fprintf(stderr, "read_snapshot_file failed %d\n", err);
-        return err;
-    }
-
-    if (readSnapshot.size() != 0) {
-        fprintf(stderr, "readSnapshot should be length 0\n");
-        return 1;
-    }
-
-    return 0;
-}
-
-int
-backup_helper_test_four()
-{
-    int err;
-    int fd;
-    KeyedVector<String8,FileRec> snapshot;
-    const char* filename = SCRATCH_DIR "backup_helper_test_four.snap";
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-
-    // write
-    fd = creat(filename, 0666);
-    if (fd == -1) {
-        fprintf(stderr, "error opening %s\n", filename);
-        return 1;
-    }
-
-    String8 filenames[4];
-    FileState states[4];
-    FileRec r;
-    r.deleted = false;
-
-    states[0].modTime_sec = 0xfedcba98;
-    states[0].modTime_nsec = 0xdeadbeef;
-    states[0].mode = 0777; // decimal 511, hex 0x000001ff
-    states[0].size = 0xababbcbc;
-    states[0].crc32 = 0x12345678;
-    states[0].nameLen = -12;
-    r.s = states[0];
-    filenames[0] = String8("bytes_of_padding");
-    snapshot.add(filenames[0], r);
-
-    states[1].modTime_sec = 0x93400031;
-    states[1].modTime_nsec = 0xdeadbeef;
-    states[1].mode = 0666; // decimal 438, hex 0x000001b6
-    states[1].size = 0x88557766;
-    states[1].crc32 = 0x22334422;
-    states[1].nameLen = -1;
-    r.s = states[1];
-    filenames[1] = String8("bytes_of_padding3");
-    snapshot.add(filenames[1], r);
-
-    states[2].modTime_sec = 0x33221144;
-    states[2].modTime_nsec = 0xdeadbeef;
-    states[2].mode = 0744; // decimal 484, hex 0x000001e4
-    states[2].size = 0x11223344;
-    states[2].crc32 = 0x01122334;
-    states[2].nameLen = 0;
-    r.s = states[2];
-    filenames[2] = String8("bytes_of_padding_2");
-    snapshot.add(filenames[2], r);
-
-    states[3].modTime_sec = 0x33221144;
-    states[3].modTime_nsec = 0xdeadbeef;
-    states[3].mode = 0755; // decimal 493, hex 0x000001ed
-    states[3].size = 0x11223344;
-    states[3].crc32 = 0x01122334;
-    states[3].nameLen = 0;
-    r.s = states[3];
-    filenames[3] = String8("bytes_of_padding__1");
-    snapshot.add(filenames[3], r);
-
-    err = write_snapshot_file(fd, snapshot);
-
-    close(fd);
-
-    if (err != 0) {
-        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
-        return err;
-    }
-
-    static const unsigned char correct_data[] = {
-        // header
-        0x53, 0x6e, 0x61, 0x70,  0x04, 0x00, 0x00, 0x00,
-        0x46, 0x69, 0x6c, 0x65,  0xbc, 0x00, 0x00, 0x00,
-
-        // bytes_of_padding
-        0x98, 0xba, 0xdc, 0xfe,  0xef, 0xbe, 0xad, 0xde,
-        0xff, 0x01, 0x00, 0x00,  0xbc, 0xbc, 0xab, 0xab,
-        0x78, 0x56, 0x34, 0x12,  0x10, 0x00, 0x00, 0x00,
-        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
-        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
-
-        // bytes_of_padding3
-        0x31, 0x00, 0x40, 0x93,  0xef, 0xbe, 0xad, 0xde,
-        0xb6, 0x01, 0x00, 0x00,  0x66, 0x77, 0x55, 0x88,
-        0x22, 0x44, 0x33, 0x22,  0x11, 0x00, 0x00, 0x00,
-        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
-        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
-        0x33, 0xab, 0xab, 0xab,
-
-        // bytes of padding2
-        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
-        0xe4, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
-        0x34, 0x23, 0x12, 0x01,  0x12, 0x00, 0x00, 0x00,
-        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
-        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
-        0x5f, 0x32, 0xab, 0xab,
-
-        // bytes of padding3
-        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
-        0xed, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
-        0x34, 0x23, 0x12, 0x01,  0x13, 0x00, 0x00, 0x00,
-        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
-        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
-        0x5f, 0x5f, 0x31, 0xab
-    };
-
-    err = compare_file(filename, correct_data, sizeof(correct_data));
-    if (err != 0) {
-        return err;
-    }
-
-    // read
-    fd = open(filename, O_RDONLY);
-    if (fd == -1) {
-        fprintf(stderr, "error opening for read %s\n", filename);
-        return 1;
-    }
-
-
-    KeyedVector<String8,FileState> readSnapshot;
-    err = read_snapshot_file(fd, &readSnapshot);
-    if (err != 0) {
-        fprintf(stderr, "read_snapshot_file failed %d\n", err);
-        return err;
-    }
-
-    if (readSnapshot.size() != 4) {
-        fprintf(stderr, "readSnapshot should be length 4 is %d\n", readSnapshot.size());
-        return 1;
-    }
-
-    bool matched = true;
-    for (size_t i=0; i<readSnapshot.size(); i++) {
-        const String8& name = readSnapshot.keyAt(i);
-        const FileState state = readSnapshot.valueAt(i);
-
-        if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec
-                || states[i].modTime_nsec != state.modTime_nsec || states[i].mode != state.mode
-                || states[i].size != state.size || states[i].crc32 != states[i].crc32) {
-            fprintf(stderr, "state %d expected={%d/%d, 0x%08x, %04o, 0x%08x, %3d} '%s'\n"
-                            "          actual={%d/%d, 0x%08x, %04o, 0x%08x, %3d} '%s'\n", i,
-                    states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size,
-                    states[i].crc32, name.length(), filenames[i].string(),
-                    state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32,
-                    state.nameLen, name.string());
-            matched = false;
-        }
-    }
-
-    return matched ? 0 : 1;
-}
-
-// hexdump -v -e '"    " 8/1 " 0x%02x," "\n"' data_writer.data
-const unsigned char DATA_GOLDEN_FILE[] = {
-     0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,
-     0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,
-     0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
-     0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
-     0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,
-     0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
-     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
-     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
-     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
-     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
-     0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,
-     0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
-     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
-     0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
-     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
-     0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,
-     0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
-     0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,
-     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00
-
-};
-const int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);
-
-static int
-test_write_header_and_entity(BackupDataWriter& writer, const char* str)
-{
-    int err;
-    String8 text(str);
-
-    err = writer.WriteEntityHeader(text, text.length()+1);
-    if (err != 0) {
-        fprintf(stderr, "WriteEntityHeader failed with %s\n", strerror(err));
-        return err;
-    }
-
-    err = writer.WriteEntityData(text.string(), text.length()+1);
-    if (err != 0) {
-        fprintf(stderr, "write failed for data '%s'\n", text.string());
-        return errno;
-    }
-
-    return err;
-}
-
-int
-backup_helper_test_data_writer()
-{
-    int err;
-    int fd;
-    const char* filename = SCRATCH_DIR "data_writer.data";
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-    mkdir(SCRATCH_DIR "data", 0777);
-
-    fd = creat(filename, 0666);
-    if (fd == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    BackupDataWriter writer(fd);
-
-    err = 0;
-    err |= test_write_header_and_entity(writer, "no_padding_");
-    err |= test_write_header_and_entity(writer, "padded_to__3");
-    err |= test_write_header_and_entity(writer, "padded_to_2__");
-    err |= test_write_header_and_entity(writer, "padded_to1");
-
-    close(fd);
-
-    err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
-    if (err != 0) {
-        return err;
-    }
-
-    return err;
-}
-
-int
-test_read_header_and_entity(BackupDataReader& reader, const char* str)
-{
-    int err;
-    int bufSize = strlen(str)+1;
-    char* buf = (char*)malloc(bufSize);
-    String8 string;
-    int cookie = 0x11111111;
-    size_t actualSize;
-    bool done;
-    int type;
-    ssize_t nRead;
-
-    // printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str);
-
-    err = reader.ReadNextHeader(&done, &type);
-    if (done) {
-        fprintf(stderr, "should not be done yet\n");
-        goto finished;
-    }
-    if (err != 0) {
-        fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
-        goto finished;
-    }
-    if (type != BACKUP_HEADER_ENTITY_V1) {
-        err = EINVAL;
-        fprintf(stderr, "type=0x%08x expected 0x%08x\n", type, BACKUP_HEADER_ENTITY_V1);
-    }
-
-    err = reader.ReadEntityHeader(&string, &actualSize);
-    if (err != 0) {
-        fprintf(stderr, "ReadEntityHeader failed with %s\n", strerror(err));
-        goto finished;
-    }
-    if (string != str) {
-        fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
-        err = EINVAL;
-        goto finished;
-    }
-    if ((int)actualSize != bufSize) {
-        fprintf(stderr, "ReadEntityHeader expected dataSize 0x%08x got 0x%08x\n", bufSize,
-                actualSize);
-        err = EINVAL;
-        goto finished;
-    }
-
-    nRead = reader.ReadEntityData(buf, bufSize);
-    if (nRead < 0) {
-        err = reader.Status();
-        fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err));
-        goto finished;
-    }
-
-    if (0 != memcmp(buf, str, bufSize)) {
-        fprintf(stderr, "ReadEntityData expected '%s' but got something starting with "
-                "%02x %02x %02x %02x  '%c%c%c%c'\n", str, buf[0], buf[1], buf[2], buf[3],
-                buf[0], buf[1], buf[2], buf[3]);
-        err = EINVAL;
-        goto finished;
-    }
-
-    // The next read will confirm whether it got the right amount of data.
-
-finished:
-    if (err != NO_ERROR) {
-        fprintf(stderr, "test_read_header_and_entity failed with %s\n", strerror(err));
-    }
-    free(buf);
-    return err;
-}
-
-int
-backup_helper_test_data_reader()
-{
-    int err;
-    int fd;
-    const char* filename = SCRATCH_DIR "data_reader.data";
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-    mkdir(SCRATCH_DIR "data", 0777);
-
-    fd = creat(filename, 0666);
-    if (fd == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    err = write(fd, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
-    if (err != DATA_GOLDEN_FILE_SIZE) {
-        fprintf(stderr, "Error \"%s\" writing golden file %s\n", strerror(errno), filename);
-        return errno;
-    }
-
-    close(fd);
-
-    fd = open(filename, O_RDONLY);
-    if (fd == -1) {
-        fprintf(stderr, "Error \"%s\" opening golden file %s for read\n", strerror(errno),
-                filename);
-        return errno;
-    }
-
-    {
-        BackupDataReader reader(fd);
-
-        err = 0;
-
-        if (err == NO_ERROR) {
-            err = test_read_header_and_entity(reader, "no_padding_");
-        }
-
-        if (err == NO_ERROR) {
-            err = test_read_header_and_entity(reader, "padded_to__3");
-        }
-
-        if (err == NO_ERROR) {
-            err = test_read_header_and_entity(reader, "padded_to_2__");
-        }
-
-        if (err == NO_ERROR) {
-            err = test_read_header_and_entity(reader, "padded_to1");
-        }
-    }
-
-    close(fd);
-
-    return err;
-}
-
-static int
-get_mod_time(const char* filename, struct timeval times[2])
-{
-    int err;
-    struct stat64 st;
-    err = stat64(filename, &st);
-    if (err != 0) {
-        fprintf(stderr, "stat '%s' failed: %s\n", filename, strerror(errno));
-        return errno;
-    }
-    times[0].tv_sec = st.st_atime;
-    times[1].tv_sec = st.st_mtime;
-
-    // If st_atime is a macro then struct stat64 uses struct timespec
-    // to store the access and modif time values and typically
-    // st_*time_nsec is not defined. In glibc, this is controlled by
-    // __USE_MISC.
-#ifdef __USE_MISC
-#if !defined(st_atime) || defined(st_atime_nsec)
-#error "Check if this __USE_MISC conditional is still needed."
-#endif
-    times[0].tv_usec = st.st_atim.tv_nsec / 1000;
-    times[1].tv_usec = st.st_mtim.tv_nsec / 1000;
-#else
-    times[0].tv_usec = st.st_atime_nsec / 1000;
-    times[1].tv_usec = st.st_mtime_nsec / 1000;
-#endif
-
-    return 0;
-}
-
-int
-backup_helper_test_files()
-{
-    int err;
-    int oldSnapshotFD;
-    int dataStreamFD;
-    int newSnapshotFD;
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-    mkdir(SCRATCH_DIR "data", 0777);
-
-    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
-    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
-    write_text_file(SCRATCH_DIR "data/d", "d\ndd\n");
-    write_text_file(SCRATCH_DIR "data/e", "e\nee\n");
-    write_text_file(SCRATCH_DIR "data/f", "f\nff\n");
-    write_text_file(SCRATCH_DIR "data/h", "h\nhh\n");
-
-    char const* files_before[] = {
-        SCRATCH_DIR "data/b",
-        SCRATCH_DIR "data/c",
-        SCRATCH_DIR "data/d",
-        SCRATCH_DIR "data/e",
-        SCRATCH_DIR "data/f"
-    };
-
-    char const* keys_before[] = {
-        "data/b",
-        "data/c",
-        "data/d",
-        "data/e",
-        "data/f"
-    };
-
-    dataStreamFD = creat(SCRATCH_DIR "1.data", 0666);
-    if (dataStreamFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    newSnapshotFD = creat(SCRATCH_DIR "before.snap", 0666);
-    if (newSnapshotFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    {
-        BackupDataWriter dataStream(dataStreamFD);
-
-        err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);
-        if (err != 0) {
-            return err;
-        }
-    }
-
-    close(dataStreamFD);
-    close(newSnapshotFD);
-
-    sleep(3);
-
-    struct timeval d_times[2];
-    struct timeval e_times[2];
-
-    err = get_mod_time(SCRATCH_DIR "data/d", d_times);
-    err |= get_mod_time(SCRATCH_DIR "data/e", e_times);
-    if (err != 0) {
-        return err;
-    }
-
-    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
-    unlink(SCRATCH_DIR "data/c");
-    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
-    write_text_file(SCRATCH_DIR "data/d", "dd\ndd\n");
-    utimes(SCRATCH_DIR "data/d", d_times);
-    write_text_file(SCRATCH_DIR "data/e", "z\nzz\n");
-    utimes(SCRATCH_DIR "data/e", e_times);
-    write_text_file(SCRATCH_DIR "data/g", "g\ngg\n");
-    unlink(SCRATCH_DIR "data/f");
-
-    char const* files_after[] = {
-        SCRATCH_DIR "data/a", // added
-        SCRATCH_DIR "data/b", // same
-        SCRATCH_DIR "data/c", // different mod time
-        SCRATCH_DIR "data/d", // different size (same mod time)
-        SCRATCH_DIR "data/e", // different contents (same mod time, same size)
-        SCRATCH_DIR "data/g"  // added
-    };
-
-    char const* keys_after[] = {
-        "data/a", // added
-        "data/b", // same
-        "data/c", // different mod time
-        "data/d", // different size (same mod time)
-        "data/e", // different contents (same mod time, same size)
-        "data/g"  // added
-    };
-
-    oldSnapshotFD = open(SCRATCH_DIR "before.snap", O_RDONLY);
-    if (oldSnapshotFD == -1) {
-        fprintf(stderr, "error opening: %s\n", strerror(errno));
-        return errno;
-    }
-
-    dataStreamFD = creat(SCRATCH_DIR "2.data", 0666);
-    if (dataStreamFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    newSnapshotFD = creat(SCRATCH_DIR "after.snap", 0666);
-    if (newSnapshotFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    {
-        BackupDataWriter dataStream(dataStreamFD);
-
-        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);
-        if (err != 0) {
-            return err;
-        }
-}
-
-    close(oldSnapshotFD);
-    close(dataStreamFD);
-    close(newSnapshotFD);
-
-    return 0;
-}
-
-int
-backup_helper_test_null_base()
-{
-    int err;
-    int oldSnapshotFD;
-    int dataStreamFD;
-    int newSnapshotFD;
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-    mkdir(SCRATCH_DIR "data", 0777);
-
-    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
-
-    char const* files[] = {
-        SCRATCH_DIR "data/a",
-    };
-
-    char const* keys[] = {
-        "a",
-    };
-
-    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
-    if (dataStreamFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
-    if (newSnapshotFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    {
-        BackupDataWriter dataStream(dataStreamFD);
-
-        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
-        if (err != 0) {
-            return err;
-        }
-    }
-
-    close(dataStreamFD);
-    close(newSnapshotFD);
-
-    return 0;
-}
-
-int
-backup_helper_test_missing_file()
-{
-    int err;
-    int oldSnapshotFD;
-    int dataStreamFD;
-    int newSnapshotFD;
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-    mkdir(SCRATCH_DIR "data", 0777);
-
-    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
-
-    char const* files[] = {
-        SCRATCH_DIR "data/a",
-        SCRATCH_DIR "data/b",
-        SCRATCH_DIR "data/c",
-    };
-
-    char const* keys[] = {
-        "a",
-        "b",
-        "c",
-    };
-
-    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
-    if (dataStreamFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
-    if (newSnapshotFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    {
-        BackupDataWriter dataStream(dataStreamFD);
-
-        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
-        if (err != 0) {
-            return err;
-        }
-    }
-
-    close(dataStreamFD);
-    close(newSnapshotFD);
-
-    return 0;
-}
-
-
-#endif // TEST_BACKUP_HELPERS
-
-}
diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
deleted file mode 100644
index 0f54edb..0000000
--- a/libs/androidfw/CursorWindow.cpp
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2006-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.
- */
-
-#undef LOG_TAG
-#define LOG_TAG "CursorWindow"
-
-#include <androidfw/CursorWindow.h>
-#include <binder/Parcel.h>
-#include <utils/Log.h>
-
-#include <cutils/ashmem.h>
-#include <sys/mman.h>
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-
-namespace android {
-
-CursorWindow::CursorWindow(const String8& name, int ashmemFd,
-        void* data, size_t size, bool readOnly) :
-        mName(name), mAshmemFd(ashmemFd), mData(data), mSize(size), mReadOnly(readOnly) {
-    mHeader = static_cast<Header*>(mData);
-}
-
-CursorWindow::~CursorWindow() {
-    ::munmap(mData, mSize);
-    ::close(mAshmemFd);
-}
-
-status_t CursorWindow::create(const String8& name, size_t size, CursorWindow** outCursorWindow) {
-    String8 ashmemName("CursorWindow: ");
-    ashmemName.append(name);
-
-    status_t result;
-    int ashmemFd = ashmem_create_region(ashmemName.string(), size);
-    if (ashmemFd < 0) {
-        result = -errno;
-    } else {
-        result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
-        if (result >= 0) {
-            void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);
-            if (data == MAP_FAILED) {
-                result = -errno;
-            } else {
-                result = ashmem_set_prot_region(ashmemFd, PROT_READ);
-                if (result >= 0) {
-                    CursorWindow* window = new CursorWindow(name, ashmemFd,
-                            data, size, false /*readOnly*/);
-                    result = window->clear();
-                    if (!result) {
-                        LOG_WINDOW("Created new CursorWindow: freeOffset=%d, "
-                                "numRows=%d, numColumns=%d, mSize=%d, mData=%p",
-                                window->mHeader->freeOffset,
-                                window->mHeader->numRows,
-                                window->mHeader->numColumns,
-                                window->mSize, window->mData);
-                        *outCursorWindow = window;
-                        return OK;
-                    }
-                    delete window;
-                }
-            }
-            ::munmap(data, size);
-        }
-        ::close(ashmemFd);
-    }
-    *outCursorWindow = NULL;
-    return result;
-}
-
-status_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow) {
-    String8 name = parcel->readString8();
-
-    status_t result;
-    int ashmemFd = parcel->readFileDescriptor();
-    if (ashmemFd == int(BAD_TYPE)) {
-        result = BAD_TYPE;
-    } else {
-        ssize_t size = ashmem_get_size_region(ashmemFd);
-        if (size < 0) {
-            result = UNKNOWN_ERROR;
-        } else {
-            int dupAshmemFd = ::dup(ashmemFd);
-            if (dupAshmemFd < 0) {
-                result = -errno;
-            } else {
-                void* data = ::mmap(NULL, size, PROT_READ, MAP_SHARED, dupAshmemFd, 0);
-                if (data == MAP_FAILED) {
-                    result = -errno;
-                } else {
-                    CursorWindow* window = new CursorWindow(name, dupAshmemFd,
-                            data, size, true /*readOnly*/);
-                    LOG_WINDOW("Created CursorWindow from parcel: freeOffset=%d, "
-                            "numRows=%d, numColumns=%d, mSize=%d, mData=%p",
-                            window->mHeader->freeOffset,
-                            window->mHeader->numRows,
-                            window->mHeader->numColumns,
-                            window->mSize, window->mData);
-                    *outCursorWindow = window;
-                    return OK;
-                }
-                ::close(dupAshmemFd);
-            }
-        }
-    }
-    *outCursorWindow = NULL;
-    return result;
-}
-
-status_t CursorWindow::writeToParcel(Parcel* parcel) {
-    status_t status = parcel->writeString8(mName);
-    if (!status) {
-        status = parcel->writeDupFileDescriptor(mAshmemFd);
-    }
-    return status;
-}
-
-status_t CursorWindow::clear() {
-    if (mReadOnly) {
-        return INVALID_OPERATION;
-    }
-
-    mHeader->freeOffset = sizeof(Header) + sizeof(RowSlotChunk);
-    mHeader->firstChunkOffset = sizeof(Header);
-    mHeader->numRows = 0;
-    mHeader->numColumns = 0;
-
-    RowSlotChunk* firstChunk = static_cast<RowSlotChunk*>(offsetToPtr(mHeader->firstChunkOffset));
-    firstChunk->nextChunkOffset = 0;
-    return OK;
-}
-
-status_t CursorWindow::setNumColumns(uint32_t numColumns) {
-    if (mReadOnly) {
-        return INVALID_OPERATION;
-    }
-
-    uint32_t cur = mHeader->numColumns;
-    if ((cur > 0 || mHeader->numRows > 0) && cur != numColumns) {
-        ALOGE("Trying to go from %d columns to %d", cur, numColumns);
-        return INVALID_OPERATION;
-    }
-    mHeader->numColumns = numColumns;
-    return OK;
-}
-
-status_t CursorWindow::allocRow() {
-    if (mReadOnly) {
-        return INVALID_OPERATION;
-    }
-
-    // Fill in the row slot
-    RowSlot* rowSlot = allocRowSlot();
-    if (rowSlot == NULL) {
-        return NO_MEMORY;
-    }
-
-    // Allocate the slots for the field directory
-    size_t fieldDirSize = mHeader->numColumns * sizeof(FieldSlot);
-    uint32_t fieldDirOffset = alloc(fieldDirSize, true /*aligned*/);
-    if (!fieldDirOffset) {
-        mHeader->numRows--;
-        LOG_WINDOW("The row failed, so back out the new row accounting "
-                "from allocRowSlot %d", mHeader->numRows);
-        return NO_MEMORY;
-    }
-    FieldSlot* fieldDir = static_cast<FieldSlot*>(offsetToPtr(fieldDirOffset));
-    memset(fieldDir, 0, fieldDirSize);
-
-    LOG_WINDOW("Allocated row %u, rowSlot is at offset %u, fieldDir is %d bytes at offset %u\n",
-            mHeader->numRows - 1, offsetFromPtr(rowSlot), fieldDirSize, fieldDirOffset);
-    rowSlot->offset = fieldDirOffset;
-    return OK;
-}
-
-status_t CursorWindow::freeLastRow() {
-    if (mReadOnly) {
-        return INVALID_OPERATION;
-    }
-
-    if (mHeader->numRows > 0) {
-        mHeader->numRows--;
-    }
-    return OK;
-}
-
-uint32_t CursorWindow::alloc(size_t size, bool aligned) {
-    uint32_t padding;
-    if (aligned) {
-        // 4 byte alignment
-        padding = (~mHeader->freeOffset + 1) & 3;
-    } else {
-        padding = 0;
-    }
-
-    uint32_t offset = mHeader->freeOffset + padding;
-    uint32_t nextFreeOffset = offset + size;
-    if (nextFreeOffset > mSize) {
-        ALOGW("Window is full: requested allocation %d bytes, "
-                "free space %d bytes, window size %d bytes",
-                size, freeSpace(), mSize);
-        return 0;
-    }
-
-    mHeader->freeOffset = nextFreeOffset;
-    return offset;
-}
-
-CursorWindow::RowSlot* CursorWindow::getRowSlot(uint32_t row) {
-    uint32_t chunkPos = row;
-    RowSlotChunk* chunk = static_cast<RowSlotChunk*>(
-            offsetToPtr(mHeader->firstChunkOffset));
-    while (chunkPos >= ROW_SLOT_CHUNK_NUM_ROWS) {
-        chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));
-        chunkPos -= ROW_SLOT_CHUNK_NUM_ROWS;
-    }
-    return &chunk->slots[chunkPos];
-}
-
-CursorWindow::RowSlot* CursorWindow::allocRowSlot() {
-    uint32_t chunkPos = mHeader->numRows;
-    RowSlotChunk* chunk = static_cast<RowSlotChunk*>(
-            offsetToPtr(mHeader->firstChunkOffset));
-    while (chunkPos > ROW_SLOT_CHUNK_NUM_ROWS) {
-        chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));
-        chunkPos -= ROW_SLOT_CHUNK_NUM_ROWS;
-    }
-    if (chunkPos == ROW_SLOT_CHUNK_NUM_ROWS) {
-        if (!chunk->nextChunkOffset) {
-            chunk->nextChunkOffset = alloc(sizeof(RowSlotChunk), true /*aligned*/);
-            if (!chunk->nextChunkOffset) {
-                return NULL;
-            }
-        }
-        chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));
-        chunk->nextChunkOffset = 0;
-        chunkPos = 0;
-    }
-    mHeader->numRows += 1;
-    return &chunk->slots[chunkPos];
-}
-
-CursorWindow::FieldSlot* CursorWindow::getFieldSlot(uint32_t row, uint32_t column) {
-    if (row >= mHeader->numRows || column >= mHeader->numColumns) {
-        ALOGE("Failed to read row %d, column %d from a CursorWindow which "
-                "has %d rows, %d columns.",
-                row, column, mHeader->numRows, mHeader->numColumns);
-        return NULL;
-    }
-    RowSlot* rowSlot = getRowSlot(row);
-    if (!rowSlot) {
-        ALOGE("Failed to find rowSlot for row %d.", row);
-        return NULL;
-    }
-    FieldSlot* fieldDir = static_cast<FieldSlot*>(offsetToPtr(rowSlot->offset));
-    return &fieldDir[column];
-}
-
-status_t CursorWindow::putBlob(uint32_t row, uint32_t column, const void* value, size_t size) {
-    return putBlobOrString(row, column, value, size, FIELD_TYPE_BLOB);
-}
-
-status_t CursorWindow::putString(uint32_t row, uint32_t column, const char* value,
-        size_t sizeIncludingNull) {
-    return putBlobOrString(row, column, value, sizeIncludingNull, FIELD_TYPE_STRING);
-}
-
-status_t CursorWindow::putBlobOrString(uint32_t row, uint32_t column,
-        const void* value, size_t size, int32_t type) {
-    if (mReadOnly) {
-        return INVALID_OPERATION;
-    }
-
-    FieldSlot* fieldSlot = getFieldSlot(row, column);
-    if (!fieldSlot) {
-        return BAD_VALUE;
-    }
-
-    uint32_t offset = alloc(size);
-    if (!offset) {
-        return NO_MEMORY;
-    }
-
-    memcpy(offsetToPtr(offset), value, size);
-
-    fieldSlot->type = type;
-    fieldSlot->data.buffer.offset = offset;
-    fieldSlot->data.buffer.size = size;
-    return OK;
-}
-
-status_t CursorWindow::putLong(uint32_t row, uint32_t column, int64_t value) {
-    if (mReadOnly) {
-        return INVALID_OPERATION;
-    }
-
-    FieldSlot* fieldSlot = getFieldSlot(row, column);
-    if (!fieldSlot) {
-        return BAD_VALUE;
-    }
-
-    fieldSlot->type = FIELD_TYPE_INTEGER;
-    fieldSlot->data.l = value;
-    return OK;
-}
-
-status_t CursorWindow::putDouble(uint32_t row, uint32_t column, double value) {
-    if (mReadOnly) {
-        return INVALID_OPERATION;
-    }
-
-    FieldSlot* fieldSlot = getFieldSlot(row, column);
-    if (!fieldSlot) {
-        return BAD_VALUE;
-    }
-
-    fieldSlot->type = FIELD_TYPE_FLOAT;
-    fieldSlot->data.d = value;
-    return OK;
-}
-
-status_t CursorWindow::putNull(uint32_t row, uint32_t column) {
-    if (mReadOnly) {
-        return INVALID_OPERATION;
-    }
-
-    FieldSlot* fieldSlot = getFieldSlot(row, column);
-    if (!fieldSlot) {
-        return BAD_VALUE;
-    }
-
-    fieldSlot->type = FIELD_TYPE_NULL;
-    fieldSlot->data.buffer.offset = 0;
-    fieldSlot->data.buffer.size = 0;
-    return OK;
-}
-
-}; // namespace android
diff --git a/libs/androidfw/MODULE_LICENSE_APACHE2 b/libs/androidfw/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/libs/androidfw/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/libs/androidfw/NOTICE b/libs/androidfw/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/libs/androidfw/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-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.
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/libs/androidfw/ObbFile.cpp b/libs/androidfw/ObbFile.cpp
deleted file mode 100644
index 21e06c8..0000000
--- a/libs/androidfw/ObbFile.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define LOG_TAG "ObbFile"
-
-#include <androidfw/ObbFile.h>
-#include <utils/Compat.h>
-#include <utils/Log.h>
-
-//#define DEBUG 1
-
-#define kFooterTagSize 8  /* last two 32-bit integers */
-
-#define kFooterMinSize 33 /* 32-bit signature version (4 bytes)
-                           * 32-bit package version (4 bytes)
-                           * 32-bit flags (4 bytes)
-                           * 64-bit salt (8 bytes)
-                           * 32-bit package name size (4 bytes)
-                           * >=1-character package name (1 byte)
-                           * 32-bit footer size (4 bytes)
-                           * 32-bit footer marker (4 bytes)
-                           */
-
-#define kMaxBufSize    32768 /* Maximum file read buffer */
-
-#define kSignature     0x01059983U /* ObbFile signature */
-
-#define kSigVersion    1 /* We only know about signature version 1 */
-
-/* offsets in version 1 of the header */
-#define kPackageVersionOffset 4
-#define kFlagsOffset          8
-#define kSaltOffset           12
-#define kPackageNameLenOffset 20
-#define kPackageNameOffset    24
-
-/*
- * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
- * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
- * not already defined, then define it here.
- */
-#ifndef TEMP_FAILURE_RETRY
-/* Used to retry syscalls that can return EINTR. */
-#define TEMP_FAILURE_RETRY(exp) ({         \
-    typeof (exp) _rc;                      \
-    do {                                   \
-        _rc = (exp);                       \
-    } while (_rc == -1 && errno == EINTR); \
-    _rc; })
-#endif
-
-
-namespace android {
-
-ObbFile::ObbFile()
-        : mPackageName("")
-        , mVersion(-1)
-        , mFlags(0)
-{
-    memset(mSalt, 0, sizeof(mSalt));
-}
-
-ObbFile::~ObbFile() {
-}
-
-bool ObbFile::readFrom(const char* filename)
-{
-    int fd;
-    bool success = false;
-
-    fd = ::open(filename, O_RDONLY);
-    if (fd < 0) {
-        ALOGW("couldn't open file %s: %s", filename, strerror(errno));
-        goto out;
-    }
-    success = readFrom(fd);
-    close(fd);
-
-    if (!success) {
-        ALOGW("failed to read from %s (fd=%d)\n", filename, fd);
-    }
-
-out:
-    return success;
-}
-
-bool ObbFile::readFrom(int fd)
-{
-    if (fd < 0) {
-        ALOGW("attempt to read from invalid fd\n");
-        return false;
-    }
-
-    return parseObbFile(fd);
-}
-
-bool ObbFile::parseObbFile(int fd)
-{
-    off64_t fileLength = lseek64(fd, 0, SEEK_END);
-
-    if (fileLength < kFooterMinSize) {
-        if (fileLength < 0) {
-            ALOGW("error seeking in ObbFile: %s\n", strerror(errno));
-        } else {
-            ALOGW("file is only %lld (less than %d minimum)\n", fileLength, kFooterMinSize);
-        }
-        return false;
-    }
-
-    ssize_t actual;
-    size_t footerSize;
-
-    {
-        lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);
-
-        char *footer = new char[kFooterTagSize];
-        actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize));
-        if (actual != kFooterTagSize) {
-            ALOGW("couldn't read footer signature: %s\n", strerror(errno));
-            return false;
-        }
-
-        unsigned int fileSig = get4LE((unsigned char*)footer + sizeof(int32_t));
-        if (fileSig != kSignature) {
-            ALOGW("footer didn't match magic string (expected 0x%08x; got 0x%08x)\n",
-                    kSignature, fileSig);
-            return false;
-        }
-
-        footerSize = get4LE((unsigned char*)footer);
-        if (footerSize > (size_t)fileLength - kFooterTagSize
-                || footerSize > kMaxBufSize) {
-            ALOGW("claimed footer size is too large (0x%08zx; file size is 0x%08llx)\n",
-                    footerSize, fileLength);
-            return false;
-        }
-
-        if (footerSize < (kFooterMinSize - kFooterTagSize)) {
-            ALOGW("claimed footer size is too small (0x%zx; minimum size is 0x%x)\n",
-                    footerSize, kFooterMinSize - kFooterTagSize);
-            return false;
-        }
-    }
-
-    off64_t fileOffset = fileLength - footerSize - kFooterTagSize;
-    if (lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {
-        ALOGW("seek %lld failed: %s\n", fileOffset, strerror(errno));
-        return false;
-    }
-
-    mFooterStart = fileOffset;
-
-    char* scanBuf = (char*)malloc(footerSize);
-    if (scanBuf == NULL) {
-        ALOGW("couldn't allocate scanBuf: %s\n", strerror(errno));
-        return false;
-    }
-
-    actual = TEMP_FAILURE_RETRY(read(fd, scanBuf, footerSize));
-    // readAmount is guaranteed to be less than kMaxBufSize
-    if (actual != (ssize_t)footerSize) {
-        ALOGI("couldn't read ObbFile footer: %s\n", strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-#ifdef DEBUG
-    for (int i = 0; i < footerSize; ++i) {
-        ALOGI("char: 0x%02x\n", scanBuf[i]);
-    }
-#endif
-
-    uint32_t sigVersion = get4LE((unsigned char*)scanBuf);
-    if (sigVersion != kSigVersion) {
-        ALOGW("Unsupported ObbFile version %d\n", sigVersion);
-        free(scanBuf);
-        return false;
-    }
-
-    mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);
-    mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);
-
-    memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt));
-
-    size_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
-    if (packageNameLen == 0
-            || packageNameLen > (footerSize - kPackageNameOffset)) {
-        ALOGW("bad ObbFile package name length (0x%04zx; 0x%04zx possible)\n",
-                packageNameLen, footerSize - kPackageNameOffset);
-        free(scanBuf);
-        return false;
-    }
-
-    char* packageName = reinterpret_cast<char*>(scanBuf + kPackageNameOffset);
-    mPackageName = String8(const_cast<char*>(packageName), packageNameLen);
-
-    free(scanBuf);
-
-#ifdef DEBUG
-    ALOGI("Obb scan succeeded: packageName=%s, version=%d\n", mPackageName.string(), mVersion);
-#endif
-
-    return true;
-}
-
-bool ObbFile::writeTo(const char* filename)
-{
-    int fd;
-    bool success = false;
-
-    fd = ::open(filename, O_WRONLY);
-    if (fd < 0) {
-        goto out;
-    }
-    success = writeTo(fd);
-    close(fd);
-
-out:
-    if (!success) {
-        ALOGW("failed to write to %s: %s\n", filename, strerror(errno));
-    }
-    return success;
-}
-
-bool ObbFile::writeTo(int fd)
-{
-    if (fd < 0) {
-        return false;
-    }
-
-    lseek64(fd, 0, SEEK_END);
-
-    if (mPackageName.size() == 0 || mVersion == -1) {
-        ALOGW("tried to write uninitialized ObbFile data\n");
-        return false;
-    }
-
-    unsigned char intBuf[sizeof(uint32_t)+1];
-    memset(&intBuf, 0, sizeof(intBuf));
-
-    put4LE(intBuf, kSigVersion);
-    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
-        ALOGW("couldn't write signature version: %s\n", strerror(errno));
-        return false;
-    }
-
-    put4LE(intBuf, mVersion);
-    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
-        ALOGW("couldn't write package version\n");
-        return false;
-    }
-
-    put4LE(intBuf, mFlags);
-    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
-        ALOGW("couldn't write package version\n");
-        return false;
-    }
-
-    if (write(fd, mSalt, sizeof(mSalt)) != (ssize_t)sizeof(mSalt)) {
-        ALOGW("couldn't write salt: %s\n", strerror(errno));
-        return false;
-    }
-
-    size_t packageNameLen = mPackageName.size();
-    put4LE(intBuf, packageNameLen);
-    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
-        ALOGW("couldn't write package name length: %s\n", strerror(errno));
-        return false;
-    }
-
-    if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {
-        ALOGW("couldn't write package name: %s\n", strerror(errno));
-        return false;
-    }
-
-    put4LE(intBuf, kPackageNameOffset + packageNameLen);
-    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
-        ALOGW("couldn't write footer size: %s\n", strerror(errno));
-        return false;
-    }
-
-    put4LE(intBuf, kSignature);
-    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
-        ALOGW("couldn't write footer magic signature: %s\n", strerror(errno));
-        return false;
-    }
-
-    return true;
-}
-
-bool ObbFile::removeFrom(const char* filename)
-{
-    int fd;
-    bool success = false;
-
-    fd = ::open(filename, O_RDWR);
-    if (fd < 0) {
-        goto out;
-    }
-    success = removeFrom(fd);
-    close(fd);
-
-out:
-    if (!success) {
-        ALOGW("failed to remove signature from %s: %s\n", filename, strerror(errno));
-    }
-    return success;
-}
-
-bool ObbFile::removeFrom(int fd)
-{
-    if (fd < 0) {
-        return false;
-    }
-
-    if (!readFrom(fd)) {
-        return false;
-    }
-
-    ftruncate(fd, mFooterStart);
-
-    return true;
-}
-
-}
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
deleted file mode 100644
index 1cc3563..0000000
--- a/libs/androidfw/ResourceTypes.cpp
+++ /dev/null
@@ -1,5796 +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.
- */
-
-#define LOG_TAG "ResourceType"
-//#define LOG_NDEBUG 0
-
-#include <androidfw/ResourceTypes.h>
-#include <utils/Atomic.h>
-#include <utils/ByteOrder.h>
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <utils/String16.h>
-#include <utils/String8.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <memory.h>
-#include <ctype.h>
-#include <stdint.h>
-
-#ifndef INT32_MAX
-#define INT32_MAX ((int32_t)(2147483647))
-#endif
-
-#define STRING_POOL_NOISY(x) //x
-#define XML_NOISY(x) //x
-#define TABLE_NOISY(x) //x
-#define TABLE_GETENTRY(x) //x
-#define TABLE_SUPER_NOISY(x) //x
-#define LOAD_TABLE_NOISY(x) //x
-#define TABLE_THEME(x) //x
-
-namespace android {
-
-#ifdef HAVE_WINSOCK
-#undef  nhtol
-#undef  htonl
-
-#ifdef HAVE_LITTLE_ENDIAN
-#define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
-#define htonl(x)    ntohl(x)
-#define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
-#define htons(x)    ntohs(x)
-#else
-#define ntohl(x)    (x)
-#define htonl(x)    (x)
-#define ntohs(x)    (x)
-#define htons(x)    (x)
-#endif
-#endif
-
-#define IDMAP_MAGIC         0x706d6469
-// size measured in sizeof(uint32_t)
-#define IDMAP_HEADER_SIZE (ResTable::IDMAP_HEADER_SIZE_BYTES / sizeof(uint32_t))
-
-static void printToLogFunc(void* cookie, const char* txt)
-{
-    ALOGV("%s", txt);
-}
-
-// Standard C isspace() is only required to look at the low byte of its input, so
-// produces incorrect results for UTF-16 characters.  For safety's sake, assume that
-// any high-byte UTF-16 code point is not whitespace.
-inline int isspace16(char16_t c) {
-    return (c < 0x0080 && isspace(c));
-}
-
-// range checked; guaranteed to NUL-terminate within the stated number of available slots
-// NOTE: if this truncates the dst string due to running out of space, no attempt is
-// made to avoid splitting surrogate pairs.
-static void strcpy16_dtoh(uint16_t* dst, const uint16_t* src, size_t avail)
-{
-    uint16_t* last = dst + avail - 1;
-    while (*src && (dst < last)) {
-        char16_t s = dtohs(*src);
-        *dst++ = s;
-        src++;
-    }
-    *dst = 0;
-}
-
-static status_t validate_chunk(const ResChunk_header* chunk,
-                               size_t minSize,
-                               const uint8_t* dataEnd,
-                               const char* name)
-{
-    const uint16_t headerSize = dtohs(chunk->headerSize);
-    const uint32_t size = dtohl(chunk->size);
-
-    if (headerSize >= minSize) {
-        if (headerSize <= size) {
-            if (((headerSize|size)&0x3) == 0) {
-                if ((ssize_t)size <= (dataEnd-((const uint8_t*)chunk))) {
-                    return NO_ERROR;
-                }
-                ALOGW("%s data size %p extends beyond resource end %p.",
-                     name, (void*)size,
-                     (void*)(dataEnd-((const uint8_t*)chunk)));
-                return BAD_TYPE;
-            }
-            ALOGW("%s size 0x%x or headerSize 0x%x is not on an integer boundary.",
-                 name, (int)size, (int)headerSize);
-            return BAD_TYPE;
-        }
-        ALOGW("%s size %p is smaller than header size %p.",
-             name, (void*)size, (void*)(int)headerSize);
-        return BAD_TYPE;
-    }
-    ALOGW("%s header size %p is too small.",
-         name, (void*)(int)headerSize);
-    return BAD_TYPE;
-}
-
-inline void Res_value::copyFrom_dtoh(const Res_value& src)
-{
-    size = dtohs(src.size);
-    res0 = src.res0;
-    dataType = src.dataType;
-    data = dtohl(src.data);
-}
-
-void Res_png_9patch::deviceToFile()
-{
-    for (int i = 0; i < numXDivs; i++) {
-        xDivs[i] = htonl(xDivs[i]);
-    }
-    for (int i = 0; i < numYDivs; i++) {
-        yDivs[i] = htonl(yDivs[i]);
-    }
-    paddingLeft = htonl(paddingLeft);
-    paddingRight = htonl(paddingRight);
-    paddingTop = htonl(paddingTop);
-    paddingBottom = htonl(paddingBottom);
-    for (int i=0; i<numColors; i++) {
-        colors[i] = htonl(colors[i]);
-    }
-}
-
-void Res_png_9patch::fileToDevice()
-{
-    for (int i = 0; i < numXDivs; i++) {
-        xDivs[i] = ntohl(xDivs[i]);
-    }
-    for (int i = 0; i < numYDivs; i++) {
-        yDivs[i] = ntohl(yDivs[i]);
-    }
-    paddingLeft = ntohl(paddingLeft);
-    paddingRight = ntohl(paddingRight);
-    paddingTop = ntohl(paddingTop);
-    paddingBottom = ntohl(paddingBottom);
-    for (int i=0; i<numColors; i++) {
-        colors[i] = ntohl(colors[i]);
-    }
-}
-
-size_t Res_png_9patch::serializedSize()
-{
-    // The size of this struct is 32 bytes on the 32-bit target system
-    // 4 * int8_t
-    // 4 * int32_t
-    // 3 * pointer
-    return 32
-            + numXDivs * sizeof(int32_t)
-            + numYDivs * sizeof(int32_t)
-            + numColors * sizeof(uint32_t);
-}
-
-void* Res_png_9patch::serialize()
-{
-    // Use calloc since we're going to leave a few holes in the data
-    // and want this to run cleanly under valgrind
-    void* newData = calloc(1, serializedSize());
-    serialize(newData);
-    return newData;
-}
-
-void Res_png_9patch::serialize(void * outData)
-{
-    char* data = (char*) outData;
-    memmove(data, &wasDeserialized, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
-    memmove(data + 12, &paddingLeft, 16);   // copy paddingXXXX
-    data += 32;
-
-    memmove(data, this->xDivs, numXDivs * sizeof(int32_t));
-    data +=  numXDivs * sizeof(int32_t);
-    memmove(data, this->yDivs, numYDivs * sizeof(int32_t));
-    data +=  numYDivs * sizeof(int32_t);
-    memmove(data, this->colors, numColors * sizeof(uint32_t));
-}
-
-static void deserializeInternal(const void* inData, Res_png_9patch* outData) {
-    char* patch = (char*) inData;
-    if (inData != outData) {
-        memmove(&outData->wasDeserialized, patch, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
-        memmove(&outData->paddingLeft, patch + 12, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
-    }
-    outData->wasDeserialized = true;
-    char* data = (char*)outData;
-    data +=  sizeof(Res_png_9patch);
-    outData->xDivs = (int32_t*) data;
-    data +=  outData->numXDivs * sizeof(int32_t);
-    outData->yDivs = (int32_t*) data;
-    data +=  outData->numYDivs * sizeof(int32_t);
-    outData->colors = (uint32_t*) data;
-}
-
-static bool assertIdmapHeader(const uint32_t* map, size_t sizeBytes)
-{
-    if (sizeBytes < ResTable::IDMAP_HEADER_SIZE_BYTES) {
-        ALOGW("idmap assertion failed: size=%d bytes\n", (int)sizeBytes);
-        return false;
-    }
-    if (*map != htodl(IDMAP_MAGIC)) { // htodl: map data expected to be in correct endianess
-        ALOGW("idmap assertion failed: invalid magic found (is 0x%08x, expected 0x%08x)\n",
-             *map, htodl(IDMAP_MAGIC));
-        return false;
-    }
-    return true;
-}
-
-static status_t idmapLookup(const uint32_t* map, size_t sizeBytes, uint32_t key, uint32_t* outValue)
-{
-    // see README for details on the format of map
-    if (!assertIdmapHeader(map, sizeBytes)) {
-        return UNKNOWN_ERROR;
-    }
-    map = map + IDMAP_HEADER_SIZE; // skip ahead to data segment
-    // size of data block, in uint32_t
-    const size_t size = (sizeBytes - ResTable::IDMAP_HEADER_SIZE_BYTES) / sizeof(uint32_t);
-    const uint32_t type = Res_GETTYPE(key) + 1; // add one, idmap stores "public" type id
-    const uint32_t entry = Res_GETENTRY(key);
-    const uint32_t typeCount = *map;
-
-    if (type > typeCount) {
-        ALOGW("Resource ID map: type=%d exceeds number of types=%d\n", type, typeCount);
-        return UNKNOWN_ERROR;
-    }
-    if (typeCount > size) {
-        ALOGW("Resource ID map: number of types=%d exceeds size of map=%d\n", typeCount, (int)size);
-        return UNKNOWN_ERROR;
-    }
-    const uint32_t typeOffset = map[type];
-    if (typeOffset == 0) {
-        *outValue = 0;
-        return NO_ERROR;
-    }
-    if (typeOffset + 1 > size) {
-        ALOGW("Resource ID map: type offset=%d exceeds reasonable value, size of map=%d\n",
-             typeOffset, (int)size);
-        return UNKNOWN_ERROR;
-    }
-    const uint32_t entryCount = map[typeOffset];
-    const uint32_t entryOffset = map[typeOffset + 1];
-    if (entryCount == 0 || entry < entryOffset || entry - entryOffset > entryCount - 1) {
-        *outValue = 0;
-        return NO_ERROR;
-    }
-    const uint32_t index = typeOffset + 2 + entry - entryOffset;
-    if (index > size) {
-        ALOGW("Resource ID map: entry index=%d exceeds size of map=%d\n", index, (int)size);
-        *outValue = 0;
-        return NO_ERROR;
-    }
-    *outValue = map[index];
-
-    return NO_ERROR;
-}
-
-static status_t getIdmapPackageId(const uint32_t* map, size_t mapSize, uint32_t *outId)
-{
-    if (!assertIdmapHeader(map, mapSize)) {
-        return UNKNOWN_ERROR;
-    }
-    const uint32_t* p = map + IDMAP_HEADER_SIZE + 1;
-    while (*p == 0) {
-        ++p;
-    }
-    *outId = (map[*p + IDMAP_HEADER_SIZE + 2] >> 24) & 0x000000ff;
-    return NO_ERROR;
-}
-
-Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
-{
-    if (sizeof(void*) != sizeof(int32_t)) {
-        ALOGE("Cannot deserialize on non 32-bit system\n");
-        return NULL;
-    }
-    deserializeInternal(inData, (Res_png_9patch*) inData);
-    return (Res_png_9patch*) inData;
-}
-
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-
-ResStringPool::ResStringPool()
-    : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)
-{
-}
-
-ResStringPool::ResStringPool(const void* data, size_t size, bool copyData)
-    : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)
-{
-    setTo(data, size, copyData);
-}
-
-ResStringPool::~ResStringPool()
-{
-    uninit();
-}
-
-status_t ResStringPool::setTo(const void* data, size_t size, bool copyData)
-{
-    if (!data || !size) {
-        return (mError=BAD_TYPE);
-    }
-
-    uninit();
-
-    const bool notDeviceEndian = htods(0xf0) != 0xf0;
-
-    if (copyData || notDeviceEndian) {
-        mOwnedData = malloc(size);
-        if (mOwnedData == NULL) {
-            return (mError=NO_MEMORY);
-        }
-        memcpy(mOwnedData, data, size);
-        data = mOwnedData;
-    }
-
-    mHeader = (const ResStringPool_header*)data;
-
-    if (notDeviceEndian) {
-        ResStringPool_header* h = const_cast<ResStringPool_header*>(mHeader);
-        h->header.headerSize = dtohs(mHeader->header.headerSize);
-        h->header.type = dtohs(mHeader->header.type);
-        h->header.size = dtohl(mHeader->header.size);
-        h->stringCount = dtohl(mHeader->stringCount);
-        h->styleCount = dtohl(mHeader->styleCount);
-        h->flags = dtohl(mHeader->flags);
-        h->stringsStart = dtohl(mHeader->stringsStart);
-        h->stylesStart = dtohl(mHeader->stylesStart);
-    }
-
-    if (mHeader->header.headerSize > mHeader->header.size
-            || mHeader->header.size > size) {
-        ALOGW("Bad string block: header size %d or total size %d is larger than data size %d\n",
-                (int)mHeader->header.headerSize, (int)mHeader->header.size, (int)size);
-        return (mError=BAD_TYPE);
-    }
-    mSize = mHeader->header.size;
-    mEntries = (const uint32_t*)
-        (((const uint8_t*)data)+mHeader->header.headerSize);
-
-    if (mHeader->stringCount > 0) {
-        if ((mHeader->stringCount*sizeof(uint32_t) < mHeader->stringCount)  // uint32 overflow?
-            || (mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t)))
-                > size) {
-            ALOGW("Bad string block: entry of %d items extends past data size %d\n",
-                    (int)(mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t))),
-                    (int)size);
-            return (mError=BAD_TYPE);
-        }
-
-        size_t charSize;
-        if (mHeader->flags&ResStringPool_header::UTF8_FLAG) {
-            charSize = sizeof(uint8_t);
-        } else {
-            charSize = sizeof(char16_t);
-        }
-
-        mStrings = (const void*)
-            (((const uint8_t*)data)+mHeader->stringsStart);
-        if (mHeader->stringsStart >= (mHeader->header.size-sizeof(uint16_t))) {
-            ALOGW("Bad string block: string pool starts at %d, after total size %d\n",
-                    (int)mHeader->stringsStart, (int)mHeader->header.size);
-            return (mError=BAD_TYPE);
-        }
-        if (mHeader->styleCount == 0) {
-            mStringPoolSize =
-                (mHeader->header.size-mHeader->stringsStart)/charSize;
-        } else {
-            // check invariant: styles starts before end of data
-            if (mHeader->stylesStart >= (mHeader->header.size-sizeof(uint16_t))) {
-                ALOGW("Bad style block: style block starts at %d past data size of %d\n",
-                    (int)mHeader->stylesStart, (int)mHeader->header.size);
-                return (mError=BAD_TYPE);
-            }
-            // check invariant: styles follow the strings
-            if (mHeader->stylesStart <= mHeader->stringsStart) {
-                ALOGW("Bad style block: style block starts at %d, before strings at %d\n",
-                    (int)mHeader->stylesStart, (int)mHeader->stringsStart);
-                return (mError=BAD_TYPE);
-            }
-            mStringPoolSize =
-                (mHeader->stylesStart-mHeader->stringsStart)/charSize;
-        }
-
-        // check invariant: stringCount > 0 requires a string pool to exist
-        if (mStringPoolSize == 0) {
-            ALOGW("Bad string block: stringCount is %d but pool size is 0\n", (int)mHeader->stringCount);
-            return (mError=BAD_TYPE);
-        }
-
-        if (notDeviceEndian) {
-            size_t i;
-            uint32_t* e = const_cast<uint32_t*>(mEntries);
-            for (i=0; i<mHeader->stringCount; i++) {
-                e[i] = dtohl(mEntries[i]);
-            }
-            if (!(mHeader->flags&ResStringPool_header::UTF8_FLAG)) {
-                const char16_t* strings = (const char16_t*)mStrings;
-                char16_t* s = const_cast<char16_t*>(strings);
-                for (i=0; i<mStringPoolSize; i++) {
-                    s[i] = dtohs(strings[i]);
-                }
-            }
-        }
-
-        if ((mHeader->flags&ResStringPool_header::UTF8_FLAG &&
-                ((uint8_t*)mStrings)[mStringPoolSize-1] != 0) ||
-                (!mHeader->flags&ResStringPool_header::UTF8_FLAG &&
-                ((char16_t*)mStrings)[mStringPoolSize-1] != 0)) {
-            ALOGW("Bad string block: last string is not 0-terminated\n");
-            return (mError=BAD_TYPE);
-        }
-    } else {
-        mStrings = NULL;
-        mStringPoolSize = 0;
-    }
-
-    if (mHeader->styleCount > 0) {
-        mEntryStyles = mEntries + mHeader->stringCount;
-        // invariant: integer overflow in calculating mEntryStyles
-        if (mEntryStyles < mEntries) {
-            ALOGW("Bad string block: integer overflow finding styles\n");
-            return (mError=BAD_TYPE);
-        }
-
-        if (((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader) > (int)size) {
-            ALOGW("Bad string block: entry of %d styles extends past data size %d\n",
-                    (int)((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader),
-                    (int)size);
-            return (mError=BAD_TYPE);
-        }
-        mStyles = (const uint32_t*)
-            (((const uint8_t*)data)+mHeader->stylesStart);
-        if (mHeader->stylesStart >= mHeader->header.size) {
-            ALOGW("Bad string block: style pool starts %d, after total size %d\n",
-                    (int)mHeader->stylesStart, (int)mHeader->header.size);
-            return (mError=BAD_TYPE);
-        }
-        mStylePoolSize =
-            (mHeader->header.size-mHeader->stylesStart)/sizeof(uint32_t);
-
-        if (notDeviceEndian) {
-            size_t i;
-            uint32_t* e = const_cast<uint32_t*>(mEntryStyles);
-            for (i=0; i<mHeader->styleCount; i++) {
-                e[i] = dtohl(mEntryStyles[i]);
-            }
-            uint32_t* s = const_cast<uint32_t*>(mStyles);
-            for (i=0; i<mStylePoolSize; i++) {
-                s[i] = dtohl(mStyles[i]);
-            }
-        }
-
-        const ResStringPool_span endSpan = {
-            { htodl(ResStringPool_span::END) },
-            htodl(ResStringPool_span::END), htodl(ResStringPool_span::END)
-        };
-        if (memcmp(&mStyles[mStylePoolSize-(sizeof(endSpan)/sizeof(uint32_t))],
-                   &endSpan, sizeof(endSpan)) != 0) {
-            ALOGW("Bad string block: last style is not 0xFFFFFFFF-terminated\n");
-            return (mError=BAD_TYPE);
-        }
-    } else {
-        mEntryStyles = NULL;
-        mStyles = NULL;
-        mStylePoolSize = 0;
-    }
-
-    return (mError=NO_ERROR);
-}
-
-status_t ResStringPool::getError() const
-{
-    return mError;
-}
-
-void ResStringPool::uninit()
-{
-    mError = NO_INIT;
-    if (mHeader != NULL && mCache != NULL) {
-        for (size_t x = 0; x < mHeader->stringCount; x++) {
-            if (mCache[x] != NULL) {
-                free(mCache[x]);
-                mCache[x] = NULL;
-            }
-        }
-        free(mCache);
-        mCache = NULL;
-    }
-    if (mOwnedData) {
-        free(mOwnedData);
-        mOwnedData = NULL;
-    }
-}
-
-/**
- * Strings in UTF-16 format have length indicated by a length encoded in the
- * stored data. It is either 1 or 2 characters of length data. This allows a
- * maximum length of 0x7FFFFFF (2147483647 bytes), but if you're storing that
- * much data in a string, you're abusing them.
- *
- * If the high bit is set, then there are two characters or 4 bytes of length
- * data encoded. In that case, drop the high bit of the first character and
- * add it together with the next character.
- */
-static inline size_t
-decodeLength(const char16_t** str)
-{
-    size_t len = **str;
-    if ((len & 0x8000) != 0) {
-        (*str)++;
-        len = ((len & 0x7FFF) << 16) | **str;
-    }
-    (*str)++;
-    return len;
-}
-
-/**
- * Strings in UTF-8 format have length indicated by a length encoded in the
- * stored data. It is either 1 or 2 characters of length data. This allows a
- * maximum length of 0x7FFF (32767 bytes), but you should consider storing
- * text in another way if you're using that much data in a single string.
- *
- * If the high bit is set, then there are two characters or 2 bytes of length
- * data encoded. In that case, drop the high bit of the first character and
- * add it together with the next character.
- */
-static inline size_t
-decodeLength(const uint8_t** str)
-{
-    size_t len = **str;
-    if ((len & 0x80) != 0) {
-        (*str)++;
-        len = ((len & 0x7F) << 8) | **str;
-    }
-    (*str)++;
-    return len;
-}
-
-const uint16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const
-{
-    if (mError == NO_ERROR && idx < mHeader->stringCount) {
-        const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;
-        const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t));
-        if (off < (mStringPoolSize-1)) {
-            if (!isUTF8) {
-                const char16_t* strings = (char16_t*)mStrings;
-                const char16_t* str = strings+off;
-
-                *u16len = decodeLength(&str);
-                if ((uint32_t)(str+*u16len-strings) < mStringPoolSize) {
-                    return str;
-                } else {
-                    ALOGW("Bad string block: string #%d extends to %d, past end at %d\n",
-                            (int)idx, (int)(str+*u16len-strings), (int)mStringPoolSize);
-                }
-            } else {
-                const uint8_t* strings = (uint8_t*)mStrings;
-                const uint8_t* u8str = strings+off;
-
-                *u16len = decodeLength(&u8str);
-                size_t u8len = decodeLength(&u8str);
-
-                // encLen must be less than 0x7FFF due to encoding.
-                if ((uint32_t)(u8str+u8len-strings) < mStringPoolSize) {
-                    AutoMutex lock(mDecodeLock);
-
-                    if (mCache == NULL) {
-#ifndef HAVE_ANDROID_OS
-                        STRING_POOL_NOISY(ALOGI("CREATING STRING CACHE OF %d bytes",
-                                mHeader->stringCount*sizeof(char16_t**)));
-#else
-                        // We do not want to be in this case when actually running Android.
-                        ALOGW("CREATING STRING CACHE OF %d bytes",
-                                mHeader->stringCount*sizeof(char16_t**));
-#endif
-                        mCache = (char16_t**)calloc(mHeader->stringCount, sizeof(char16_t**));
-                        if (mCache == NULL) {
-                            ALOGW("No memory trying to allocate decode cache table of %d bytes\n",
-                                    (int)(mHeader->stringCount*sizeof(char16_t**)));
-                            return NULL;
-                        }
-                    }
-
-                    if (mCache[idx] != NULL) {
-                        return mCache[idx];
-                    }
-
-                    ssize_t actualLen = utf8_to_utf16_length(u8str, u8len);
-                    if (actualLen < 0 || (size_t)actualLen != *u16len) {
-                        ALOGW("Bad string block: string #%lld decoded length is not correct "
-                                "%lld vs %llu\n",
-                                (long long)idx, (long long)actualLen, (long long)*u16len);
-                        return NULL;
-                    }
-
-                    char16_t *u16str = (char16_t *)calloc(*u16len+1, sizeof(char16_t));
-                    if (!u16str) {
-                        ALOGW("No memory when trying to allocate decode cache for string #%d\n",
-                                (int)idx);
-                        return NULL;
-                    }
-
-                    STRING_POOL_NOISY(ALOGI("Caching UTF8 string: %s", u8str));
-                    utf8_to_utf16(u8str, u8len, u16str);
-                    mCache[idx] = u16str;
-                    return u16str;
-                } else {
-                    ALOGW("Bad string block: string #%lld extends to %lld, past end at %lld\n",
-                            (long long)idx, (long long)(u8str+u8len-strings),
-                            (long long)mStringPoolSize);
-                }
-            }
-        } else {
-            ALOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
-                    (int)idx, (int)(off*sizeof(uint16_t)),
-                    (int)(mStringPoolSize*sizeof(uint16_t)));
-        }
-    }
-    return NULL;
-}
-
-const char* ResStringPool::string8At(size_t idx, size_t* outLen) const
-{
-    if (mError == NO_ERROR && idx < mHeader->stringCount) {
-        if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) == 0) {
-            return NULL;
-        }
-        const uint32_t off = mEntries[idx]/sizeof(char);
-        if (off < (mStringPoolSize-1)) {
-            const uint8_t* strings = (uint8_t*)mStrings;
-            const uint8_t* str = strings+off;
-            *outLen = decodeLength(&str);
-            size_t encLen = decodeLength(&str);
-            if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {
-                return (const char*)str;
-            } else {
-                ALOGW("Bad string block: string #%d extends to %d, past end at %d\n",
-                        (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize);
-            }
-        } else {
-            ALOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
-                    (int)idx, (int)(off*sizeof(uint16_t)),
-                    (int)(mStringPoolSize*sizeof(uint16_t)));
-        }
-    }
-    return NULL;
-}
-
-const String8 ResStringPool::string8ObjectAt(size_t idx) const
-{
-    size_t len;
-    const char *str = (const char*)string8At(idx, &len);
-    if (str != NULL) {
-        return String8(str);
-    }
-    return String8(stringAt(idx, &len));
-}
-
-const ResStringPool_span* ResStringPool::styleAt(const ResStringPool_ref& ref) const
-{
-    return styleAt(ref.index);
-}
-
-const ResStringPool_span* ResStringPool::styleAt(size_t idx) const
-{
-    if (mError == NO_ERROR && idx < mHeader->styleCount) {
-        const uint32_t off = (mEntryStyles[idx]/sizeof(uint32_t));
-        if (off < mStylePoolSize) {
-            return (const ResStringPool_span*)(mStyles+off);
-        } else {
-            ALOGW("Bad string block: style #%d entry is at %d, past end at %d\n",
-                    (int)idx, (int)(off*sizeof(uint32_t)),
-                    (int)(mStylePoolSize*sizeof(uint32_t)));
-        }
-    }
-    return NULL;
-}
-
-ssize_t ResStringPool::indexOfString(const char16_t* str, size_t strLen) const
-{
-    if (mError != NO_ERROR) {
-        return mError;
-    }
-
-    size_t len;
-
-    if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0) {
-        STRING_POOL_NOISY(ALOGI("indexOfString UTF-8: %s", String8(str, strLen).string()));
-
-        // The string pool contains UTF 8 strings; we don't want to cause
-        // temporary UTF-16 strings to be created as we search.
-        if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
-            // Do a binary search for the string...  this is a little tricky,
-            // because the strings are sorted with strzcmp16().  So to match
-            // the ordering, we need to convert strings in the pool to UTF-16.
-            // But we don't want to hit the cache, so instead we will have a
-            // local temporary allocation for the conversions.
-            char16_t* convBuffer = (char16_t*)malloc(strLen+4);
-            ssize_t l = 0;
-            ssize_t h = mHeader->stringCount-1;
-
-            ssize_t mid;
-            while (l <= h) {
-                mid = l + (h - l)/2;
-                const uint8_t* s = (const uint8_t*)string8At(mid, &len);
-                int c;
-                if (s != NULL) {
-                    char16_t* end = utf8_to_utf16_n(s, len, convBuffer, strLen+3);
-                    *end = 0;
-                    c = strzcmp16(convBuffer, end-convBuffer, str, strLen);
-                } else {
-                    c = -1;
-                }
-                STRING_POOL_NOISY(ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
-                             (const char*)s, c, (int)l, (int)mid, (int)h));
-                if (c == 0) {
-                    STRING_POOL_NOISY(ALOGI("MATCH!"));
-                    free(convBuffer);
-                    return mid;
-                } else if (c < 0) {
-                    l = mid + 1;
-                } else {
-                    h = mid - 1;
-                }
-            }
-            free(convBuffer);
-        } else {
-            // It is unusual to get the ID from an unsorted string block...
-            // most often this happens because we want to get IDs for style
-            // span tags; since those always appear at the end of the string
-            // block, start searching at the back.
-            String8 str8(str, strLen);
-            const size_t str8Len = str8.size();
-            for (int i=mHeader->stringCount-1; i>=0; i--) {
-                const char* s = string8At(i, &len);
-                STRING_POOL_NOISY(ALOGI("Looking at %s, i=%d\n",
-                             String8(s).string(),
-                             i));
-                if (s && str8Len == len && memcmp(s, str8.string(), str8Len) == 0) {
-                    STRING_POOL_NOISY(ALOGI("MATCH!"));
-                    return i;
-                }
-            }
-        }
-
-    } else {
-        STRING_POOL_NOISY(ALOGI("indexOfString UTF-16: %s", String8(str, strLen).string()));
-
-        if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
-            // Do a binary search for the string...
-            ssize_t l = 0;
-            ssize_t h = mHeader->stringCount-1;
-
-            ssize_t mid;
-            while (l <= h) {
-                mid = l + (h - l)/2;
-                const char16_t* s = stringAt(mid, &len);
-                int c = s ? strzcmp16(s, len, str, strLen) : -1;
-                STRING_POOL_NOISY(ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
-                             String8(s).string(),
-                             c, (int)l, (int)mid, (int)h));
-                if (c == 0) {
-                    STRING_POOL_NOISY(ALOGI("MATCH!"));
-                    return mid;
-                } else if (c < 0) {
-                    l = mid + 1;
-                } else {
-                    h = mid - 1;
-                }
-            }
-        } else {
-            // It is unusual to get the ID from an unsorted string block...
-            // most often this happens because we want to get IDs for style
-            // span tags; since those always appear at the end of the string
-            // block, start searching at the back.
-            for (int i=mHeader->stringCount-1; i>=0; i--) {
-                const char16_t* s = stringAt(i, &len);
-                STRING_POOL_NOISY(ALOGI("Looking at %s, i=%d\n",
-                             String8(s).string(),
-                             i));
-                if (s && strLen == len && strzcmp16(s, len, str, strLen) == 0) {
-                    STRING_POOL_NOISY(ALOGI("MATCH!"));
-                    return i;
-                }
-            }
-        }
-    }
-
-    return NAME_NOT_FOUND;
-}
-
-size_t ResStringPool::size() const
-{
-    return (mError == NO_ERROR) ? mHeader->stringCount : 0;
-}
-
-size_t ResStringPool::styleCount() const
-{
-    return (mError == NO_ERROR) ? mHeader->styleCount : 0;
-}
-
-size_t ResStringPool::bytes() const
-{
-    return (mError == NO_ERROR) ? mHeader->header.size : 0;
-}
-
-bool ResStringPool::isSorted() const
-{
-    return (mHeader->flags&ResStringPool_header::SORTED_FLAG)!=0;
-}
-
-bool ResStringPool::isUTF8() const
-{
-    return (mHeader->flags&ResStringPool_header::UTF8_FLAG)!=0;
-}
-
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-
-ResXMLParser::ResXMLParser(const ResXMLTree& tree)
-    : mTree(tree), mEventCode(BAD_DOCUMENT)
-{
-}
-
-void ResXMLParser::restart()
-{
-    mCurNode = NULL;
-    mEventCode = mTree.mError == NO_ERROR ? START_DOCUMENT : BAD_DOCUMENT;
-}
-const ResStringPool& ResXMLParser::getStrings() const
-{
-    return mTree.mStrings;
-}
-
-ResXMLParser::event_code_t ResXMLParser::getEventType() const
-{
-    return mEventCode;
-}
-
-ResXMLParser::event_code_t ResXMLParser::next()
-{
-    if (mEventCode == START_DOCUMENT) {
-        mCurNode = mTree.mRootNode;
-        mCurExt = mTree.mRootExt;
-        return (mEventCode=mTree.mRootCode);
-    } else if (mEventCode >= FIRST_CHUNK_CODE) {
-        return nextNode();
-    }
-    return mEventCode;
-}
-
-int32_t ResXMLParser::getCommentID() const
-{
-    return mCurNode != NULL ? dtohl(mCurNode->comment.index) : -1;
-}
-
-const uint16_t* ResXMLParser::getComment(size_t* outLen) const
-{
-    int32_t id = getCommentID();
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-uint32_t ResXMLParser::getLineNumber() const
-{
-    return mCurNode != NULL ? dtohl(mCurNode->lineNumber) : -1;
-}
-
-int32_t ResXMLParser::getTextID() const
-{
-    if (mEventCode == TEXT) {
-        return dtohl(((const ResXMLTree_cdataExt*)mCurExt)->data.index);
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getText(size_t* outLen) const
-{
-    int32_t id = getTextID();
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-ssize_t ResXMLParser::getTextValue(Res_value* outValue) const
-{
-    if (mEventCode == TEXT) {
-        outValue->copyFrom_dtoh(((const ResXMLTree_cdataExt*)mCurExt)->typedData);
-        return sizeof(Res_value);
-    }
-    return BAD_TYPE;
-}
-
-int32_t ResXMLParser::getNamespacePrefixID() const
-{
-    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {
-        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->prefix.index);
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const
-{
-    int32_t id = getNamespacePrefixID();
-    //printf("prefix=%d  event=%p\n", id, mEventCode);
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-int32_t ResXMLParser::getNamespaceUriID() const
-{
-    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {
-        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->uri.index);
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const
-{
-    int32_t id = getNamespaceUriID();
-    //printf("uri=%d  event=%p\n", id, mEventCode);
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-int32_t ResXMLParser::getElementNamespaceID() const
-{
-    if (mEventCode == START_TAG) {
-        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->ns.index);
-    }
-    if (mEventCode == END_TAG) {
-        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->ns.index);
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getElementNamespace(size_t* outLen) const
-{
-    int32_t id = getElementNamespaceID();
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-int32_t ResXMLParser::getElementNameID() const
-{
-    if (mEventCode == START_TAG) {
-        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->name.index);
-    }
-    if (mEventCode == END_TAG) {
-        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->name.index);
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getElementName(size_t* outLen) const
-{
-    int32_t id = getElementNameID();
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-size_t ResXMLParser::getAttributeCount() const
-{
-    if (mEventCode == START_TAG) {
-        return dtohs(((const ResXMLTree_attrExt*)mCurExt)->attributeCount);
-    }
-    return 0;
-}
-
-int32_t ResXMLParser::getAttributeNamespaceID(size_t idx) const
-{
-    if (mEventCode == START_TAG) {
-        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
-        if (idx < dtohs(tag->attributeCount)) {
-            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
-                (((const uint8_t*)tag)
-                 + dtohs(tag->attributeStart)
-                 + (dtohs(tag->attributeSize)*idx));
-            return dtohl(attr->ns.index);
-        }
-    }
-    return -2;
-}
-
-const uint16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) const
-{
-    int32_t id = getAttributeNamespaceID(idx);
-    //printf("attribute namespace=%d  idx=%d  event=%p\n", id, idx, mEventCode);
-    //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id));
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-const char* ResXMLParser::getAttributeNamespace8(size_t idx, size_t* outLen) const
-{
-    int32_t id = getAttributeNamespaceID(idx);
-    //printf("attribute namespace=%d  idx=%d  event=%p\n", id, idx, mEventCode);
-    //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id));
-    return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL;
-}
-
-int32_t ResXMLParser::getAttributeNameID(size_t idx) const
-{
-    if (mEventCode == START_TAG) {
-        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
-        if (idx < dtohs(tag->attributeCount)) {
-            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
-                (((const uint8_t*)tag)
-                 + dtohs(tag->attributeStart)
-                 + (dtohs(tag->attributeSize)*idx));
-            return dtohl(attr->name.index);
-        }
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const
-{
-    int32_t id = getAttributeNameID(idx);
-    //printf("attribute name=%d  idx=%d  event=%p\n", id, idx, mEventCode);
-    //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id));
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-const char* ResXMLParser::getAttributeName8(size_t idx, size_t* outLen) const
-{
-    int32_t id = getAttributeNameID(idx);
-    //printf("attribute name=%d  idx=%d  event=%p\n", id, idx, mEventCode);
-    //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id));
-    return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL;
-}
-
-uint32_t ResXMLParser::getAttributeNameResID(size_t idx) const
-{
-    int32_t id = getAttributeNameID(idx);
-    if (id >= 0 && (size_t)id < mTree.mNumResIds) {
-        return dtohl(mTree.mResIds[id]);
-    }
-    return 0;
-}
-
-int32_t ResXMLParser::getAttributeValueStringID(size_t idx) const
-{
-    if (mEventCode == START_TAG) {
-        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
-        if (idx < dtohs(tag->attributeCount)) {
-            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
-                (((const uint8_t*)tag)
-                 + dtohs(tag->attributeStart)
-                 + (dtohs(tag->attributeSize)*idx));
-            return dtohl(attr->rawValue.index);
-        }
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const
-{
-    int32_t id = getAttributeValueStringID(idx);
-    //XML_NOISY(printf("getAttributeValue 0x%x=0x%x\n", idx, id));
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-int32_t ResXMLParser::getAttributeDataType(size_t idx) const
-{
-    if (mEventCode == START_TAG) {
-        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
-        if (idx < dtohs(tag->attributeCount)) {
-            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
-                (((const uint8_t*)tag)
-                 + dtohs(tag->attributeStart)
-                 + (dtohs(tag->attributeSize)*idx));
-            return attr->typedValue.dataType;
-        }
-    }
-    return Res_value::TYPE_NULL;
-}
-
-int32_t ResXMLParser::getAttributeData(size_t idx) const
-{
-    if (mEventCode == START_TAG) {
-        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
-        if (idx < dtohs(tag->attributeCount)) {
-            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
-                (((const uint8_t*)tag)
-                 + dtohs(tag->attributeStart)
-                 + (dtohs(tag->attributeSize)*idx));
-            return dtohl(attr->typedValue.data);
-        }
-    }
-    return 0;
-}
-
-ssize_t ResXMLParser::getAttributeValue(size_t idx, Res_value* outValue) const
-{
-    if (mEventCode == START_TAG) {
-        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
-        if (idx < dtohs(tag->attributeCount)) {
-            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
-                (((const uint8_t*)tag)
-                 + dtohs(tag->attributeStart)
-                 + (dtohs(tag->attributeSize)*idx));
-            outValue->copyFrom_dtoh(attr->typedValue);
-            return sizeof(Res_value);
-        }
-    }
-    return BAD_TYPE;
-}
-
-ssize_t ResXMLParser::indexOfAttribute(const char* ns, const char* attr) const
-{
-    String16 nsStr(ns != NULL ? ns : "");
-    String16 attrStr(attr);
-    return indexOfAttribute(ns ? nsStr.string() : NULL, ns ? nsStr.size() : 0,
-                            attrStr.string(), attrStr.size());
-}
-
-ssize_t ResXMLParser::indexOfAttribute(const char16_t* ns, size_t nsLen,
-                                       const char16_t* attr, size_t attrLen) const
-{
-    if (mEventCode == START_TAG) {
-        if (attr == NULL) {
-            return NAME_NOT_FOUND;
-        }
-        const size_t N = getAttributeCount();
-        if (mTree.mStrings.isUTF8()) {
-            String8 ns8, attr8;
-            if (ns != NULL) {
-                ns8 = String8(ns, nsLen);
-            }
-            attr8 = String8(attr, attrLen);
-            STRING_POOL_NOISY(ALOGI("indexOfAttribute UTF8 %s (%d) / %s (%d)", ns8.string(), nsLen,
-                    attr8.string(), attrLen));
-            for (size_t i=0; i<N; i++) {
-                size_t curNsLen = 0, curAttrLen = 0;
-                const char* curNs = getAttributeNamespace8(i, &curNsLen);
-                const char* curAttr = getAttributeName8(i, &curAttrLen);
-                STRING_POOL_NOISY(ALOGI("  curNs=%s (%d), curAttr=%s (%d)", curNs, curNsLen,
-                        curAttr, curAttrLen));
-                if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen
-                        && memcmp(attr8.string(), curAttr, attrLen) == 0) {
-                    if (ns == NULL) {
-                        if (curNs == NULL) {
-                            STRING_POOL_NOISY(ALOGI("  FOUND!"));
-                            return i;
-                        }
-                    } else if (curNs != NULL) {
-                        //printf(" --> ns=%s, curNs=%s\n",
-                        //       String8(ns).string(), String8(curNs).string());
-                        if (memcmp(ns8.string(), curNs, nsLen) == 0) {
-                            STRING_POOL_NOISY(ALOGI("  FOUND!"));
-                            return i;
-                        }
-                    }
-                }
-            }
-        } else {
-            STRING_POOL_NOISY(ALOGI("indexOfAttribute UTF16 %s (%d) / %s (%d)",
-                    String8(ns, nsLen).string(), nsLen,
-                    String8(attr, attrLen).string(), attrLen));
-            for (size_t i=0; i<N; i++) {
-                size_t curNsLen = 0, curAttrLen = 0;
-                const char16_t* curNs = getAttributeNamespace(i, &curNsLen);
-                const char16_t* curAttr = getAttributeName(i, &curAttrLen);
-                STRING_POOL_NOISY(ALOGI("  curNs=%s (%d), curAttr=%s (%d)",
-                        String8(curNs, curNsLen).string(), curNsLen,
-                        String8(curAttr, curAttrLen).string(), curAttrLen));
-                if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen
-                        && (memcmp(attr, curAttr, attrLen*sizeof(char16_t)) == 0)) {
-                    if (ns == NULL) {
-                        if (curNs == NULL) {
-                            STRING_POOL_NOISY(ALOGI("  FOUND!"));
-                            return i;
-                        }
-                    } else if (curNs != NULL) {
-                        //printf(" --> ns=%s, curNs=%s\n",
-                        //       String8(ns).string(), String8(curNs).string());
-                        if (memcmp(ns, curNs, nsLen*sizeof(char16_t)) == 0) {
-                            STRING_POOL_NOISY(ALOGI("  FOUND!"));
-                            return i;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    return NAME_NOT_FOUND;
-}
-
-ssize_t ResXMLParser::indexOfID() const
-{
-    if (mEventCode == START_TAG) {
-        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->idIndex);
-        if (idx > 0) return (idx-1);
-    }
-    return NAME_NOT_FOUND;
-}
-
-ssize_t ResXMLParser::indexOfClass() const
-{
-    if (mEventCode == START_TAG) {
-        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->classIndex);
-        if (idx > 0) return (idx-1);
-    }
-    return NAME_NOT_FOUND;
-}
-
-ssize_t ResXMLParser::indexOfStyle() const
-{
-    if (mEventCode == START_TAG) {
-        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->styleIndex);
-        if (idx > 0) return (idx-1);
-    }
-    return NAME_NOT_FOUND;
-}
-
-ResXMLParser::event_code_t ResXMLParser::nextNode()
-{
-    if (mEventCode < 0) {
-        return mEventCode;
-    }
-
-    do {
-        const ResXMLTree_node* next = (const ResXMLTree_node*)
-            (((const uint8_t*)mCurNode) + dtohl(mCurNode->header.size));
-        //ALOGW("Next node: prev=%p, next=%p\n", mCurNode, next);
-        
-        if (((const uint8_t*)next) >= mTree.mDataEnd) {
-            mCurNode = NULL;
-            return (mEventCode=END_DOCUMENT);
-        }
-
-        if (mTree.validateNode(next) != NO_ERROR) {
-            mCurNode = NULL;
-            return (mEventCode=BAD_DOCUMENT);
-        }
-
-        mCurNode = next;
-        const uint16_t headerSize = dtohs(next->header.headerSize);
-        const uint32_t totalSize = dtohl(next->header.size);
-        mCurExt = ((const uint8_t*)next) + headerSize;
-        size_t minExtSize = 0;
-        event_code_t eventCode = (event_code_t)dtohs(next->header.type);
-        switch ((mEventCode=eventCode)) {
-            case RES_XML_START_NAMESPACE_TYPE:
-            case RES_XML_END_NAMESPACE_TYPE:
-                minExtSize = sizeof(ResXMLTree_namespaceExt);
-                break;
-            case RES_XML_START_ELEMENT_TYPE:
-                minExtSize = sizeof(ResXMLTree_attrExt);
-                break;
-            case RES_XML_END_ELEMENT_TYPE:
-                minExtSize = sizeof(ResXMLTree_endElementExt);
-                break;
-            case RES_XML_CDATA_TYPE:
-                minExtSize = sizeof(ResXMLTree_cdataExt);
-                break;
-            default:
-                ALOGW("Unknown XML block: header type %d in node at %d\n",
-                     (int)dtohs(next->header.type),
-                     (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)));
-                continue;
-        }
-        
-        if ((totalSize-headerSize) < minExtSize) {
-            ALOGW("Bad XML block: header type 0x%x in node at 0x%x has size %d, need %d\n",
-                 (int)dtohs(next->header.type),
-                 (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)),
-                 (int)(totalSize-headerSize), (int)minExtSize);
-            return (mEventCode=BAD_DOCUMENT);
-        }
-        
-        //printf("CurNode=%p, CurExt=%p, headerSize=%d, minExtSize=%d\n",
-        //       mCurNode, mCurExt, headerSize, minExtSize);
-        
-        return eventCode;
-    } while (true);
-}
-
-void ResXMLParser::getPosition(ResXMLParser::ResXMLPosition* pos) const
-{
-    pos->eventCode = mEventCode;
-    pos->curNode = mCurNode;
-    pos->curExt = mCurExt;
-}
-
-void ResXMLParser::setPosition(const ResXMLParser::ResXMLPosition& pos)
-{
-    mEventCode = pos.eventCode;
-    mCurNode = pos.curNode;
-    mCurExt = pos.curExt;
-}
-
-
-// --------------------------------------------------------------------
-
-static volatile int32_t gCount = 0;
-
-ResXMLTree::ResXMLTree()
-    : ResXMLParser(*this)
-    , mError(NO_INIT), mOwnedData(NULL)
-{
-    //ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
-    restart();
-}
-
-ResXMLTree::ResXMLTree(const void* data, size_t size, bool copyData)
-    : ResXMLParser(*this)
-    , mError(NO_INIT), mOwnedData(NULL)
-{
-    //ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
-    setTo(data, size, copyData);
-}
-
-ResXMLTree::~ResXMLTree()
-{
-    //ALOGI("Destroying ResXMLTree in %p #%d\n", this, android_atomic_dec(&gCount)-1);
-    uninit();
-}
-
-status_t ResXMLTree::setTo(const void* data, size_t size, bool copyData)
-{
-    uninit();
-    mEventCode = START_DOCUMENT;
-
-    if (!data || !size) {
-        return (mError=BAD_TYPE);
-    }
-
-    if (copyData) {
-        mOwnedData = malloc(size);
-        if (mOwnedData == NULL) {
-            return (mError=NO_MEMORY);
-        }
-        memcpy(mOwnedData, data, size);
-        data = mOwnedData;
-    }
-
-    mHeader = (const ResXMLTree_header*)data;
-    mSize = dtohl(mHeader->header.size);
-    if (dtohs(mHeader->header.headerSize) > mSize || mSize > size) {
-        ALOGW("Bad XML block: header size %d or total size %d is larger than data size %d\n",
-             (int)dtohs(mHeader->header.headerSize),
-             (int)dtohl(mHeader->header.size), (int)size);
-        mError = BAD_TYPE;
-        restart();
-        return mError;
-    }
-    mDataEnd = ((const uint8_t*)mHeader) + mSize;
-
-    mStrings.uninit();
-    mRootNode = NULL;
-    mResIds = NULL;
-    mNumResIds = 0;
-
-    // First look for a couple interesting chunks: the string block
-    // and first XML node.
-    const ResChunk_header* chunk =
-        (const ResChunk_header*)(((const uint8_t*)mHeader) + dtohs(mHeader->header.headerSize));
-    const ResChunk_header* lastChunk = chunk;
-    while (((const uint8_t*)chunk) < (mDataEnd-sizeof(ResChunk_header)) &&
-           ((const uint8_t*)chunk) < (mDataEnd-dtohl(chunk->size))) {
-        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), mDataEnd, "XML");
-        if (err != NO_ERROR) {
-            mError = err;
-            goto done;
-        }
-        const uint16_t type = dtohs(chunk->type);
-        const size_t size = dtohl(chunk->size);
-        XML_NOISY(printf("Scanning @ %p: type=0x%x, size=0x%x\n",
-                     (void*)(((uint32_t)chunk)-((uint32_t)mHeader)), type, size));
-        if (type == RES_STRING_POOL_TYPE) {
-            mStrings.setTo(chunk, size);
-        } else if (type == RES_XML_RESOURCE_MAP_TYPE) {
-            mResIds = (const uint32_t*)
-                (((const uint8_t*)chunk)+dtohs(chunk->headerSize));
-            mNumResIds = (dtohl(chunk->size)-dtohs(chunk->headerSize))/sizeof(uint32_t);
-        } else if (type >= RES_XML_FIRST_CHUNK_TYPE
-                   && type <= RES_XML_LAST_CHUNK_TYPE) {
-            if (validateNode((const ResXMLTree_node*)chunk) != NO_ERROR) {
-                mError = BAD_TYPE;
-                goto done;
-            }
-            mCurNode = (const ResXMLTree_node*)lastChunk;
-            if (nextNode() == BAD_DOCUMENT) {
-                mError = BAD_TYPE;
-                goto done;
-            }
-            mRootNode = mCurNode;
-            mRootExt = mCurExt;
-            mRootCode = mEventCode;
-            break;
-        } else {
-            XML_NOISY(printf("Skipping unknown chunk!\n"));
-        }
-        lastChunk = chunk;
-        chunk = (const ResChunk_header*)
-            (((const uint8_t*)chunk) + size);
-    }
-
-    if (mRootNode == NULL) {
-        ALOGW("Bad XML block: no root element node found\n");
-        mError = BAD_TYPE;
-        goto done;
-    }
-
-    mError = mStrings.getError();
-
-done:
-    restart();
-    return mError;
-}
-
-status_t ResXMLTree::getError() const
-{
-    return mError;
-}
-
-void ResXMLTree::uninit()
-{
-    mError = NO_INIT;
-    mStrings.uninit();
-    if (mOwnedData) {
-        free(mOwnedData);
-        mOwnedData = NULL;
-    }
-    restart();
-}
-
-status_t ResXMLTree::validateNode(const ResXMLTree_node* node) const
-{
-    const uint16_t eventCode = dtohs(node->header.type);
-
-    status_t err = validate_chunk(
-        &node->header, sizeof(ResXMLTree_node),
-        mDataEnd, "ResXMLTree_node");
-
-    if (err >= NO_ERROR) {
-        // Only perform additional validation on START nodes
-        if (eventCode != RES_XML_START_ELEMENT_TYPE) {
-            return NO_ERROR;
-        }
-
-        const uint16_t headerSize = dtohs(node->header.headerSize);
-        const uint32_t size = dtohl(node->header.size);
-        const ResXMLTree_attrExt* attrExt = (const ResXMLTree_attrExt*)
-            (((const uint8_t*)node) + headerSize);
-        // check for sensical values pulled out of the stream so far...
-        if ((size >= headerSize + sizeof(ResXMLTree_attrExt))
-                && ((void*)attrExt > (void*)node)) {
-            const size_t attrSize = ((size_t)dtohs(attrExt->attributeSize))
-                * dtohs(attrExt->attributeCount);
-            if ((dtohs(attrExt->attributeStart)+attrSize) <= (size-headerSize)) {
-                return NO_ERROR;
-            }
-            ALOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n",
-                    (unsigned int)(dtohs(attrExt->attributeStart)+attrSize),
-                    (unsigned int)(size-headerSize));
-        }
-        else {
-            ALOGW("Bad XML start block: node header size 0x%x, size 0x%x\n",
-                (unsigned int)headerSize, (unsigned int)size);
-        }
-        return BAD_TYPE;
-    }
-
-    return err;
-
-#if 0
-    const bool isStart = dtohs(node->header.type) == RES_XML_START_ELEMENT_TYPE;
-
-    const uint16_t headerSize = dtohs(node->header.headerSize);
-    const uint32_t size = dtohl(node->header.size);
-
-    if (headerSize >= (isStart ? sizeof(ResXMLTree_attrNode) : sizeof(ResXMLTree_node))) {
-        if (size >= headerSize) {
-            if (((const uint8_t*)node) <= (mDataEnd-size)) {
-                if (!isStart) {
-                    return NO_ERROR;
-                }
-                if ((((size_t)dtohs(node->attributeSize))*dtohs(node->attributeCount))
-                        <= (size-headerSize)) {
-                    return NO_ERROR;
-                }
-                ALOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n",
-                        ((int)dtohs(node->attributeSize))*dtohs(node->attributeCount),
-                        (int)(size-headerSize));
-                return BAD_TYPE;
-            }
-            ALOGW("Bad XML block: node at 0x%x extends beyond data end 0x%x\n",
-                    (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), (int)mSize);
-            return BAD_TYPE;
-        }
-        ALOGW("Bad XML block: node at 0x%x header size 0x%x smaller than total size 0x%x\n",
-                (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),
-                (int)headerSize, (int)size);
-        return BAD_TYPE;
-    }
-    ALOGW("Bad XML block: node at 0x%x header size 0x%x too small\n",
-            (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),
-            (int)headerSize);
-    return BAD_TYPE;
-#endif
-}
-
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-
-void ResTable_config::copyFromDeviceNoSwap(const ResTable_config& o) {
-    const size_t size = dtohl(o.size);
-    if (size >= sizeof(ResTable_config)) {
-        *this = o;
-    } else {
-        memcpy(this, &o, size);
-        memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);
-    }
-}
-
-void ResTable_config::copyFromDtoH(const ResTable_config& o) {
-    copyFromDeviceNoSwap(o);
-    size = sizeof(ResTable_config);
-    mcc = dtohs(mcc);
-    mnc = dtohs(mnc);
-    density = dtohs(density);
-    screenWidth = dtohs(screenWidth);
-    screenHeight = dtohs(screenHeight);
-    sdkVersion = dtohs(sdkVersion);
-    minorVersion = dtohs(minorVersion);
-    smallestScreenWidthDp = dtohs(smallestScreenWidthDp);
-    screenWidthDp = dtohs(screenWidthDp);
-    screenHeightDp = dtohs(screenHeightDp);
-}
-
-void ResTable_config::swapHtoD() {
-    size = htodl(size);
-    mcc = htods(mcc);
-    mnc = htods(mnc);
-    density = htods(density);
-    screenWidth = htods(screenWidth);
-    screenHeight = htods(screenHeight);
-    sdkVersion = htods(sdkVersion);
-    minorVersion = htods(minorVersion);
-    smallestScreenWidthDp = htods(smallestScreenWidthDp);
-    screenWidthDp = htods(screenWidthDp);
-    screenHeightDp = htods(screenHeightDp);
-}
-
-int ResTable_config::compare(const ResTable_config& o) const {
-    int32_t diff = (int32_t)(imsi - o.imsi);
-    if (diff != 0) return diff;
-    diff = (int32_t)(locale - o.locale);
-    if (diff != 0) return diff;
-    diff = (int32_t)(screenType - o.screenType);
-    if (diff != 0) return diff;
-    diff = (int32_t)(input - o.input);
-    if (diff != 0) return diff;
-    diff = (int32_t)(screenSize - o.screenSize);
-    if (diff != 0) return diff;
-    diff = (int32_t)(version - o.version);
-    if (diff != 0) return diff;
-    diff = (int32_t)(screenLayout - o.screenLayout);
-    if (diff != 0) return diff;
-    diff = (int32_t)(uiMode - o.uiMode);
-    if (diff != 0) return diff;
-    diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp);
-    if (diff != 0) return diff;
-    diff = (int32_t)(screenSizeDp - o.screenSizeDp);
-    return (int)diff;
-}
-
-int ResTable_config::compareLogical(const ResTable_config& o) const {
-    if (mcc != o.mcc) {
-        return mcc < o.mcc ? -1 : 1;
-    }
-    if (mnc != o.mnc) {
-        return mnc < o.mnc ? -1 : 1;
-    }
-    if (language[0] != o.language[0]) {
-        return language[0] < o.language[0] ? -1 : 1;
-    }
-    if (language[1] != o.language[1]) {
-        return language[1] < o.language[1] ? -1 : 1;
-    }
-    if (country[0] != o.country[0]) {
-        return country[0] < o.country[0] ? -1 : 1;
-    }
-    if (country[1] != o.country[1]) {
-        return country[1] < o.country[1] ? -1 : 1;
-    }
-    if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) {
-        return (screenLayout & MASK_LAYOUTDIR) < (o.screenLayout & MASK_LAYOUTDIR) ? -1 : 1;
-    }
-    if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
-        return smallestScreenWidthDp < o.smallestScreenWidthDp ? -1 : 1;
-    }
-    if (screenWidthDp != o.screenWidthDp) {
-        return screenWidthDp < o.screenWidthDp ? -1 : 1;
-    }
-    if (screenHeightDp != o.screenHeightDp) {
-        return screenHeightDp < o.screenHeightDp ? -1 : 1;
-    }
-    if (screenWidth != o.screenWidth) {
-        return screenWidth < o.screenWidth ? -1 : 1;
-    }
-    if (screenHeight != o.screenHeight) {
-        return screenHeight < o.screenHeight ? -1 : 1;
-    }
-    if (density != o.density) {
-        return density < o.density ? -1 : 1;
-    }
-    if (orientation != o.orientation) {
-        return orientation < o.orientation ? -1 : 1;
-    }
-    if (touchscreen != o.touchscreen) {
-        return touchscreen < o.touchscreen ? -1 : 1;
-    }
-    if (input != o.input) {
-        return input < o.input ? -1 : 1;
-    }
-    if (screenLayout != o.screenLayout) {
-        return screenLayout < o.screenLayout ? -1 : 1;
-    }
-    if (uiMode != o.uiMode) {
-        return uiMode < o.uiMode ? -1 : 1;
-    }
-    if (version != o.version) {
-        return version < o.version ? -1 : 1;
-    }
-    return 0;
-}
-
-int ResTable_config::diff(const ResTable_config& o) const {
-    int diffs = 0;
-    if (mcc != o.mcc) diffs |= CONFIG_MCC;
-    if (mnc != o.mnc) diffs |= CONFIG_MNC;
-    if (locale != o.locale) diffs |= CONFIG_LOCALE;
-    if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;
-    if (density != o.density) diffs |= CONFIG_DENSITY;
-    if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;
-    if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0)
-            diffs |= CONFIG_KEYBOARD_HIDDEN;
-    if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;
-    if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
-    if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
-    if (version != o.version) diffs |= CONFIG_VERSION;
-    if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) diffs |= CONFIG_LAYOUTDIR;
-    if ((screenLayout & ~MASK_LAYOUTDIR) != (o.screenLayout & ~MASK_LAYOUTDIR)) diffs |= CONFIG_SCREEN_LAYOUT;
-    if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;
-    if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE;
-    if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE;
-    return diffs;
-}
-
-bool ResTable_config::isMoreSpecificThan(const ResTable_config& o) const {
-    // The order of the following tests defines the importance of one
-    // configuration parameter over another.  Those tests first are more
-    // important, trumping any values in those following them.
-    if (imsi || o.imsi) {
-        if (mcc != o.mcc) {
-            if (!mcc) return false;
-            if (!o.mcc) return true;
-        }
-
-        if (mnc != o.mnc) {
-            if (!mnc) return false;
-            if (!o.mnc) return true;
-        }
-    }
-
-    if (locale || o.locale) {
-        if (language[0] != o.language[0]) {
-            if (!language[0]) return false;
-            if (!o.language[0]) return true;
-        }
-
-        if (country[0] != o.country[0]) {
-            if (!country[0]) return false;
-            if (!o.country[0]) return true;
-        }
-    }
-
-    if (screenLayout || o.screenLayout) {
-        if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0) {
-            if (!(screenLayout & MASK_LAYOUTDIR)) return false;
-            if (!(o.screenLayout & MASK_LAYOUTDIR)) return true;
-        }
-    }
-
-    if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
-        if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
-            if (!smallestScreenWidthDp) return false;
-            if (!o.smallestScreenWidthDp) return true;
-        }
-    }
-
-    if (screenSizeDp || o.screenSizeDp) {
-        if (screenWidthDp != o.screenWidthDp) {
-            if (!screenWidthDp) return false;
-            if (!o.screenWidthDp) return true;
-        }
-
-        if (screenHeightDp != o.screenHeightDp) {
-            if (!screenHeightDp) return false;
-            if (!o.screenHeightDp) return true;
-        }
-    }
-
-    if (screenLayout || o.screenLayout) {
-        if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) {
-            if (!(screenLayout & MASK_SCREENSIZE)) return false;
-            if (!(o.screenLayout & MASK_SCREENSIZE)) return true;
-        }
-        if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) {
-            if (!(screenLayout & MASK_SCREENLONG)) return false;
-            if (!(o.screenLayout & MASK_SCREENLONG)) return true;
-        }
-    }
-
-    if (orientation != o.orientation) {
-        if (!orientation) return false;
-        if (!o.orientation) return true;
-    }
-
-    if (uiMode || o.uiMode) {
-        if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) {
-            if (!(uiMode & MASK_UI_MODE_TYPE)) return false;
-            if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true;
-        }
-        if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) {
-            if (!(uiMode & MASK_UI_MODE_NIGHT)) return false;
-            if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true;
-        }
-    }
-
-    // density is never 'more specific'
-    // as the default just equals 160
-
-    if (touchscreen != o.touchscreen) {
-        if (!touchscreen) return false;
-        if (!o.touchscreen) return true;
-    }
-
-    if (input || o.input) {
-        if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) {
-            if (!(inputFlags & MASK_KEYSHIDDEN)) return false;
-            if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true;
-        }
-
-        if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) {
-            if (!(inputFlags & MASK_NAVHIDDEN)) return false;
-            if (!(o.inputFlags & MASK_NAVHIDDEN)) return true;
-        }
-
-        if (keyboard != o.keyboard) {
-            if (!keyboard) return false;
-            if (!o.keyboard) return true;
-        }
-
-        if (navigation != o.navigation) {
-            if (!navigation) return false;
-            if (!o.navigation) return true;
-        }
-    }
-
-    if (screenSize || o.screenSize) {
-        if (screenWidth != o.screenWidth) {
-            if (!screenWidth) return false;
-            if (!o.screenWidth) return true;
-        }
-
-        if (screenHeight != o.screenHeight) {
-            if (!screenHeight) return false;
-            if (!o.screenHeight) return true;
-        }
-    }
-
-    if (version || o.version) {
-        if (sdkVersion != o.sdkVersion) {
-            if (!sdkVersion) return false;
-            if (!o.sdkVersion) return true;
-        }
-
-        if (minorVersion != o.minorVersion) {
-            if (!minorVersion) return false;
-            if (!o.minorVersion) return true;
-        }
-    }
-    return false;
-}
-
-bool ResTable_config::isBetterThan(const ResTable_config& o,
-        const ResTable_config* requested) const {
-    if (requested) {
-        if (imsi || o.imsi) {
-            if ((mcc != o.mcc) && requested->mcc) {
-                return (mcc);
-            }
-
-            if ((mnc != o.mnc) && requested->mnc) {
-                return (mnc);
-            }
-        }
-
-        if (locale || o.locale) {
-            if ((language[0] != o.language[0]) && requested->language[0]) {
-                return (language[0]);
-            }
-
-            if ((country[0] != o.country[0]) && requested->country[0]) {
-                return (country[0]);
-            }
-        }
-
-        if (screenLayout || o.screenLayout) {
-            if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0
-                    && (requested->screenLayout & MASK_LAYOUTDIR)) {
-                int myLayoutDir = screenLayout & MASK_LAYOUTDIR;
-                int oLayoutDir = o.screenLayout & MASK_LAYOUTDIR;
-                return (myLayoutDir > oLayoutDir);
-            }
-        }
-
-        if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
-            // The configuration closest to the actual size is best.
-            // We assume that larger configs have already been filtered
-            // out at this point.  That means we just want the largest one.
-            if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
-                return smallestScreenWidthDp > o.smallestScreenWidthDp;
-            }
-        }
-
-        if (screenSizeDp || o.screenSizeDp) {
-            // "Better" is based on the sum of the difference between both
-            // width and height from the requested dimensions.  We are
-            // assuming the invalid configs (with smaller dimens) have
-            // already been filtered.  Note that if a particular dimension
-            // is unspecified, we will end up with a large value (the
-            // difference between 0 and the requested dimension), which is
-            // good since we will prefer a config that has specified a
-            // dimension value.
-            int myDelta = 0, otherDelta = 0;
-            if (requested->screenWidthDp) {
-                myDelta += requested->screenWidthDp - screenWidthDp;
-                otherDelta += requested->screenWidthDp - o.screenWidthDp;
-            }
-            if (requested->screenHeightDp) {
-                myDelta += requested->screenHeightDp - screenHeightDp;
-                otherDelta += requested->screenHeightDp - o.screenHeightDp;
-            }
-            //ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
-            //    screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
-            //    requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
-            if (myDelta != otherDelta) {
-                return myDelta < otherDelta;
-            }
-        }
-
-        if (screenLayout || o.screenLayout) {
-            if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
-                    && (requested->screenLayout & MASK_SCREENSIZE)) {
-                // A little backwards compatibility here: undefined is
-                // considered equivalent to normal.  But only if the
-                // requested size is at least normal; otherwise, small
-                // is better than the default.
-                int mySL = (screenLayout & MASK_SCREENSIZE);
-                int oSL = (o.screenLayout & MASK_SCREENSIZE);
-                int fixedMySL = mySL;
-                int fixedOSL = oSL;
-                if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {
-                    if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;
-                    if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;
-                }
-                // For screen size, the best match is the one that is
-                // closest to the requested screen size, but not over
-                // (the not over part is dealt with in match() below).
-                if (fixedMySL == fixedOSL) {
-                    // If the two are the same, but 'this' is actually
-                    // undefined, then the other is really a better match.
-                    if (mySL == 0) return false;
-                    return true;
-                }
-                if (fixedMySL != fixedOSL) {
-                    return fixedMySL > fixedOSL;
-                }
-            }
-            if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
-                    && (requested->screenLayout & MASK_SCREENLONG)) {
-                return (screenLayout & MASK_SCREENLONG);
-            }
-        }
-
-        if ((orientation != o.orientation) && requested->orientation) {
-            return (orientation);
-        }
-
-        if (uiMode || o.uiMode) {
-            if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0
-                    && (requested->uiMode & MASK_UI_MODE_TYPE)) {
-                return (uiMode & MASK_UI_MODE_TYPE);
-            }
-            if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0
-                    && (requested->uiMode & MASK_UI_MODE_NIGHT)) {
-                return (uiMode & MASK_UI_MODE_NIGHT);
-            }
-        }
-
-        if (screenType || o.screenType) {
-            if (density != o.density) {
-                // density is tough.  Any density is potentially useful
-                // because the system will scale it.  Scaling down
-                // is generally better than scaling up.
-                // Default density counts as 160dpi (the system default)
-                // TODO - remove 160 constants
-                int h = (density?density:160);
-                int l = (o.density?o.density:160);
-                bool bImBigger = true;
-                if (l > h) {
-                    int t = h;
-                    h = l;
-                    l = t;
-                    bImBigger = false;
-                }
-
-                int reqValue = (requested->density?requested->density:160);
-                if (reqValue >= h) {
-                    // requested value higher than both l and h, give h
-                    return bImBigger;
-                }
-                if (l >= reqValue) {
-                    // requested value lower than both l and h, give l
-                    return !bImBigger;
-                }
-                // saying that scaling down is 2x better than up
-                if (((2 * l) - reqValue) * h > reqValue * reqValue) {
-                    return !bImBigger;
-                } else {
-                    return bImBigger;
-                }
-            }
-
-            if ((touchscreen != o.touchscreen) && requested->touchscreen) {
-                return (touchscreen);
-            }
-        }
-
-        if (input || o.input) {
-            const int keysHidden = inputFlags & MASK_KEYSHIDDEN;
-            const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;
-            if (keysHidden != oKeysHidden) {
-                const int reqKeysHidden =
-                        requested->inputFlags & MASK_KEYSHIDDEN;
-                if (reqKeysHidden) {
-
-                    if (!keysHidden) return false;
-                    if (!oKeysHidden) return true;
-                    // For compatibility, we count KEYSHIDDEN_NO as being
-                    // the same as KEYSHIDDEN_SOFT.  Here we disambiguate
-                    // these by making an exact match more specific.
-                    if (reqKeysHidden == keysHidden) return true;
-                    if (reqKeysHidden == oKeysHidden) return false;
-                }
-            }
-
-            const int navHidden = inputFlags & MASK_NAVHIDDEN;
-            const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;
-            if (navHidden != oNavHidden) {
-                const int reqNavHidden =
-                        requested->inputFlags & MASK_NAVHIDDEN;
-                if (reqNavHidden) {
-
-                    if (!navHidden) return false;
-                    if (!oNavHidden) return true;
-                }
-            }
-
-            if ((keyboard != o.keyboard) && requested->keyboard) {
-                return (keyboard);
-            }
-
-            if ((navigation != o.navigation) && requested->navigation) {
-                return (navigation);
-            }
-        }
-
-        if (screenSize || o.screenSize) {
-            // "Better" is based on the sum of the difference between both
-            // width and height from the requested dimensions.  We are
-            // assuming the invalid configs (with smaller sizes) have
-            // already been filtered.  Note that if a particular dimension
-            // is unspecified, we will end up with a large value (the
-            // difference between 0 and the requested dimension), which is
-            // good since we will prefer a config that has specified a
-            // size value.
-            int myDelta = 0, otherDelta = 0;
-            if (requested->screenWidth) {
-                myDelta += requested->screenWidth - screenWidth;
-                otherDelta += requested->screenWidth - o.screenWidth;
-            }
-            if (requested->screenHeight) {
-                myDelta += requested->screenHeight - screenHeight;
-                otherDelta += requested->screenHeight - o.screenHeight;
-            }
-            if (myDelta != otherDelta) {
-                return myDelta < otherDelta;
-            }
-        }
-
-        if (version || o.version) {
-            if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
-                return (sdkVersion > o.sdkVersion);
-            }
-
-            if ((minorVersion != o.minorVersion) &&
-                    requested->minorVersion) {
-                return (minorVersion);
-            }
-        }
-
-        return false;
-    }
-    return isMoreSpecificThan(o);
-}
-
-bool ResTable_config::match(const ResTable_config& settings) const {
-    if (imsi != 0) {
-        if (mcc != 0 && mcc != settings.mcc) {
-            return false;
-        }
-        if (mnc != 0 && mnc != settings.mnc) {
-            return false;
-        }
-    }
-    if (locale != 0) {
-        if (language[0] != 0
-            && (language[0] != settings.language[0]
-                || language[1] != settings.language[1])) {
-            return false;
-        }
-        if (country[0] != 0
-            && (country[0] != settings.country[0]
-                || country[1] != settings.country[1])) {
-            return false;
-        }
-    }
-    if (screenConfig != 0) {
-        const int layoutDir = screenLayout&MASK_LAYOUTDIR;
-        const int setLayoutDir = settings.screenLayout&MASK_LAYOUTDIR;
-        if (layoutDir != 0 && layoutDir != setLayoutDir) {
-            return false;
-        }
-
-        const int screenSize = screenLayout&MASK_SCREENSIZE;
-        const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
-        // Any screen sizes for larger screens than the setting do not
-        // match.
-        if (screenSize != 0 && screenSize > setScreenSize) {
-            return false;
-        }
-
-        const int screenLong = screenLayout&MASK_SCREENLONG;
-        const int setScreenLong = settings.screenLayout&MASK_SCREENLONG;
-        if (screenLong != 0 && screenLong != setScreenLong) {
-            return false;
-        }
-
-        const int uiModeType = uiMode&MASK_UI_MODE_TYPE;
-        const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE;
-        if (uiModeType != 0 && uiModeType != setUiModeType) {
-            return false;
-        }
-
-        const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT;
-        const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT;
-        if (uiModeNight != 0 && uiModeNight != setUiModeNight) {
-            return false;
-        }
-
-        if (smallestScreenWidthDp != 0
-                && smallestScreenWidthDp > settings.smallestScreenWidthDp) {
-            return false;
-        }
-    }
-    if (screenSizeDp != 0) {
-        if (screenWidthDp != 0 && screenWidthDp > settings.screenWidthDp) {
-            //ALOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp);
-            return false;
-        }
-        if (screenHeightDp != 0 && screenHeightDp > settings.screenHeightDp) {
-            //ALOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp);
-            return false;
-        }
-    }
-    if (screenType != 0) {
-        if (orientation != 0 && orientation != settings.orientation) {
-            return false;
-        }
-        // density always matches - we can scale it.  See isBetterThan
-        if (touchscreen != 0 && touchscreen != settings.touchscreen) {
-            return false;
-        }
-    }
-    if (input != 0) {
-        const int keysHidden = inputFlags&MASK_KEYSHIDDEN;
-        const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
-        if (keysHidden != 0 && keysHidden != setKeysHidden) {
-            // For compatibility, we count a request for KEYSHIDDEN_NO as also
-            // matching the more recent KEYSHIDDEN_SOFT.  Basically
-            // KEYSHIDDEN_NO means there is some kind of keyboard available.
-            //ALOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden);
-            if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) {
-                //ALOGI("No match!");
-                return false;
-            }
-        }
-        const int navHidden = inputFlags&MASK_NAVHIDDEN;
-        const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;
-        if (navHidden != 0 && navHidden != setNavHidden) {
-            return false;
-        }
-        if (keyboard != 0 && keyboard != settings.keyboard) {
-            return false;
-        }
-        if (navigation != 0 && navigation != settings.navigation) {
-            return false;
-        }
-    }
-    if (screenSize != 0) {
-        if (screenWidth != 0 && screenWidth > settings.screenWidth) {
-            return false;
-        }
-        if (screenHeight != 0 && screenHeight > settings.screenHeight) {
-            return false;
-        }
-    }
-    if (version != 0) {
-        if (sdkVersion != 0 && sdkVersion > settings.sdkVersion) {
-            return false;
-        }
-        if (minorVersion != 0 && minorVersion != settings.minorVersion) {
-            return false;
-        }
-    }
-    return true;
-}
-
-void ResTable_config::getLocale(char str[6]) const {
-    memset(str, 0, 6);
-    if (language[0]) {
-        str[0] = language[0];
-        str[1] = language[1];
-        if (country[0]) {
-            str[2] = '_';
-            str[3] = country[0];
-            str[4] = country[1];
-        }
-    }
-}
-
-String8 ResTable_config::toString() const {
-    String8 res;
-
-    if (mcc != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("%dmcc", dtohs(mcc));
-    }
-    if (mnc != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("%dmnc", dtohs(mnc));
-    }
-    if (language[0] != 0) {
-        if (res.size() > 0) res.append("-");
-        res.append(language, 2);
-    }
-    if (country[0] != 0) {
-        if (res.size() > 0) res.append("-");
-        res.append(country, 2);
-    }
-    if ((screenLayout&MASK_LAYOUTDIR) != 0) {
-        if (res.size() > 0) res.append("-");
-        switch (screenLayout&ResTable_config::MASK_LAYOUTDIR) {
-            case ResTable_config::LAYOUTDIR_LTR:
-                res.append("ldltr");
-                break;
-            case ResTable_config::LAYOUTDIR_RTL:
-                res.append("ldrtl");
-                break;
-            default:
-                res.appendFormat("layoutDir=%d",
-                        dtohs(screenLayout&ResTable_config::MASK_LAYOUTDIR));
-                break;
-        }
-    }
-    if (smallestScreenWidthDp != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("sw%ddp", dtohs(smallestScreenWidthDp));
-    }
-    if (screenWidthDp != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("w%ddp", dtohs(screenWidthDp));
-    }
-    if (screenHeightDp != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("h%ddp", dtohs(screenHeightDp));
-    }
-    if ((screenLayout&MASK_SCREENSIZE) != SCREENSIZE_ANY) {
-        if (res.size() > 0) res.append("-");
-        switch (screenLayout&ResTable_config::MASK_SCREENSIZE) {
-            case ResTable_config::SCREENSIZE_SMALL:
-                res.append("small");
-                break;
-            case ResTable_config::SCREENSIZE_NORMAL:
-                res.append("normal");
-                break;
-            case ResTable_config::SCREENSIZE_LARGE:
-                res.append("large");
-                break;
-            case ResTable_config::SCREENSIZE_XLARGE:
-                res.append("xlarge");
-                break;
-            default:
-                res.appendFormat("screenLayoutSize=%d",
-                        dtohs(screenLayout&ResTable_config::MASK_SCREENSIZE));
-                break;
-        }
-    }
-    if ((screenLayout&MASK_SCREENLONG) != 0) {
-        if (res.size() > 0) res.append("-");
-        switch (screenLayout&ResTable_config::MASK_SCREENLONG) {
-            case ResTable_config::SCREENLONG_NO:
-                res.append("notlong");
-                break;
-            case ResTable_config::SCREENLONG_YES:
-                res.append("long");
-                break;
-            default:
-                res.appendFormat("screenLayoutLong=%d",
-                        dtohs(screenLayout&ResTable_config::MASK_SCREENLONG));
-                break;
-        }
-    }
-    if (orientation != ORIENTATION_ANY) {
-        if (res.size() > 0) res.append("-");
-        switch (orientation) {
-            case ResTable_config::ORIENTATION_PORT:
-                res.append("port");
-                break;
-            case ResTable_config::ORIENTATION_LAND:
-                res.append("land");
-                break;
-            case ResTable_config::ORIENTATION_SQUARE:
-                res.append("square");
-                break;
-            default:
-                res.appendFormat("orientation=%d", dtohs(orientation));
-                break;
-        }
-    }
-    if ((uiMode&MASK_UI_MODE_TYPE) != UI_MODE_TYPE_ANY) {
-        if (res.size() > 0) res.append("-");
-        switch (uiMode&ResTable_config::MASK_UI_MODE_TYPE) {
-            case ResTable_config::UI_MODE_TYPE_DESK:
-                res.append("desk");
-                break;
-            case ResTable_config::UI_MODE_TYPE_CAR:
-                res.append("car");
-                break;
-            case ResTable_config::UI_MODE_TYPE_TELEVISION:
-                res.append("television");
-                break;
-            case ResTable_config::UI_MODE_TYPE_APPLIANCE:
-                res.append("appliance");
-                break;
-            default:
-                res.appendFormat("uiModeType=%d",
-                        dtohs(screenLayout&ResTable_config::MASK_UI_MODE_TYPE));
-                break;
-        }
-    }
-    if ((uiMode&MASK_UI_MODE_NIGHT) != 0) {
-        if (res.size() > 0) res.append("-");
-        switch (uiMode&ResTable_config::MASK_UI_MODE_NIGHT) {
-            case ResTable_config::UI_MODE_NIGHT_NO:
-                res.append("notnight");
-                break;
-            case ResTable_config::UI_MODE_NIGHT_YES:
-                res.append("night");
-                break;
-            default:
-                res.appendFormat("uiModeNight=%d",
-                        dtohs(uiMode&MASK_UI_MODE_NIGHT));
-                break;
-        }
-    }
-    if (density != DENSITY_DEFAULT) {
-        if (res.size() > 0) res.append("-");
-        switch (density) {
-            case ResTable_config::DENSITY_LOW:
-                res.append("ldpi");
-                break;
-            case ResTable_config::DENSITY_MEDIUM:
-                res.append("mdpi");
-                break;
-            case ResTable_config::DENSITY_TV:
-                res.append("tvdpi");
-                break;
-            case ResTable_config::DENSITY_HIGH:
-                res.append("hdpi");
-                break;
-            case ResTable_config::DENSITY_XHIGH:
-                res.append("xhdpi");
-                break;
-            case ResTable_config::DENSITY_XXHIGH:
-                res.append("xxhdpi");
-                break;
-            case ResTable_config::DENSITY_NONE:
-                res.append("nodpi");
-                break;
-            default:
-                res.appendFormat("%ddpi", dtohs(density));
-                break;
-        }
-    }
-    if (touchscreen != TOUCHSCREEN_ANY) {
-        if (res.size() > 0) res.append("-");
-        switch (touchscreen) {
-            case ResTable_config::TOUCHSCREEN_NOTOUCH:
-                res.append("notouch");
-                break;
-            case ResTable_config::TOUCHSCREEN_FINGER:
-                res.append("finger");
-                break;
-            case ResTable_config::TOUCHSCREEN_STYLUS:
-                res.append("stylus");
-                break;
-            default:
-                res.appendFormat("touchscreen=%d", dtohs(touchscreen));
-                break;
-        }
-    }
-    if (keyboard != KEYBOARD_ANY) {
-        if (res.size() > 0) res.append("-");
-        switch (keyboard) {
-            case ResTable_config::KEYBOARD_NOKEYS:
-                res.append("nokeys");
-                break;
-            case ResTable_config::KEYBOARD_QWERTY:
-                res.append("qwerty");
-                break;
-            case ResTable_config::KEYBOARD_12KEY:
-                res.append("12key");
-                break;
-            default:
-                res.appendFormat("keyboard=%d", dtohs(keyboard));
-                break;
-        }
-    }
-    if ((inputFlags&MASK_KEYSHIDDEN) != 0) {
-        if (res.size() > 0) res.append("-");
-        switch (inputFlags&MASK_KEYSHIDDEN) {
-            case ResTable_config::KEYSHIDDEN_NO:
-                res.append("keysexposed");
-                break;
-            case ResTable_config::KEYSHIDDEN_YES:
-                res.append("keyshidden");
-                break;
-            case ResTable_config::KEYSHIDDEN_SOFT:
-                res.append("keyssoft");
-                break;
-        }
-    }
-    if (navigation != NAVIGATION_ANY) {
-        if (res.size() > 0) res.append("-");
-        switch (navigation) {
-            case ResTable_config::NAVIGATION_NONAV:
-                res.append("nonav");
-                break;
-            case ResTable_config::NAVIGATION_DPAD:
-                res.append("dpad");
-                break;
-            case ResTable_config::NAVIGATION_TRACKBALL:
-                res.append("trackball");
-                break;
-            case ResTable_config::NAVIGATION_WHEEL:
-                res.append("wheel");
-                break;
-            default:
-                res.appendFormat("navigation=%d", dtohs(navigation));
-                break;
-        }
-    }
-    if ((inputFlags&MASK_NAVHIDDEN) != 0) {
-        if (res.size() > 0) res.append("-");
-        switch (inputFlags&MASK_NAVHIDDEN) {
-            case ResTable_config::NAVHIDDEN_NO:
-                res.append("navsexposed");
-                break;
-            case ResTable_config::NAVHIDDEN_YES:
-                res.append("navhidden");
-                break;
-            default:
-                res.appendFormat("inputFlagsNavHidden=%d",
-                        dtohs(inputFlags&MASK_NAVHIDDEN));
-                break;
-        }
-    }
-    if (screenSize != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("%dx%d", dtohs(screenWidth), dtohs(screenHeight));
-    }
-    if (version != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("v%d", dtohs(sdkVersion));
-        if (minorVersion != 0) {
-            res.appendFormat(".%d", dtohs(minorVersion));
-        }
-    }
-
-    return res;
-}
-
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-
-struct ResTable::Header
-{
-    Header(ResTable* _owner) : owner(_owner), ownedData(NULL), header(NULL),
-        resourceIDMap(NULL), resourceIDMapSize(0) { }
-
-    ~Header()
-    {
-        free(resourceIDMap);
-    }
-
-    ResTable* const                 owner;
-    void*                           ownedData;
-    const ResTable_header*          header;
-    size_t                          size;
-    const uint8_t*                  dataEnd;
-    size_t                          index;
-    void*                           cookie;
-
-    ResStringPool                   values;
-    uint32_t*                       resourceIDMap;
-    size_t                          resourceIDMapSize;
-};
-
-struct ResTable::Type
-{
-    Type(const Header* _header, const Package* _package, size_t count)
-        : header(_header), package(_package), entryCount(count),
-          typeSpec(NULL), typeSpecFlags(NULL) { }
-    const Header* const             header;
-    const Package* const            package;
-    const size_t                    entryCount;
-    const ResTable_typeSpec*        typeSpec;
-    const uint32_t*                 typeSpecFlags;
-    Vector<const ResTable_type*>    configs;
-};
-
-struct ResTable::Package
-{
-    Package(ResTable* _owner, const Header* _header, const ResTable_package* _package)
-        : owner(_owner), header(_header), package(_package) { }
-    ~Package()
-    {
-        size_t i = types.size();
-        while (i > 0) {
-            i--;
-            delete types[i];
-        }
-    }
-    
-    ResTable* const                 owner;
-    const Header* const             header;
-    const ResTable_package* const   package;
-    Vector<Type*>                   types;
-
-    ResStringPool                   typeStrings;
-    ResStringPool                   keyStrings;
-    
-    const Type* getType(size_t idx) const {
-        return idx < types.size() ? types[idx] : NULL;
-    }
-};
-
-// A group of objects describing a particular resource package.
-// The first in 'package' is always the root object (from the resource
-// table that defined the package); the ones after are skins on top of it.
-struct ResTable::PackageGroup
-{
-    PackageGroup(ResTable* _owner, const String16& _name, uint32_t _id)
-        : owner(_owner), name(_name), id(_id), typeCount(0), bags(NULL) { }
-    ~PackageGroup() {
-        clearBagCache();
-        const size_t N = packages.size();
-        for (size_t i=0; i<N; i++) {
-            Package* pkg = packages[i];
-            if (pkg->owner == owner) {
-                delete pkg;
-            }
-        }
-    }
-
-    void clearBagCache() {
-        if (bags) {
-            TABLE_NOISY(printf("bags=%p\n", bags));
-            Package* pkg = packages[0];
-            TABLE_NOISY(printf("typeCount=%x\n", typeCount));
-            for (size_t i=0; i<typeCount; i++) {
-                TABLE_NOISY(printf("type=%d\n", i));
-                const Type* type = pkg->getType(i);
-                if (type != NULL) {
-                    bag_set** typeBags = bags[i];
-                    TABLE_NOISY(printf("typeBags=%p\n", typeBags));
-                    if (typeBags) {
-                        TABLE_NOISY(printf("type->entryCount=%x\n", type->entryCount));
-                        const size_t N = type->entryCount;
-                        for (size_t j=0; j<N; j++) {
-                            if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF)
-                                free(typeBags[j]);
-                        }
-                        free(typeBags);
-                    }
-                }
-            }
-            free(bags);
-            bags = NULL;
-        }
-    }
-    
-    ResTable* const                 owner;
-    String16 const                  name;
-    uint32_t const                  id;
-    Vector<Package*>                packages;
-    
-    // This is for finding typeStrings and other common package stuff.
-    Package*                        basePackage;
-
-    // For quick access.
-    size_t                          typeCount;
-    
-    // Computed attribute bags, first indexed by the type and second
-    // by the entry in that type.
-    bag_set***                      bags;
-};
-
-struct ResTable::bag_set
-{
-    size_t numAttrs;    // number in array
-    size_t availAttrs;  // total space in array
-    uint32_t typeSpecFlags;
-    // Followed by 'numAttr' bag_entry structures.
-};
-
-ResTable::Theme::Theme(const ResTable& table)
-    : mTable(table)
-{
-    memset(mPackages, 0, sizeof(mPackages));
-}
-
-ResTable::Theme::~Theme()
-{
-    for (size_t i=0; i<Res_MAXPACKAGE; i++) {
-        package_info* pi = mPackages[i];
-        if (pi != NULL) {
-            free_package(pi);
-        }
-    }
-}
-
-void ResTable::Theme::free_package(package_info* pi)
-{
-    for (size_t j=0; j<pi->numTypes; j++) {
-        theme_entry* te = pi->types[j].entries;
-        if (te != NULL) {
-            free(te);
-        }
-    }
-    free(pi);
-}
-
-ResTable::Theme::package_info* ResTable::Theme::copy_package(package_info* pi)
-{
-    package_info* newpi = (package_info*)malloc(
-        sizeof(package_info) + (pi->numTypes*sizeof(type_info)));
-    newpi->numTypes = pi->numTypes;
-    for (size_t j=0; j<newpi->numTypes; j++) {
-        size_t cnt = pi->types[j].numEntries;
-        newpi->types[j].numEntries = cnt;
-        theme_entry* te = pi->types[j].entries;
-        if (te != NULL) {
-            theme_entry* newte = (theme_entry*)malloc(cnt*sizeof(theme_entry));
-            newpi->types[j].entries = newte;
-            memcpy(newte, te, cnt*sizeof(theme_entry));
-        } else {
-            newpi->types[j].entries = NULL;
-        }
-    }
-    return newpi;
-}
-
-status_t ResTable::Theme::applyStyle(uint32_t resID, bool force)
-{
-    const bag_entry* bag;
-    uint32_t bagTypeSpecFlags = 0;
-    mTable.lock();
-    const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);
-    TABLE_NOISY(ALOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
-    if (N < 0) {
-        mTable.unlock();
-        return N;
-    }
-
-    uint32_t curPackage = 0xffffffff;
-    ssize_t curPackageIndex = 0;
-    package_info* curPI = NULL;
-    uint32_t curType = 0xffffffff;
-    size_t numEntries = 0;
-    theme_entry* curEntries = NULL;
-
-    const bag_entry* end = bag + N;
-    while (bag < end) {
-        const uint32_t attrRes = bag->map.name.ident;
-        const uint32_t p = Res_GETPACKAGE(attrRes);
-        const uint32_t t = Res_GETTYPE(attrRes);
-        const uint32_t e = Res_GETENTRY(attrRes);
-
-        if (curPackage != p) {
-            const ssize_t pidx = mTable.getResourcePackageIndex(attrRes);
-            if (pidx < 0) {
-                ALOGE("Style contains key with bad package: 0x%08x\n", attrRes);
-                bag++;
-                continue;
-            }
-            curPackage = p;
-            curPackageIndex = pidx;
-            curPI = mPackages[pidx];
-            if (curPI == NULL) {
-                PackageGroup* const grp = mTable.mPackageGroups[pidx];
-                int cnt = grp->typeCount;
-                curPI = (package_info*)malloc(
-                    sizeof(package_info) + (cnt*sizeof(type_info)));
-                curPI->numTypes = cnt;
-                memset(curPI->types, 0, cnt*sizeof(type_info));
-                mPackages[pidx] = curPI;
-            }
-            curType = 0xffffffff;
-        }
-        if (curType != t) {
-            if (t >= curPI->numTypes) {
-                ALOGE("Style contains key with bad type: 0x%08x\n", attrRes);
-                bag++;
-                continue;
-            }
-            curType = t;
-            curEntries = curPI->types[t].entries;
-            if (curEntries == NULL) {
-                PackageGroup* const grp = mTable.mPackageGroups[curPackageIndex];
-                const Type* type = grp->packages[0]->getType(t);
-                int cnt = type != NULL ? type->entryCount : 0;
-                curEntries = (theme_entry*)malloc(cnt*sizeof(theme_entry));
-                memset(curEntries, Res_value::TYPE_NULL, cnt*sizeof(theme_entry));
-                curPI->types[t].numEntries = cnt;
-                curPI->types[t].entries = curEntries;
-            }
-            numEntries = curPI->types[t].numEntries;
-        }
-        if (e >= numEntries) {
-            ALOGE("Style contains key with bad entry: 0x%08x\n", attrRes);
-            bag++;
-            continue;
-        }
-        theme_entry* curEntry = curEntries + e;
-        TABLE_NOISY(ALOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
-                   attrRes, bag->map.value.dataType, bag->map.value.data,
-             curEntry->value.dataType));
-        if (force || curEntry->value.dataType == Res_value::TYPE_NULL) {
-            curEntry->stringBlock = bag->stringBlock;
-            curEntry->typeSpecFlags |= bagTypeSpecFlags;
-            curEntry->value = bag->map.value;
-        }
-
-        bag++;
-    }
-
-    mTable.unlock();
-
-    //ALOGI("Applying style 0x%08x (force=%d)  theme %p...\n", resID, force, this);
-    //dumpToLog();
-    
-    return NO_ERROR;
-}
-
-status_t ResTable::Theme::setTo(const Theme& other)
-{
-    //ALOGI("Setting theme %p from theme %p...\n", this, &other);
-    //dumpToLog();
-    //other.dumpToLog();
-    
-    if (&mTable == &other.mTable) {
-        for (size_t i=0; i<Res_MAXPACKAGE; i++) {
-            if (mPackages[i] != NULL) {
-                free_package(mPackages[i]);
-            }
-            if (other.mPackages[i] != NULL) {
-                mPackages[i] = copy_package(other.mPackages[i]);
-            } else {
-                mPackages[i] = NULL;
-            }
-        }
-    } else {
-        // @todo: need to really implement this, not just copy
-        // the system package (which is still wrong because it isn't
-        // fixing up resource references).
-        for (size_t i=0; i<Res_MAXPACKAGE; i++) {
-            if (mPackages[i] != NULL) {
-                free_package(mPackages[i]);
-            }
-            if (i == 0 && other.mPackages[i] != NULL) {
-                mPackages[i] = copy_package(other.mPackages[i]);
-            } else {
-                mPackages[i] = NULL;
-            }
-        }
-    }
-
-    //ALOGI("Final theme:");
-    //dumpToLog();
-    
-    return NO_ERROR;
-}
-
-ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue,
-        uint32_t* outTypeSpecFlags) const
-{
-    int cnt = 20;
-
-    if (outTypeSpecFlags != NULL) *outTypeSpecFlags = 0;
-    
-    do {
-        const ssize_t p = mTable.getResourcePackageIndex(resID);
-        const uint32_t t = Res_GETTYPE(resID);
-        const uint32_t e = Res_GETENTRY(resID);
-
-        TABLE_THEME(ALOGI("Looking up attr 0x%08x in theme %p", resID, this));
-
-        if (p >= 0) {
-            const package_info* const pi = mPackages[p];
-            TABLE_THEME(ALOGI("Found package: %p", pi));
-            if (pi != NULL) {
-                TABLE_THEME(ALOGI("Desired type index is %ld in avail %d", t, pi->numTypes));
-                if (t < pi->numTypes) {
-                    const type_info& ti = pi->types[t];
-                    TABLE_THEME(ALOGI("Desired entry index is %ld in avail %d", e, ti.numEntries));
-                    if (e < ti.numEntries) {
-                        const theme_entry& te = ti.entries[e];
-                        if (outTypeSpecFlags != NULL) {
-                            *outTypeSpecFlags |= te.typeSpecFlags;
-                        }
-                        TABLE_THEME(ALOGI("Theme value: type=0x%x, data=0x%08x",
-                                te.value.dataType, te.value.data));
-                        const uint8_t type = te.value.dataType;
-                        if (type == Res_value::TYPE_ATTRIBUTE) {
-                            if (cnt > 0) {
-                                cnt--;
-                                resID = te.value.data;
-                                continue;
-                            }
-                            ALOGW("Too many attribute references, stopped at: 0x%08x\n", resID);
-                            return BAD_INDEX;
-                        } else if (type != Res_value::TYPE_NULL) {
-                            *outValue = te.value;
-                            return te.stringBlock;
-                        }
-                        return BAD_INDEX;
-                    }
-                }
-            }
-        }
-        break;
-
-    } while (true);
-
-    return BAD_INDEX;
-}
-
-ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,
-        ssize_t blockIndex, uint32_t* outLastRef,
-        uint32_t* inoutTypeSpecFlags, ResTable_config* inoutConfig) const
-{
-    //printf("Resolving type=0x%x\n", inOutValue->dataType);
-    if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
-        uint32_t newTypeSpecFlags;
-        blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags);
-        TABLE_THEME(ALOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n",
-             (int)blockIndex, (int)inOutValue->dataType, (void*)inOutValue->data));
-        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags;
-        //printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType);
-        if (blockIndex < 0) {
-            return blockIndex;
-        }
-    }
-    return mTable.resolveReference(inOutValue, blockIndex, outLastRef,
-            inoutTypeSpecFlags, inoutConfig);
-}
-
-void ResTable::Theme::dumpToLog() const
-{
-    ALOGI("Theme %p:\n", this);
-    for (size_t i=0; i<Res_MAXPACKAGE; i++) {
-        package_info* pi = mPackages[i];
-        if (pi == NULL) continue;
-        
-        ALOGI("  Package #0x%02x:\n", (int)(i+1));
-        for (size_t j=0; j<pi->numTypes; j++) {
-            type_info& ti = pi->types[j];
-            if (ti.numEntries == 0) continue;
-            
-            ALOGI("    Type #0x%02x:\n", (int)(j+1));
-            for (size_t k=0; k<ti.numEntries; k++) {
-                theme_entry& te = ti.entries[k];
-                if (te.value.dataType == Res_value::TYPE_NULL) continue;
-                ALOGI("      0x%08x: t=0x%x, d=0x%08x (block=%d)\n",
-                     (int)Res_MAKEID(i, j, k),
-                     te.value.dataType, (int)te.value.data, (int)te.stringBlock);
-            }
-        }
-    }
-}
-
-ResTable::ResTable()
-    : mError(NO_INIT)
-{
-    memset(&mParams, 0, sizeof(mParams));
-    memset(mPackageMap, 0, sizeof(mPackageMap));
-    //ALOGI("Creating ResTable %p\n", this);
-}
-
-ResTable::ResTable(const void* data, size_t size, void* cookie, bool copyData)
-    : mError(NO_INIT)
-{
-    memset(&mParams, 0, sizeof(mParams));
-    memset(mPackageMap, 0, sizeof(mPackageMap));
-    add(data, size, cookie, copyData);
-    LOG_FATAL_IF(mError != NO_ERROR, "Error parsing resource table");
-    //ALOGI("Creating ResTable %p\n", this);
-}
-
-ResTable::~ResTable()
-{
-    //ALOGI("Destroying ResTable in %p\n", this);
-    uninit();
-}
-
-inline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const
-{
-    return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1;
-}
-
-status_t ResTable::add(const void* data, size_t size, void* cookie, bool copyData,
-                       const void* idmap)
-{
-    return add(data, size, cookie, NULL, copyData, reinterpret_cast<const Asset*>(idmap));
-}
-
-status_t ResTable::add(Asset* asset, void* cookie, bool copyData, const void* idmap)
-{
-    const void* data = asset->getBuffer(true);
-    if (data == NULL) {
-        ALOGW("Unable to get buffer of resource asset file");
-        return UNKNOWN_ERROR;
-    }
-    size_t size = (size_t)asset->getLength();
-    return add(data, size, cookie, asset, copyData, reinterpret_cast<const Asset*>(idmap));
-}
-
-status_t ResTable::add(ResTable* src)
-{
-    mError = src->mError;
-    
-    for (size_t i=0; i<src->mHeaders.size(); i++) {
-        mHeaders.add(src->mHeaders[i]);
-    }
-    
-    for (size_t i=0; i<src->mPackageGroups.size(); i++) {
-        PackageGroup* srcPg = src->mPackageGroups[i];
-        PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id);
-        for (size_t j=0; j<srcPg->packages.size(); j++) {
-            pg->packages.add(srcPg->packages[j]);
-        }
-        pg->basePackage = srcPg->basePackage;
-        pg->typeCount = srcPg->typeCount;
-        mPackageGroups.add(pg);
-    }
-    
-    memcpy(mPackageMap, src->mPackageMap, sizeof(mPackageMap));
-    
-    return mError;
-}
-
-status_t ResTable::add(const void* data, size_t size, void* cookie,
-                       Asset* asset, bool copyData, const Asset* idmap)
-{
-    if (!data) return NO_ERROR;
-    Header* header = new Header(this);
-    header->index = mHeaders.size();
-    header->cookie = cookie;
-    if (idmap != NULL) {
-        const size_t idmap_size = idmap->getLength();
-        const void* idmap_data = const_cast<Asset*>(idmap)->getBuffer(true);
-        header->resourceIDMap = (uint32_t*)malloc(idmap_size);
-        if (header->resourceIDMap == NULL) {
-            delete header;
-            return (mError = NO_MEMORY);
-        }
-        memcpy((void*)header->resourceIDMap, idmap_data, idmap_size);
-        header->resourceIDMapSize = idmap_size;
-    }
-    mHeaders.add(header);
-
-    const bool notDeviceEndian = htods(0xf0) != 0xf0;
-
-    LOAD_TABLE_NOISY(
-        ALOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%p, asset=%p, copy=%d "
-             "idmap=%p\n", data, size, cookie, asset, copyData, idmap));
-    
-    if (copyData || notDeviceEndian) {
-        header->ownedData = malloc(size);
-        if (header->ownedData == NULL) {
-            return (mError=NO_MEMORY);
-        }
-        memcpy(header->ownedData, data, size);
-        data = header->ownedData;
-    }
-
-    header->header = (const ResTable_header*)data;
-    header->size = dtohl(header->header->header.size);
-    //ALOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header->size,
-    //     dtohl(header->header->header.size), header->header->header.size);
-    LOAD_TABLE_NOISY(ALOGV("Loading ResTable @%p:\n", header->header));
-    LOAD_TABLE_NOISY(printHexData(2, header->header, header->size < 256 ? header->size : 256,
-                                  16, 16, 0, false, printToLogFunc));
-    if (dtohs(header->header->header.headerSize) > header->size
-            || header->size > size) {
-        ALOGW("Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n",
-             (int)dtohs(header->header->header.headerSize),
-             (int)header->size, (int)size);
-        return (mError=BAD_TYPE);
-    }
-    if (((dtohs(header->header->header.headerSize)|header->size)&0x3) != 0) {
-        ALOGW("Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\n",
-             (int)dtohs(header->header->header.headerSize),
-             (int)header->size);
-        return (mError=BAD_TYPE);
-    }
-    header->dataEnd = ((const uint8_t*)header->header) + header->size;
-
-    // Iterate through all chunks.
-    size_t curPackage = 0;
-
-    const ResChunk_header* chunk =
-        (const ResChunk_header*)(((const uint8_t*)header->header)
-                                 + dtohs(header->header->header.headerSize));
-    while (((const uint8_t*)chunk) <= (header->dataEnd-sizeof(ResChunk_header)) &&
-           ((const uint8_t*)chunk) <= (header->dataEnd-dtohl(chunk->size))) {
-        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), header->dataEnd, "ResTable");
-        if (err != NO_ERROR) {
-            return (mError=err);
-        }
-        TABLE_NOISY(ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
-                     dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
-                     (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
-        const size_t csize = dtohl(chunk->size);
-        const uint16_t ctype = dtohs(chunk->type);
-        if (ctype == RES_STRING_POOL_TYPE) {
-            if (header->values.getError() != NO_ERROR) {
-                // Only use the first string chunk; ignore any others that
-                // may appear.
-                status_t err = header->values.setTo(chunk, csize);
-                if (err != NO_ERROR) {
-                    return (mError=err);
-                }
-            } else {
-                ALOGW("Multiple string chunks found in resource table.");
-            }
-        } else if (ctype == RES_TABLE_PACKAGE_TYPE) {
-            if (curPackage >= dtohl(header->header->packageCount)) {
-                ALOGW("More package chunks were found than the %d declared in the header.",
-                     dtohl(header->header->packageCount));
-                return (mError=BAD_TYPE);
-            }
-            uint32_t idmap_id = 0;
-            if (idmap != NULL) {
-                uint32_t tmp;
-                if (getIdmapPackageId(header->resourceIDMap,
-                                      header->resourceIDMapSize,
-                                      &tmp) == NO_ERROR) {
-                    idmap_id = tmp;
-                }
-            }
-            if (parsePackage((ResTable_package*)chunk, header, idmap_id) != NO_ERROR) {
-                return mError;
-            }
-            curPackage++;
-        } else {
-            ALOGW("Unknown chunk type %p in table at %p.\n",
-                 (void*)(int)(ctype),
-                 (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)));
-        }
-        chunk = (const ResChunk_header*)
-            (((const uint8_t*)chunk) + csize);
-    }
-
-    if (curPackage < dtohl(header->header->packageCount)) {
-        ALOGW("Fewer package chunks (%d) were found than the %d declared in the header.",
-             (int)curPackage, dtohl(header->header->packageCount));
-        return (mError=BAD_TYPE);
-    }
-    mError = header->values.getError();
-    if (mError != NO_ERROR) {
-        ALOGW("No string values found in resource table!");
-    }
-
-    TABLE_NOISY(ALOGV("Returning from add with mError=%d\n", mError));
-    return mError;
-}
-
-status_t ResTable::getError() const
-{
-    return mError;
-}
-
-void ResTable::uninit()
-{
-    mError = NO_INIT;
-    size_t N = mPackageGroups.size();
-    for (size_t i=0; i<N; i++) {
-        PackageGroup* g = mPackageGroups[i];
-        delete g;
-    }
-    N = mHeaders.size();
-    for (size_t i=0; i<N; i++) {
-        Header* header = mHeaders[i];
-        if (header->owner == this) {
-            if (header->ownedData) {
-                free(header->ownedData);
-            }
-            delete header;
-        }
-    }
-
-    mPackageGroups.clear();
-    mHeaders.clear();
-}
-
-bool ResTable::getResourceName(uint32_t resID, bool allowUtf8, resource_name* outName) const
-{
-    if (mError != NO_ERROR) {
-        return false;
-    }
-
-    const ssize_t p = getResourcePackageIndex(resID);
-    const int t = Res_GETTYPE(resID);
-    const int e = Res_GETENTRY(resID);
-
-    if (p < 0) {
-        if (Res_GETPACKAGE(resID)+1 == 0) {
-            ALOGW("No package identifier when getting name for resource number 0x%08x", resID);
-        } else {
-            ALOGW("No known package when getting name for resource number 0x%08x", resID);
-        }
-        return false;
-    }
-    if (t < 0) {
-        ALOGW("No type identifier when getting name for resource number 0x%08x", resID);
-        return false;
-    }
-
-    const PackageGroup* const grp = mPackageGroups[p];
-    if (grp == NULL) {
-        ALOGW("Bad identifier when getting name for resource number 0x%08x", resID);
-        return false;
-    }
-    if (grp->packages.size() > 0) {
-        const Package* const package = grp->packages[0];
-
-        const ResTable_type* type;
-        const ResTable_entry* entry;
-        ssize_t offset = getEntry(package, t, e, NULL, &type, &entry, NULL);
-        if (offset <= 0) {
-            return false;
-        }
-
-        outName->package = grp->name.string();
-        outName->packageLen = grp->name.size();
-        if (allowUtf8) {
-            outName->type8 = grp->basePackage->typeStrings.string8At(t, &outName->typeLen);
-            outName->name8 = grp->basePackage->keyStrings.string8At(
-                dtohl(entry->key.index), &outName->nameLen);
-        } else {
-            outName->type8 = NULL;
-            outName->name8 = NULL;
-        }
-        if (outName->type8 == NULL) {
-            outName->type = grp->basePackage->typeStrings.stringAt(t, &outName->typeLen);
-            // If we have a bad index for some reason, we should abort.
-            if (outName->type == NULL) {
-                return false;
-            }
-        }
-        if (outName->name8 == NULL) {
-            outName->name = grp->basePackage->keyStrings.stringAt(
-                dtohl(entry->key.index), &outName->nameLen);
-            // If we have a bad index for some reason, we should abort.
-            if (outName->name == NULL) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    return false;
-}
-
-ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, uint16_t density,
-        uint32_t* outSpecFlags, ResTable_config* outConfig) const
-{
-    if (mError != NO_ERROR) {
-        return mError;
-    }
-
-    const ssize_t p = getResourcePackageIndex(resID);
-    const int t = Res_GETTYPE(resID);
-    const int e = Res_GETENTRY(resID);
-
-    if (p < 0) {
-        if (Res_GETPACKAGE(resID)+1 == 0) {
-            ALOGW("No package identifier when getting value for resource number 0x%08x", resID);
-        } else {
-            ALOGW("No known package when getting value for resource number 0x%08x", resID);
-        }
-        return BAD_INDEX;
-    }
-    if (t < 0) {
-        ALOGW("No type identifier when getting value for resource number 0x%08x", resID);
-        return BAD_INDEX;
-    }
-
-    const Res_value* bestValue = NULL;
-    const Package* bestPackage = NULL;
-    ResTable_config bestItem;
-    memset(&bestItem, 0, sizeof(bestItem)); // make the compiler shut up
-
-    if (outSpecFlags != NULL) *outSpecFlags = 0;
-
-    // Look through all resource packages, starting with the most
-    // recently added.
-    const PackageGroup* const grp = mPackageGroups[p];
-    if (grp == NULL) {
-        ALOGW("Bad identifier when getting value for resource number 0x%08x", resID);
-        return BAD_INDEX;
-    }
-
-    // Allow overriding density
-    const ResTable_config* desiredConfig = &mParams;
-    ResTable_config* overrideConfig = NULL;
-    if (density > 0) {
-        overrideConfig = (ResTable_config*) malloc(sizeof(ResTable_config));
-        if (overrideConfig == NULL) {
-            ALOGE("Couldn't malloc ResTable_config for overrides: %s", strerror(errno));
-            return BAD_INDEX;
-        }
-        memcpy(overrideConfig, &mParams, sizeof(ResTable_config));
-        overrideConfig->density = density;
-        desiredConfig = overrideConfig;
-    }
-
-    ssize_t rc = BAD_VALUE;
-    size_t ip = grp->packages.size();
-    while (ip > 0) {
-        ip--;
-        int T = t;
-        int E = e;
-
-        const Package* const package = grp->packages[ip];
-        if (package->header->resourceIDMap) {
-            uint32_t overlayResID = 0x0;
-            status_t retval = idmapLookup(package->header->resourceIDMap,
-                                          package->header->resourceIDMapSize,
-                                          resID, &overlayResID);
-            if (retval == NO_ERROR && overlayResID != 0x0) {
-                // for this loop iteration, this is the type and entry we really want
-                ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID);
-                T = Res_GETTYPE(overlayResID);
-                E = Res_GETENTRY(overlayResID);
-            } else {
-                // resource not present in overlay package, continue with the next package
-                continue;
-            }
-        }
-
-        const ResTable_type* type;
-        const ResTable_entry* entry;
-        const Type* typeClass;
-        ssize_t offset = getEntry(package, T, E, desiredConfig, &type, &entry, &typeClass);
-        if (offset <= 0) {
-            // No {entry, appropriate config} pair found in package. If this
-            // package is an overlay package (ip != 0), this simply means the
-            // overlay package did not specify a default.
-            // Non-overlay packages are still required to provide a default.
-            if (offset < 0 && ip == 0) {
-                ALOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %zd (error %d)\n",
-                        resID, T, E, ip, (int)offset);
-                rc = offset;
-                goto out;
-            }
-            continue;
-        }
-
-        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) != 0) {
-            if (!mayBeBag) {
-                ALOGW("Requesting resource %p failed because it is complex\n",
-                     (void*)resID);
-            }
-            continue;
-        }
-
-        TABLE_NOISY(aout << "Resource type data: "
-              << HexDump(type, dtohl(type->header.size)) << endl);
-
-        if ((size_t)offset > (dtohl(type->header.size)-sizeof(Res_value))) {
-            ALOGW("ResTable_item at %d is beyond type chunk data %d",
-                 (int)offset, dtohl(type->header.size));
-            rc = BAD_TYPE;
-            goto out;
-        }
-
-        const Res_value* item =
-            (const Res_value*)(((const uint8_t*)type) + offset);
-        ResTable_config thisConfig;
-        thisConfig.copyFromDtoH(type->config);
-
-        if (outSpecFlags != NULL) {
-            if (typeClass->typeSpecFlags != NULL) {
-                *outSpecFlags |= dtohl(typeClass->typeSpecFlags[E]);
-            } else {
-                *outSpecFlags = -1;
-            }
-        }
-
-        if (bestPackage != NULL &&
-            (bestItem.isMoreSpecificThan(thisConfig) || bestItem.diff(thisConfig) == 0)) {
-            // Discard thisConfig not only if bestItem is more specific, but also if the two configs
-            // are identical (diff == 0), or overlay packages will not take effect.
-            continue;
-        }
-        
-        bestItem = thisConfig;
-        bestValue = item;
-        bestPackage = package;
-    }
-
-    TABLE_NOISY(printf("Found result: package %p\n", bestPackage));
-
-    if (bestValue) {
-        outValue->size = dtohs(bestValue->size);
-        outValue->res0 = bestValue->res0;
-        outValue->dataType = bestValue->dataType;
-        outValue->data = dtohl(bestValue->data);
-        if (outConfig != NULL) {
-            *outConfig = bestItem;
-        }
-        TABLE_NOISY(size_t len;
-              printf("Found value: pkg=%d, type=%d, str=%s, int=%d\n",
-                     bestPackage->header->index,
-                     outValue->dataType,
-                     outValue->dataType == bestValue->TYPE_STRING
-                     ? String8(bestPackage->header->values.stringAt(
-                         outValue->data, &len)).string()
-                     : "",
-                     outValue->data));
-        rc = bestPackage->header->index;
-        goto out;
-    }
-
-out:
-    if (overrideConfig != NULL) {
-        free(overrideConfig);
-    }
-
-    return rc;
-}
-
-ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
-        uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags,
-        ResTable_config* outConfig) const
-{
-    int count=0;
-    while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE
-           && value->data != 0 && count < 20) {
-        if (outLastRef) *outLastRef = value->data;
-        uint32_t lastRef = value->data;
-        uint32_t newFlags = 0;
-        const ssize_t newIndex = getResource(value->data, value, true, 0, &newFlags,
-                outConfig);
-        if (newIndex == BAD_INDEX) {
-            return BAD_INDEX;
-        }
-        TABLE_THEME(ALOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n",
-             (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data));
-        //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
-        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags;
-        if (newIndex < 0) {
-            // This can fail if the resource being referenced is a style...
-            // in this case, just return the reference, and expect the
-            // caller to deal with.
-            return blockIndex;
-        }
-        blockIndex = newIndex;
-        count++;
-    }
-    return blockIndex;
-}
-
-const char16_t* ResTable::valueToString(
-    const Res_value* value, size_t stringBlock,
-    char16_t tmpBuffer[TMP_BUFFER_SIZE], size_t* outLen)
-{
-    if (!value) {
-        return NULL;
-    }
-    if (value->dataType == value->TYPE_STRING) {
-        return getTableStringBlock(stringBlock)->stringAt(value->data, outLen);
-    }
-    // XXX do int to string conversions.
-    return NULL;
-}
-
-ssize_t ResTable::lockBag(uint32_t resID, const bag_entry** outBag) const
-{
-    mLock.lock();
-    ssize_t err = getBagLocked(resID, outBag);
-    if (err < NO_ERROR) {
-        //printf("*** get failed!  unlocking\n");
-        mLock.unlock();
-    }
-    return err;
-}
-
-void ResTable::unlockBag(const bag_entry* bag) const
-{
-    //printf("<<< unlockBag %p\n", this);
-    mLock.unlock();
-}
-
-void ResTable::lock() const
-{
-    mLock.lock();
-}
-
-void ResTable::unlock() const
-{
-    mLock.unlock();
-}
-
-ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
-        uint32_t* outTypeSpecFlags) const
-{
-    if (mError != NO_ERROR) {
-        return mError;
-    }
-
-    const ssize_t p = getResourcePackageIndex(resID);
-    const int t = Res_GETTYPE(resID);
-    const int e = Res_GETENTRY(resID);
-
-    if (p < 0) {
-        ALOGW("Invalid package identifier when getting bag for resource number 0x%08x", resID);
-        return BAD_INDEX;
-    }
-    if (t < 0) {
-        ALOGW("No type identifier when getting bag for resource number 0x%08x", resID);
-        return BAD_INDEX;
-    }
-
-    //printf("Get bag: id=0x%08x, p=%d, t=%d\n", resID, p, t);
-    PackageGroup* const grp = mPackageGroups[p];
-    if (grp == NULL) {
-        ALOGW("Bad identifier when getting bag for resource number 0x%08x", resID);
-        return false;
-    }
-
-    if (t >= (int)grp->typeCount) {
-        ALOGW("Type identifier 0x%x is larger than type count 0x%x",
-             t+1, (int)grp->typeCount);
-        return BAD_INDEX;
-    }
-
-    const Package* const basePackage = grp->packages[0];
-
-    const Type* const typeConfigs = basePackage->getType(t);
-
-    const size_t NENTRY = typeConfigs->entryCount;
-    if (e >= (int)NENTRY) {
-        ALOGW("Entry identifier 0x%x is larger than entry count 0x%x",
-             e, (int)typeConfigs->entryCount);
-        return BAD_INDEX;
-    }
-
-    // First see if we've already computed this bag...
-    if (grp->bags) {
-        bag_set** typeSet = grp->bags[t];
-        if (typeSet) {
-            bag_set* set = typeSet[e];
-            if (set) {
-                if (set != (bag_set*)0xFFFFFFFF) {
-                    if (outTypeSpecFlags != NULL) {
-                        *outTypeSpecFlags = set->typeSpecFlags;
-                    }
-                    *outBag = (bag_entry*)(set+1);
-                    //ALOGI("Found existing bag for: %p\n", (void*)resID);
-                    return set->numAttrs;
-                }
-                ALOGW("Attempt to retrieve bag 0x%08x which is invalid or in a cycle.",
-                     resID);
-                return BAD_INDEX;
-            }
-        }
-    }
-
-    // Bag not found, we need to compute it!
-    if (!grp->bags) {
-        grp->bags = (bag_set***)calloc(grp->typeCount, sizeof(bag_set*));
-        if (!grp->bags) return NO_MEMORY;
-    }
-
-    bag_set** typeSet = grp->bags[t];
-    if (!typeSet) {
-        typeSet = (bag_set**)calloc(NENTRY, sizeof(bag_set*));
-        if (!typeSet) return NO_MEMORY;
-        grp->bags[t] = typeSet;
-    }
-
-    // Mark that we are currently working on this one.
-    typeSet[e] = (bag_set*)0xFFFFFFFF;
-
-    // This is what we are building.
-    bag_set* set = NULL;
-
-    TABLE_NOISY(ALOGI("Building bag: %p\n", (void*)resID));
-    
-    ResTable_config bestConfig;
-    memset(&bestConfig, 0, sizeof(bestConfig));
-
-    // Now collect all bag attributes from all packages.
-    size_t ip = grp->packages.size();
-    while (ip > 0) {
-        ip--;
-        int T = t;
-        int E = e;
-
-        const Package* const package = grp->packages[ip];
-        if (package->header->resourceIDMap) {
-            uint32_t overlayResID = 0x0;
-            status_t retval = idmapLookup(package->header->resourceIDMap,
-                                          package->header->resourceIDMapSize,
-                                          resID, &overlayResID);
-            if (retval == NO_ERROR && overlayResID != 0x0) {
-                // for this loop iteration, this is the type and entry we really want
-                ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID);
-                T = Res_GETTYPE(overlayResID);
-                E = Res_GETENTRY(overlayResID);
-            } else {
-                // resource not present in overlay package, continue with the next package
-                continue;
-            }
-        }
-
-        const ResTable_type* type;
-        const ResTable_entry* entry;
-        const Type* typeClass;
-        ALOGV("Getting entry pkg=%p, t=%d, e=%d\n", package, T, E);
-        ssize_t offset = getEntry(package, T, E, &mParams, &type, &entry, &typeClass);
-        ALOGV("Resulting offset=%d\n", offset);
-        if (offset <= 0) {
-            // No {entry, appropriate config} pair found in package. If this
-            // package is an overlay package (ip != 0), this simply means the
-            // overlay package did not specify a default.
-            // Non-overlay packages are still required to provide a default.
-            if (offset < 0 && ip == 0) {
-                if (set) free(set);
-                return offset;
-            }
-            continue;
-        }
-
-        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) == 0) {
-            ALOGW("Skipping entry %p in package table %d because it is not complex!\n",
-                 (void*)resID, (int)ip);
-            continue;
-        }
-
-        if (set != NULL && !type->config.isBetterThan(bestConfig, NULL)) {
-            continue;
-        }
-        bestConfig = type->config;
-        if (set) {
-            free(set);
-            set = NULL;
-        }
-
-        const uint16_t entrySize = dtohs(entry->size);
-        const uint32_t parent = entrySize >= sizeof(ResTable_map_entry)
-            ? dtohl(((const ResTable_map_entry*)entry)->parent.ident) : 0;
-        const uint32_t count = entrySize >= sizeof(ResTable_map_entry)
-            ? dtohl(((const ResTable_map_entry*)entry)->count) : 0;
-        
-        size_t N = count;
-
-        TABLE_NOISY(ALOGI("Found map: size=%p parent=%p count=%d\n",
-                         entrySize, parent, count));
-
-        // If this map inherits from another, we need to start
-        // with its parent's values.  Otherwise start out empty.
-        TABLE_NOISY(printf("Creating new bag, entrySize=0x%08x, parent=0x%08x\n",
-                           entrySize, parent));
-        if (parent) {
-            const bag_entry* parentBag;
-            uint32_t parentTypeSpecFlags = 0;
-            const ssize_t NP = getBagLocked(parent, &parentBag, &parentTypeSpecFlags);
-            const size_t NT = ((NP >= 0) ? NP : 0) + N;
-            set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*NT);
-            if (set == NULL) {
-                return NO_MEMORY;
-            }
-            if (NP > 0) {
-                memcpy(set+1, parentBag, NP*sizeof(bag_entry));
-                set->numAttrs = NP;
-                TABLE_NOISY(ALOGI("Initialized new bag with %d inherited attributes.\n", NP));
-            } else {
-                TABLE_NOISY(ALOGI("Initialized new bag with no inherited attributes.\n"));
-                set->numAttrs = 0;
-            }
-            set->availAttrs = NT;
-            set->typeSpecFlags = parentTypeSpecFlags;
-        } else {
-            set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*N);
-            if (set == NULL) {
-                return NO_MEMORY;
-            }
-            set->numAttrs = 0;
-            set->availAttrs = N;
-            set->typeSpecFlags = 0;
-        }
-
-        if (typeClass->typeSpecFlags != NULL) {
-            set->typeSpecFlags |= dtohl(typeClass->typeSpecFlags[E]);
-        } else {
-            set->typeSpecFlags = -1;
-        }
-        
-        // Now merge in the new attributes...
-        ssize_t curOff = offset;
-        const ResTable_map* map;
-        bag_entry* entries = (bag_entry*)(set+1);
-        size_t curEntry = 0;
-        uint32_t pos = 0;
-        TABLE_NOISY(ALOGI("Starting with set %p, entries=%p, avail=%d\n",
-                     set, entries, set->availAttrs));
-        while (pos < count) {
-            TABLE_NOISY(printf("Now at %p\n", (void*)curOff));
-
-            if ((size_t)curOff > (dtohl(type->header.size)-sizeof(ResTable_map))) {
-                ALOGW("ResTable_map at %d is beyond type chunk data %d",
-                     (int)curOff, dtohl(type->header.size));
-                return BAD_TYPE;
-            }
-            map = (const ResTable_map*)(((const uint8_t*)type) + curOff);
-            N++;
-
-            const uint32_t newName = htodl(map->name.ident);
-            bool isInside;
-            uint32_t oldName = 0;
-            while ((isInside=(curEntry < set->numAttrs))
-                    && (oldName=entries[curEntry].map.name.ident) < newName) {
-                TABLE_NOISY(printf("#%d: Keeping existing attribute: 0x%08x\n",
-                             curEntry, entries[curEntry].map.name.ident));
-                curEntry++;
-            }
-
-            if ((!isInside) || oldName != newName) {
-                // This is a new attribute...  figure out what to do with it.
-                if (set->numAttrs >= set->availAttrs) {
-                    // Need to alloc more memory...
-                    const size_t newAvail = set->availAttrs+N;
-                    set = (bag_set*)realloc(set,
-                                            sizeof(bag_set)
-                                            + sizeof(bag_entry)*newAvail);
-                    if (set == NULL) {
-                        return NO_MEMORY;
-                    }
-                    set->availAttrs = newAvail;
-                    entries = (bag_entry*)(set+1);
-                    TABLE_NOISY(printf("Reallocated set %p, entries=%p, avail=%d\n",
-                                 set, entries, set->availAttrs));
-                }
-                if (isInside) {
-                    // Going in the middle, need to make space.
-                    memmove(entries+curEntry+1, entries+curEntry,
-                            sizeof(bag_entry)*(set->numAttrs-curEntry));
-                    set->numAttrs++;
-                }
-                TABLE_NOISY(printf("#%d: Inserting new attribute: 0x%08x\n",
-                             curEntry, newName));
-            } else {
-                TABLE_NOISY(printf("#%d: Replacing existing attribute: 0x%08x\n",
-                             curEntry, oldName));
-            }
-
-            bag_entry* cur = entries+curEntry;
-
-            cur->stringBlock = package->header->index;
-            cur->map.name.ident = newName;
-            cur->map.value.copyFrom_dtoh(map->value);
-            TABLE_NOISY(printf("Setting entry #%d %p: block=%d, name=0x%08x, type=%d, data=0x%08x\n",
-                         curEntry, cur, cur->stringBlock, cur->map.name.ident,
-                         cur->map.value.dataType, cur->map.value.data));
-
-            // On to the next!
-            curEntry++;
-            pos++;
-            const size_t size = dtohs(map->value.size);
-            curOff += size + sizeof(*map)-sizeof(map->value);
-        };
-        if (curEntry > set->numAttrs) {
-            set->numAttrs = curEntry;
-        }
-    }
-
-    // And this is it...
-    typeSet[e] = set;
-    if (set) {
-        if (outTypeSpecFlags != NULL) {
-            *outTypeSpecFlags = set->typeSpecFlags;
-        }
-        *outBag = (bag_entry*)(set+1);
-        TABLE_NOISY(ALOGI("Returning %d attrs\n", set->numAttrs));
-        return set->numAttrs;
-    }
-    return BAD_INDEX;
-}
-
-void ResTable::setParameters(const ResTable_config* params)
-{
-    mLock.lock();
-    TABLE_GETENTRY(ALOGI("Setting parameters: %s\n", params->toString().string()));
-    mParams = *params;
-    for (size_t i=0; i<mPackageGroups.size(); i++) {
-        TABLE_NOISY(ALOGI("CLEARING BAGS FOR GROUP %d!", i));
-        mPackageGroups[i]->clearBagCache();
-    }
-    mLock.unlock();
-}
-
-void ResTable::getParameters(ResTable_config* params) const
-{
-    mLock.lock();
-    *params = mParams;
-    mLock.unlock();
-}
-
-struct id_name_map {
-    uint32_t id;
-    size_t len;
-    char16_t name[6];
-};
-
-const static id_name_map ID_NAMES[] = {
-    { ResTable_map::ATTR_TYPE,  5, { '^', 't', 'y', 'p', 'e' } },
-    { ResTable_map::ATTR_L10N,  5, { '^', 'l', '1', '0', 'n' } },
-    { ResTable_map::ATTR_MIN,   4, { '^', 'm', 'i', 'n' } },
-    { ResTable_map::ATTR_MAX,   4, { '^', 'm', 'a', 'x' } },
-    { ResTable_map::ATTR_OTHER, 6, { '^', 'o', 't', 'h', 'e', 'r' } },
-    { ResTable_map::ATTR_ZERO,  5, { '^', 'z', 'e', 'r', 'o' } },
-    { ResTable_map::ATTR_ONE,   4, { '^', 'o', 'n', 'e' } },
-    { ResTable_map::ATTR_TWO,   4, { '^', 't', 'w', 'o' } },
-    { ResTable_map::ATTR_FEW,   4, { '^', 'f', 'e', 'w' } },
-    { ResTable_map::ATTR_MANY,  5, { '^', 'm', 'a', 'n', 'y' } },
-};
-
-uint32_t ResTable::identifierForName(const char16_t* name, size_t nameLen,
-                                     const char16_t* type, size_t typeLen,
-                                     const char16_t* package,
-                                     size_t packageLen,
-                                     uint32_t* outTypeSpecFlags) const
-{
-    TABLE_SUPER_NOISY(printf("Identifier for name: error=%d\n", mError));
-
-    // Check for internal resource identifier as the very first thing, so
-    // that we will always find them even when there are no resources.
-    if (name[0] == '^') {
-        const int N = (sizeof(ID_NAMES)/sizeof(ID_NAMES[0]));
-        size_t len;
-        for (int i=0; i<N; i++) {
-            const id_name_map* m = ID_NAMES + i;
-            len = m->len;
-            if (len != nameLen) {
-                continue;
-            }
-            for (size_t j=1; j<len; j++) {
-                if (m->name[j] != name[j]) {
-                    goto nope;
-                }
-            }
-            if (outTypeSpecFlags) {
-                *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC;
-            }
-            return m->id;
-nope:
-            ;
-        }
-        if (nameLen > 7) {
-            if (name[1] == 'i' && name[2] == 'n'
-                && name[3] == 'd' && name[4] == 'e' && name[5] == 'x'
-                && name[6] == '_') {
-                int index = atoi(String8(name + 7, nameLen - 7).string());
-                if (Res_CHECKID(index)) {
-                    ALOGW("Array resource index: %d is too large.",
-                         index);
-                    return 0;
-                }
-                if (outTypeSpecFlags) {
-                    *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC;
-                }
-                return  Res_MAKEARRAY(index);
-            }
-        }
-        return 0;
-    }
-
-    if (mError != NO_ERROR) {
-        return 0;
-    }
-
-    bool fakePublic = false;
-
-    // Figure out the package and type we are looking in...
-
-    const char16_t* packageEnd = NULL;
-    const char16_t* typeEnd = NULL;
-    const char16_t* const nameEnd = name+nameLen;
-    const char16_t* p = name;
-    while (p < nameEnd) {
-        if (*p == ':') packageEnd = p;
-        else if (*p == '/') typeEnd = p;
-        p++;
-    }
-    if (*name == '@') {
-        name++;
-        if (*name == '*') {
-            fakePublic = true;
-            name++;
-        }
-    }
-    if (name >= nameEnd) {
-        return 0;
-    }
-
-    if (packageEnd) {
-        package = name;
-        packageLen = packageEnd-name;
-        name = packageEnd+1;
-    } else if (!package) {
-        return 0;
-    }
-
-    if (typeEnd) {
-        type = name;
-        typeLen = typeEnd-name;
-        name = typeEnd+1;
-    } else if (!type) {
-        return 0;
-    }
-
-    if (name >= nameEnd) {
-        return 0;
-    }
-    nameLen = nameEnd-name;
-
-    TABLE_NOISY(printf("Looking for identifier: type=%s, name=%s, package=%s\n",
-                 String8(type, typeLen).string(),
-                 String8(name, nameLen).string(),
-                 String8(package, packageLen).string()));
-
-    const size_t NG = mPackageGroups.size();
-    for (size_t ig=0; ig<NG; ig++) {
-        const PackageGroup* group = mPackageGroups[ig];
-
-        if (strzcmp16(package, packageLen,
-                      group->name.string(), group->name.size())) {
-            TABLE_NOISY(printf("Skipping package group: %s\n", String8(group->name).string()));
-            continue;
-        }
-
-        const ssize_t ti = group->basePackage->typeStrings.indexOfString(type, typeLen);
-        if (ti < 0) {
-            TABLE_NOISY(printf("Type not found in package %s\n", String8(group->name).string()));
-            continue;
-        }
-
-        const ssize_t ei = group->basePackage->keyStrings.indexOfString(name, nameLen);
-        if (ei < 0) {
-            TABLE_NOISY(printf("Name not found in package %s\n", String8(group->name).string()));
-            continue;
-        }
-
-        TABLE_NOISY(printf("Search indices: type=%d, name=%d\n", ti, ei));
-
-        const Type* const typeConfigs = group->packages[0]->getType(ti);
-        if (typeConfigs == NULL || typeConfigs->configs.size() <= 0) {
-            TABLE_NOISY(printf("Expected type structure not found in package %s for idnex %d\n",
-                               String8(group->name).string(), ti));
-        }
-        
-        size_t NTC = typeConfigs->configs.size();
-        for (size_t tci=0; tci<NTC; tci++) {
-            const ResTable_type* const ty = typeConfigs->configs[tci];
-            const uint32_t typeOffset = dtohl(ty->entriesStart);
-
-            const uint8_t* const end = ((const uint8_t*)ty) + dtohl(ty->header.size);
-            const uint32_t* const eindex = (const uint32_t*)
-                (((const uint8_t*)ty) + dtohs(ty->header.headerSize));
-
-            const size_t NE = dtohl(ty->entryCount);
-            for (size_t i=0; i<NE; i++) {
-                uint32_t offset = dtohl(eindex[i]);
-                if (offset == ResTable_type::NO_ENTRY) {
-                    continue;
-                }
-                
-                offset += typeOffset;
-                
-                if (offset > (dtohl(ty->header.size)-sizeof(ResTable_entry))) {
-                    ALOGW("ResTable_entry at %d is beyond type chunk data %d",
-                         offset, dtohl(ty->header.size));
-                    return 0;
-                }
-                if ((offset&0x3) != 0) {
-                    ALOGW("ResTable_entry at %d (pkg=%d type=%d ent=%d) is not on an integer boundary when looking for %s:%s/%s",
-                         (int)offset, (int)group->id, (int)ti+1, (int)i,
-                         String8(package, packageLen).string(),
-                         String8(type, typeLen).string(),
-                         String8(name, nameLen).string());
-                    return 0;
-                }
-                
-                const ResTable_entry* const entry = (const ResTable_entry*)
-                    (((const uint8_t*)ty) + offset);
-                if (dtohs(entry->size) < sizeof(*entry)) {
-                    ALOGW("ResTable_entry size %d is too small", dtohs(entry->size));
-                    return BAD_TYPE;
-                }
-
-                TABLE_SUPER_NOISY(printf("Looking at entry #%d: want str %d, have %d\n",
-                                         i, ei, dtohl(entry->key.index)));
-                if (dtohl(entry->key.index) == (size_t)ei) {
-                    if (outTypeSpecFlags) {
-                        *outTypeSpecFlags = typeConfigs->typeSpecFlags[i];
-                        if (fakePublic) {
-                            *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC;
-                        }
-                    }
-                    return Res_MAKEID(group->id-1, ti, i);
-                }
-            }
-        }
-    }
-
-    return 0;
-}
-
-bool ResTable::expandResourceRef(const uint16_t* refStr, size_t refLen,
-                                 String16* outPackage,
-                                 String16* outType,
-                                 String16* outName,
-                                 const String16* defType,
-                                 const String16* defPackage,
-                                 const char** outErrorMsg,
-                                 bool* outPublicOnly)
-{
-    const char16_t* packageEnd = NULL;
-    const char16_t* typeEnd = NULL;
-    const char16_t* p = refStr;
-    const char16_t* const end = p + refLen;
-    while (p < end) {
-        if (*p == ':') packageEnd = p;
-        else if (*p == '/') {
-            typeEnd = p;
-            break;
-        }
-        p++;
-    }
-    p = refStr;
-    if (*p == '@') p++;
-
-    if (outPublicOnly != NULL) {
-        *outPublicOnly = true;
-    }
-    if (*p == '*') {
-        p++;
-        if (outPublicOnly != NULL) {
-            *outPublicOnly = false;
-        }
-    }
-
-    if (packageEnd) {
-        *outPackage = String16(p, packageEnd-p);
-        p = packageEnd+1;
-    } else {
-        if (!defPackage) {
-            if (outErrorMsg) {
-                *outErrorMsg = "No resource package specified";
-            }
-            return false;
-        }
-        *outPackage = *defPackage;
-    }
-    if (typeEnd) {
-        *outType = String16(p, typeEnd-p);
-        p = typeEnd+1;
-    } else {
-        if (!defType) {
-            if (outErrorMsg) {
-                *outErrorMsg = "No resource type specified";
-            }
-            return false;
-        }
-        *outType = *defType;
-    }
-    *outName = String16(p, end-p);
-    if(**outPackage == 0) {
-        if(outErrorMsg) {
-            *outErrorMsg = "Resource package cannot be an empty string";
-        }
-        return false;
-    }
-    if(**outType == 0) {
-        if(outErrorMsg) {
-            *outErrorMsg = "Resource type cannot be an empty string";
-        }
-        return false;
-    }
-    if(**outName == 0) {
-        if(outErrorMsg) {
-            *outErrorMsg = "Resource id cannot be an empty string";
-        }
-        return false;
-    }
-    return true;
-}
-
-static uint32_t get_hex(char c, bool* outError)
-{
-    if (c >= '0' && c <= '9') {
-        return c - '0';
-    } else if (c >= 'a' && c <= 'f') {
-        return c - 'a' + 0xa;
-    } else if (c >= 'A' && c <= 'F') {
-        return c - 'A' + 0xa;
-    }
-    *outError = true;
-    return 0;
-}
-
-struct unit_entry
-{
-    const char* name;
-    size_t len;
-    uint8_t type;
-    uint32_t unit;
-    float scale;
-};
-
-static const unit_entry unitNames[] = {
-    { "px", strlen("px"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PX, 1.0f },
-    { "dip", strlen("dip"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },
-    { "dp", strlen("dp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },
-    { "sp", strlen("sp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_SP, 1.0f },
-    { "pt", strlen("pt"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PT, 1.0f },
-    { "in", strlen("in"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_IN, 1.0f },
-    { "mm", strlen("mm"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_MM, 1.0f },
-    { "%", strlen("%"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION, 1.0f/100 },
-    { "%p", strlen("%p"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100 },
-    { NULL, 0, 0, 0, 0 }
-};
-
-static bool parse_unit(const char* str, Res_value* outValue,
-                       float* outScale, const char** outEnd)
-{
-    const char* end = str;
-    while (*end != 0 && !isspace((unsigned char)*end)) {
-        end++;
-    }
-    const size_t len = end-str;
-
-    const char* realEnd = end;
-    while (*realEnd != 0 && isspace((unsigned char)*realEnd)) {
-        realEnd++;
-    }
-    if (*realEnd != 0) {
-        return false;
-    }
-    
-    const unit_entry* cur = unitNames;
-    while (cur->name) {
-        if (len == cur->len && strncmp(cur->name, str, len) == 0) {
-            outValue->dataType = cur->type;
-            outValue->data = cur->unit << Res_value::COMPLEX_UNIT_SHIFT;
-            *outScale = cur->scale;
-            *outEnd = end;
-            //printf("Found unit %s for %s\n", cur->name, str);
-            return true;
-        }
-        cur++;
-    }
-
-    return false;
-}
-
-
-bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)
-{
-    while (len > 0 && isspace16(*s)) {
-        s++;
-        len--;
-    }
-
-    if (len <= 0) {
-        return false;
-    }
-
-    size_t i = 0;
-    int32_t val = 0;
-    bool neg = false;
-
-    if (*s == '-') {
-        neg = true;
-        i++;
-    }
-
-    if (s[i] < '0' || s[i] > '9') {
-        return false;
-    }
-
-    // Decimal or hex?
-    if (s[i] == '0' && s[i+1] == 'x') {
-        if (outValue)
-            outValue->dataType = outValue->TYPE_INT_HEX;
-        i += 2;
-        bool error = false;
-        while (i < len && !error) {
-            val = (val*16) + get_hex(s[i], &error);
-            i++;
-        }
-        if (error) {
-            return false;
-        }
-    } else {
-        if (outValue)
-            outValue->dataType = outValue->TYPE_INT_DEC;
-        while (i < len) {
-            if (s[i] < '0' || s[i] > '9') {
-                return false;
-            }
-            val = (val*10) + s[i]-'0';
-            i++;
-        }
-    }
-
-    if (neg) val = -val;
-
-    while (i < len && isspace16(s[i])) {
-        i++;
-    }
-
-    if (i == len) {
-        if (outValue)
-            outValue->data = val;
-        return true;
-    }
-
-    return false;
-}
-
-bool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue)
-{
-    while (len > 0 && isspace16(*s)) {
-        s++;
-        len--;
-    }
-
-    if (len <= 0) {
-        return false;
-    }
-
-    char buf[128];
-    int i=0;
-    while (len > 0 && *s != 0 && i < 126) {
-        if (*s > 255) {
-            return false;
-        }
-        buf[i++] = *s++;
-        len--;
-    }
-
-    if (len > 0) {
-        return false;
-    }
-    if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') {
-        return false;
-    }
-
-    buf[i] = 0;
-    const char* end;
-    float f = strtof(buf, (char**)&end);
-
-    if (*end != 0 && !isspace((unsigned char)*end)) {
-        // Might be a unit...
-        float scale;
-        if (parse_unit(end, outValue, &scale, &end)) {
-            f *= scale;
-            const bool neg = f < 0;
-            if (neg) f = -f;
-            uint64_t bits = (uint64_t)(f*(1<<23)+.5f);
-            uint32_t radix;
-            uint32_t shift;
-            if ((bits&0x7fffff) == 0) {
-                // Always use 23p0 if there is no fraction, just to make
-                // things easier to read.
-                radix = Res_value::COMPLEX_RADIX_23p0;
-                shift = 23;
-            } else if ((bits&0xffffffffff800000LL) == 0) {
-                // Magnitude is zero -- can fit in 0 bits of precision.
-                radix = Res_value::COMPLEX_RADIX_0p23;
-                shift = 0;
-            } else if ((bits&0xffffffff80000000LL) == 0) {
-                // Magnitude can fit in 8 bits of precision.
-                radix = Res_value::COMPLEX_RADIX_8p15;
-                shift = 8;
-            } else if ((bits&0xffffff8000000000LL) == 0) {
-                // Magnitude can fit in 16 bits of precision.
-                radix = Res_value::COMPLEX_RADIX_16p7;
-                shift = 16;
-            } else {
-                // Magnitude needs entire range, so no fractional part.
-                radix = Res_value::COMPLEX_RADIX_23p0;
-                shift = 23;
-            }
-            int32_t mantissa = (int32_t)(
-                (bits>>shift) & Res_value::COMPLEX_MANTISSA_MASK);
-            if (neg) {
-                mantissa = (-mantissa) & Res_value::COMPLEX_MANTISSA_MASK;
-            }
-            outValue->data |= 
-                (radix<<Res_value::COMPLEX_RADIX_SHIFT)
-                | (mantissa<<Res_value::COMPLEX_MANTISSA_SHIFT);
-            //printf("Input value: %f 0x%016Lx, mult: %f, radix: %d, shift: %d, final: 0x%08x\n",
-            //       f * (neg ? -1 : 1), bits, f*(1<<23),
-            //       radix, shift, outValue->data);
-            return true;
-        }
-        return false;
-    }
-
-    while (*end != 0 && isspace((unsigned char)*end)) {
-        end++;
-    }
-
-    if (*end == 0) {
-        if (outValue) {
-            outValue->dataType = outValue->TYPE_FLOAT;
-            *(float*)(&outValue->data) = f;
-            return true;
-        }
-    }
-
-    return false;
-}
-
-bool ResTable::stringToValue(Res_value* outValue, String16* outString,
-                             const char16_t* s, size_t len,
-                             bool preserveSpaces, bool coerceType,
-                             uint32_t attrID,
-                             const String16* defType,
-                             const String16* defPackage,
-                             Accessor* accessor,
-                             void* accessorCookie,
-                             uint32_t attrType,
-                             bool enforcePrivate) const
-{
-    bool localizationSetting = accessor != NULL && accessor->getLocalizationSetting();
-    const char* errorMsg = NULL;
-
-    outValue->size = sizeof(Res_value);
-    outValue->res0 = 0;
-
-    // First strip leading/trailing whitespace.  Do this before handling
-    // escapes, so they can be used to force whitespace into the string.
-    if (!preserveSpaces) {
-        while (len > 0 && isspace16(*s)) {
-            s++;
-            len--;
-        }
-        while (len > 0 && isspace16(s[len-1])) {
-            len--;
-        }
-        // If the string ends with '\', then we keep the space after it.
-        if (len > 0 && s[len-1] == '\\' && s[len] != 0) {
-            len++;
-        }
-    }
-
-    //printf("Value for: %s\n", String8(s, len).string());
-
-    uint32_t l10nReq = ResTable_map::L10N_NOT_REQUIRED;
-    uint32_t attrMin = 0x80000000, attrMax = 0x7fffffff;
-    bool fromAccessor = false;
-    if (attrID != 0 && !Res_INTERNALID(attrID)) {
-        const ssize_t p = getResourcePackageIndex(attrID);
-        const bag_entry* bag;
-        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
-        //printf("For attr 0x%08x got bag of %d\n", attrID, cnt);
-        if (cnt >= 0) {
-            while (cnt > 0) {
-                //printf("Entry 0x%08x = 0x%08x\n", bag->map.name.ident, bag->map.value.data);
-                switch (bag->map.name.ident) {
-                case ResTable_map::ATTR_TYPE:
-                    attrType = bag->map.value.data;
-                    break;
-                case ResTable_map::ATTR_MIN:
-                    attrMin = bag->map.value.data;
-                    break;
-                case ResTable_map::ATTR_MAX:
-                    attrMax = bag->map.value.data;
-                    break;
-                case ResTable_map::ATTR_L10N:
-                    l10nReq = bag->map.value.data;
-                    break;
-                }
-                bag++;
-                cnt--;
-            }
-            unlockBag(bag);
-        } else if (accessor && accessor->getAttributeType(attrID, &attrType)) {
-            fromAccessor = true;
-            if (attrType == ResTable_map::TYPE_ENUM
-                    || attrType == ResTable_map::TYPE_FLAGS
-                    || attrType == ResTable_map::TYPE_INTEGER) {
-                accessor->getAttributeMin(attrID, &attrMin);
-                accessor->getAttributeMax(attrID, &attrMax);
-            }
-            if (localizationSetting) {
-                l10nReq = accessor->getAttributeL10N(attrID);
-            }
-        }
-    }
-
-    const bool canStringCoerce =
-        coerceType && (attrType&ResTable_map::TYPE_STRING) != 0;
-
-    if (*s == '@') {
-        outValue->dataType = outValue->TYPE_REFERENCE;
-
-        // Note: we don't check attrType here because the reference can
-        // be to any other type; we just need to count on the client making
-        // sure the referenced type is correct.
-        
-        //printf("Looking up ref: %s\n", String8(s, len).string());
-
-        // It's a reference!
-        if (len == 5 && s[1]=='n' && s[2]=='u' && s[3]=='l' && s[4]=='l') {
-            outValue->data = 0;
-            return true;
-        } else {
-            bool createIfNotFound = false;
-            const char16_t* resourceRefName;
-            int resourceNameLen;
-            if (len > 2 && s[1] == '+') {
-                createIfNotFound = true;
-                resourceRefName = s + 2;
-                resourceNameLen = len - 2;
-            } else if (len > 2 && s[1] == '*') {
-                enforcePrivate = false;
-                resourceRefName = s + 2;
-                resourceNameLen = len - 2;
-            } else {
-                createIfNotFound = false;
-                resourceRefName = s + 1;
-                resourceNameLen = len - 1;
-            }
-            String16 package, type, name;
-            if (!expandResourceRef(resourceRefName,resourceNameLen, &package, &type, &name,
-                                   defType, defPackage, &errorMsg)) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, errorMsg);
-                }
-                return false;
-            }
-
-            uint32_t specFlags = 0;
-            uint32_t rid = identifierForName(name.string(), name.size(), type.string(),
-                    type.size(), package.string(), package.size(), &specFlags);
-            if (rid != 0) {
-                if (enforcePrivate) {
-                    if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
-                        if (accessor != NULL) {
-                            accessor->reportError(accessorCookie, "Resource is not public.");
-                        }
-                        return false;
-                    }
-                }
-                if (!accessor) {
-                    outValue->data = rid;
-                    return true;
-                }
-                rid = Res_MAKEID(
-                    accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
-                    Res_GETTYPE(rid), Res_GETENTRY(rid));
-                TABLE_NOISY(printf("Incl %s:%s/%s: 0x%08x\n",
-                       String8(package).string(), String8(type).string(),
-                       String8(name).string(), rid));
-                outValue->data = rid;
-                return true;
-            }
-
-            if (accessor) {
-                uint32_t rid = accessor->getCustomResourceWithCreation(package, type, name,
-                                                                       createIfNotFound);
-                if (rid != 0) {
-                    TABLE_NOISY(printf("Pckg %s:%s/%s: 0x%08x\n",
-                           String8(package).string(), String8(type).string(),
-                           String8(name).string(), rid));
-                    outValue->data = rid;
-                    return true;
-                }
-            }
-        }
-
-        if (accessor != NULL) {
-            accessor->reportError(accessorCookie, "No resource found that matches the given name");
-        }
-        return false;
-    }
-
-    // if we got to here, and localization is required and it's not a reference,
-    // complain and bail.
-    if (l10nReq == ResTable_map::L10N_SUGGESTED) {
-        if (localizationSetting) {
-            if (accessor != NULL) {
-                accessor->reportError(accessorCookie, "This attribute must be localized.");
-            }
-        }
-    }
-    
-    if (*s == '#') {
-        // It's a color!  Convert to an integer of the form 0xaarrggbb.
-        uint32_t color = 0;
-        bool error = false;
-        if (len == 4) {
-            outValue->dataType = outValue->TYPE_INT_COLOR_RGB4;
-            color |= 0xFF000000;
-            color |= get_hex(s[1], &error) << 20;
-            color |= get_hex(s[1], &error) << 16;
-            color |= get_hex(s[2], &error) << 12;
-            color |= get_hex(s[2], &error) << 8;
-            color |= get_hex(s[3], &error) << 4;
-            color |= get_hex(s[3], &error);
-        } else if (len == 5) {
-            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB4;
-            color |= get_hex(s[1], &error) << 28;
-            color |= get_hex(s[1], &error) << 24;
-            color |= get_hex(s[2], &error) << 20;
-            color |= get_hex(s[2], &error) << 16;
-            color |= get_hex(s[3], &error) << 12;
-            color |= get_hex(s[3], &error) << 8;
-            color |= get_hex(s[4], &error) << 4;
-            color |= get_hex(s[4], &error);
-        } else if (len == 7) {
-            outValue->dataType = outValue->TYPE_INT_COLOR_RGB8;
-            color |= 0xFF000000;
-            color |= get_hex(s[1], &error) << 20;
-            color |= get_hex(s[2], &error) << 16;
-            color |= get_hex(s[3], &error) << 12;
-            color |= get_hex(s[4], &error) << 8;
-            color |= get_hex(s[5], &error) << 4;
-            color |= get_hex(s[6], &error);
-        } else if (len == 9) {
-            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB8;
-            color |= get_hex(s[1], &error) << 28;
-            color |= get_hex(s[2], &error) << 24;
-            color |= get_hex(s[3], &error) << 20;
-            color |= get_hex(s[4], &error) << 16;
-            color |= get_hex(s[5], &error) << 12;
-            color |= get_hex(s[6], &error) << 8;
-            color |= get_hex(s[7], &error) << 4;
-            color |= get_hex(s[8], &error);
-        } else {
-            error = true;
-        }
-        if (!error) {
-            if ((attrType&ResTable_map::TYPE_COLOR) == 0) {
-                if (!canStringCoerce) {
-                    if (accessor != NULL) {
-                        accessor->reportError(accessorCookie,
-                                "Color types not allowed");
-                    }
-                    return false;
-                }
-            } else {
-                outValue->data = color;
-                //printf("Color input=%s, output=0x%x\n", String8(s, len).string(), color);
-                return true;
-            }
-        } else {
-            if ((attrType&ResTable_map::TYPE_COLOR) != 0) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, "Color value not valid --"
-                            " must be #rgb, #argb, #rrggbb, or #aarrggbb");
-                }
-                #if 0
-                fprintf(stderr, "%s: Color ID %s value %s is not valid\n",
-                        "Resource File", //(const char*)in->getPrintableSource(),
-                        String8(*curTag).string(),
-                        String8(s, len).string());
-                #endif
-                return false;
-            }
-        }
-    }
-
-    if (*s == '?') {
-        outValue->dataType = outValue->TYPE_ATTRIBUTE;
-
-        // Note: we don't check attrType here because the reference can
-        // be to any other type; we just need to count on the client making
-        // sure the referenced type is correct.
-
-        //printf("Looking up attr: %s\n", String8(s, len).string());
-
-        static const String16 attr16("attr");
-        String16 package, type, name;
-        if (!expandResourceRef(s+1, len-1, &package, &type, &name,
-                               &attr16, defPackage, &errorMsg)) {
-            if (accessor != NULL) {
-                accessor->reportError(accessorCookie, errorMsg);
-            }
-            return false;
-        }
-
-        //printf("Pkg: %s, Type: %s, Name: %s\n",
-        //       String8(package).string(), String8(type).string(),
-        //       String8(name).string());
-        uint32_t specFlags = 0;
-        uint32_t rid = 
-            identifierForName(name.string(), name.size(),
-                              type.string(), type.size(),
-                              package.string(), package.size(), &specFlags);
-        if (rid != 0) {
-            if (enforcePrivate) {
-                if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
-                    if (accessor != NULL) {
-                        accessor->reportError(accessorCookie, "Attribute is not public.");
-                    }
-                    return false;
-                }
-            }
-            if (!accessor) {
-                outValue->data = rid;
-                return true;
-            }
-            rid = Res_MAKEID(
-                accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
-                Res_GETTYPE(rid), Res_GETENTRY(rid));
-            //printf("Incl %s:%s/%s: 0x%08x\n",
-            //       String8(package).string(), String8(type).string(),
-            //       String8(name).string(), rid);
-            outValue->data = rid;
-            return true;
-        }
-
-        if (accessor) {
-            uint32_t rid = accessor->getCustomResource(package, type, name);
-            if (rid != 0) {
-                //printf("Mine %s:%s/%s: 0x%08x\n",
-                //       String8(package).string(), String8(type).string(),
-                //       String8(name).string(), rid);
-                outValue->data = rid;
-                return true;
-            }
-        }
-
-        if (accessor != NULL) {
-            accessor->reportError(accessorCookie, "No resource found that matches the given name");
-        }
-        return false;
-    }
-
-    if (stringToInt(s, len, outValue)) {
-        if ((attrType&ResTable_map::TYPE_INTEGER) == 0) {
-            // If this type does not allow integers, but does allow floats,
-            // fall through on this error case because the float type should
-            // be able to accept any integer value.
-            if (!canStringCoerce && (attrType&ResTable_map::TYPE_FLOAT) == 0) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, "Integer types not allowed");
-                }
-                return false;
-            }
-        } else {
-            if (((int32_t)outValue->data) < ((int32_t)attrMin)
-                    || ((int32_t)outValue->data) > ((int32_t)attrMax)) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, "Integer value out of range");
-                }
-                return false;
-            }
-            return true;
-        }
-    }
-
-    if (stringToFloat(s, len, outValue)) {
-        if (outValue->dataType == Res_value::TYPE_DIMENSION) {
-            if ((attrType&ResTable_map::TYPE_DIMENSION) != 0) {
-                return true;
-            }
-            if (!canStringCoerce) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, "Dimension types not allowed");
-                }
-                return false;
-            }
-        } else if (outValue->dataType == Res_value::TYPE_FRACTION) {
-            if ((attrType&ResTable_map::TYPE_FRACTION) != 0) {
-                return true;
-            }
-            if (!canStringCoerce) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, "Fraction types not allowed");
-                }
-                return false;
-            }
-        } else if ((attrType&ResTable_map::TYPE_FLOAT) == 0) {
-            if (!canStringCoerce) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, "Float types not allowed");
-                }
-                return false;
-            }
-        } else {
-            return true;
-        }
-    }
-
-    if (len == 4) {
-        if ((s[0] == 't' || s[0] == 'T') &&
-            (s[1] == 'r' || s[1] == 'R') &&
-            (s[2] == 'u' || s[2] == 'U') &&
-            (s[3] == 'e' || s[3] == 'E')) {
-            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {
-                if (!canStringCoerce) {
-                    if (accessor != NULL) {
-                        accessor->reportError(accessorCookie, "Boolean types not allowed");
-                    }
-                    return false;
-                }
-            } else {
-                outValue->dataType = outValue->TYPE_INT_BOOLEAN;
-                outValue->data = (uint32_t)-1;
-                return true;
-            }
-        }
-    }
-
-    if (len == 5) {
-        if ((s[0] == 'f' || s[0] == 'F') &&
-            (s[1] == 'a' || s[1] == 'A') &&
-            (s[2] == 'l' || s[2] == 'L') &&
-            (s[3] == 's' || s[3] == 'S') &&
-            (s[4] == 'e' || s[4] == 'E')) {
-            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {
-                if (!canStringCoerce) {
-                    if (accessor != NULL) {
-                        accessor->reportError(accessorCookie, "Boolean types not allowed");
-                    }
-                    return false;
-                }
-            } else {
-                outValue->dataType = outValue->TYPE_INT_BOOLEAN;
-                outValue->data = 0;
-                return true;
-            }
-        }
-    }
-
-    if ((attrType&ResTable_map::TYPE_ENUM) != 0) {
-        const ssize_t p = getResourcePackageIndex(attrID);
-        const bag_entry* bag;
-        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
-        //printf("Got %d for enum\n", cnt);
-        if (cnt >= 0) {
-            resource_name rname;
-            while (cnt > 0) {
-                if (!Res_INTERNALID(bag->map.name.ident)) {
-                    //printf("Trying attr #%08x\n", bag->map.name.ident);
-                    if (getResourceName(bag->map.name.ident, false, &rname)) {
-                        #if 0
-                        printf("Matching %s against %s (0x%08x)\n",
-                               String8(s, len).string(),
-                               String8(rname.name, rname.nameLen).string(),
-                               bag->map.name.ident);
-                        #endif
-                        if (strzcmp16(s, len, rname.name, rname.nameLen) == 0) {
-                            outValue->dataType = bag->map.value.dataType;
-                            outValue->data = bag->map.value.data;
-                            unlockBag(bag);
-                            return true;
-                        }
-                    }
-    
-                }
-                bag++;
-                cnt--;
-            }
-            unlockBag(bag);
-        }
-
-        if (fromAccessor) {
-            if (accessor->getAttributeEnum(attrID, s, len, outValue)) {
-                return true;
-            }
-        }
-    }
-
-    if ((attrType&ResTable_map::TYPE_FLAGS) != 0) {
-        const ssize_t p = getResourcePackageIndex(attrID);
-        const bag_entry* bag;
-        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
-        //printf("Got %d for flags\n", cnt);
-        if (cnt >= 0) {
-            bool failed = false;
-            resource_name rname;
-            outValue->dataType = Res_value::TYPE_INT_HEX;
-            outValue->data = 0;
-            const char16_t* end = s + len;
-            const char16_t* pos = s;
-            while (pos < end && !failed) {
-                const char16_t* start = pos;
-                pos++;
-                while (pos < end && *pos != '|') {
-                    pos++;
-                }
-                //printf("Looking for: %s\n", String8(start, pos-start).string());
-                const bag_entry* bagi = bag;
-                ssize_t i;
-                for (i=0; i<cnt; i++, bagi++) {
-                    if (!Res_INTERNALID(bagi->map.name.ident)) {
-                        //printf("Trying attr #%08x\n", bagi->map.name.ident);
-                        if (getResourceName(bagi->map.name.ident, false, &rname)) {
-                            #if 0
-                            printf("Matching %s against %s (0x%08x)\n",
-                                   String8(start,pos-start).string(),
-                                   String8(rname.name, rname.nameLen).string(),
-                                   bagi->map.name.ident);
-                            #endif
-                            if (strzcmp16(start, pos-start, rname.name, rname.nameLen) == 0) {
-                                outValue->data |= bagi->map.value.data;
-                                break;
-                            }
-                        }
-                    }
-                }
-                if (i >= cnt) {
-                    // Didn't find this flag identifier.
-                    failed = true;
-                }
-                if (pos < end) {
-                    pos++;
-                }
-            }
-            unlockBag(bag);
-            if (!failed) {
-                //printf("Final flag value: 0x%lx\n", outValue->data);
-                return true;
-            }
-        }
-
-
-        if (fromAccessor) {
-            if (accessor->getAttributeFlags(attrID, s, len, outValue)) {
-                //printf("Final flag value: 0x%lx\n", outValue->data);
-                return true;
-            }
-        }
-    }
-
-    if ((attrType&ResTable_map::TYPE_STRING) == 0) {
-        if (accessor != NULL) {
-            accessor->reportError(accessorCookie, "String types not allowed");
-        }
-        return false;
-    }
-
-    // Generic string handling...
-    outValue->dataType = outValue->TYPE_STRING;
-    if (outString) {
-        bool failed = collectString(outString, s, len, preserveSpaces, &errorMsg);
-        if (accessor != NULL) {
-            accessor->reportError(accessorCookie, errorMsg);
-        }
-        return failed;
-    }
-
-    return true;
-}
-
-bool ResTable::collectString(String16* outString,
-                             const char16_t* s, size_t len,
-                             bool preserveSpaces,
-                             const char** outErrorMsg,
-                             bool append)
-{
-    String16 tmp;
-
-    char quoted = 0;
-    const char16_t* p = s;
-    while (p < (s+len)) {
-        while (p < (s+len)) {
-            const char16_t c = *p;
-            if (c == '\\') {
-                break;
-            }
-            if (!preserveSpaces) {
-                if (quoted == 0 && isspace16(c)
-                    && (c != ' ' || isspace16(*(p+1)))) {
-                    break;
-                }
-                if (c == '"' && (quoted == 0 || quoted == '"')) {
-                    break;
-                }
-                if (c == '\'' && (quoted == 0 || quoted == '\'')) {
-                    /*
-                     * In practice, when people write ' instead of \'
-                     * in a string, they are doing it by accident
-                     * instead of really meaning to use ' as a quoting
-                     * character.  Warn them so they don't lose it.
-                     */
-                    if (outErrorMsg) {
-                        *outErrorMsg = "Apostrophe not preceded by \\";
-                    }
-                    return false;
-                }
-            }
-            p++;
-        }
-        if (p < (s+len)) {
-            if (p > s) {
-                tmp.append(String16(s, p-s));
-            }
-            if (!preserveSpaces && (*p == '"' || *p == '\'')) {
-                if (quoted == 0) {
-                    quoted = *p;
-                } else {
-                    quoted = 0;
-                }
-                p++;
-            } else if (!preserveSpaces && isspace16(*p)) {
-                // Space outside of a quote -- consume all spaces and
-                // leave a single plain space char.
-                tmp.append(String16(" "));
-                p++;
-                while (p < (s+len) && isspace16(*p)) {
-                    p++;
-                }
-            } else if (*p == '\\') {
-                p++;
-                if (p < (s+len)) {
-                    switch (*p) {
-                    case 't':
-                        tmp.append(String16("\t"));
-                        break;
-                    case 'n':
-                        tmp.append(String16("\n"));
-                        break;
-                    case '#':
-                        tmp.append(String16("#"));
-                        break;
-                    case '@':
-                        tmp.append(String16("@"));
-                        break;
-                    case '?':
-                        tmp.append(String16("?"));
-                        break;
-                    case '"':
-                        tmp.append(String16("\""));
-                        break;
-                    case '\'':
-                        tmp.append(String16("'"));
-                        break;
-                    case '\\':
-                        tmp.append(String16("\\"));
-                        break;
-                    case 'u':
-                    {
-                        char16_t chr = 0;
-                        int i = 0;
-                        while (i < 4 && p[1] != 0) {
-                            p++;
-                            i++;
-                            int c;
-                            if (*p >= '0' && *p <= '9') {
-                                c = *p - '0';
-                            } else if (*p >= 'a' && *p <= 'f') {
-                                c = *p - 'a' + 10;
-                            } else if (*p >= 'A' && *p <= 'F') {
-                                c = *p - 'A' + 10;
-                            } else {
-                                if (outErrorMsg) {
-                                    *outErrorMsg = "Bad character in \\u unicode escape sequence";
-                                }
-                                return false;
-                            }
-                            chr = (chr<<4) | c;
-                        }
-                        tmp.append(String16(&chr, 1));
-                    } break;
-                    default:
-                        // ignore unknown escape chars.
-                        break;
-                    }
-                    p++;
-                }
-            }
-            len -= (p-s);
-            s = p;
-        }
-    }
-
-    if (tmp.size() != 0) {
-        if (len > 0) {
-            tmp.append(String16(s, len));
-        }
-        if (append) {
-            outString->append(tmp);
-        } else {
-            outString->setTo(tmp);
-        }
-    } else {
-        if (append) {
-            outString->append(String16(s, len));
-        } else {
-            outString->setTo(s, len);
-        }
-    }
-
-    return true;
-}
-
-size_t ResTable::getBasePackageCount() const
-{
-    if (mError != NO_ERROR) {
-        return 0;
-    }
-    return mPackageGroups.size();
-}
-
-const char16_t* ResTable::getBasePackageName(size_t idx) const
-{
-    if (mError != NO_ERROR) {
-        return 0;
-    }
-    LOG_FATAL_IF(idx >= mPackageGroups.size(),
-                 "Requested package index %d past package count %d",
-                 (int)idx, (int)mPackageGroups.size());
-    return mPackageGroups[idx]->name.string();
-}
-
-uint32_t ResTable::getBasePackageId(size_t idx) const
-{
-    if (mError != NO_ERROR) {
-        return 0;
-    }
-    LOG_FATAL_IF(idx >= mPackageGroups.size(),
-                 "Requested package index %d past package count %d",
-                 (int)idx, (int)mPackageGroups.size());
-    return mPackageGroups[idx]->id;
-}
-
-size_t ResTable::getTableCount() const
-{
-    return mHeaders.size();
-}
-
-const ResStringPool* ResTable::getTableStringBlock(size_t index) const
-{
-    return &mHeaders[index]->values;
-}
-
-void* ResTable::getTableCookie(size_t index) const
-{
-    return mHeaders[index]->cookie;
-}
-
-void ResTable::getConfigurations(Vector<ResTable_config>* configs) const
-{
-    const size_t I = mPackageGroups.size();
-    for (size_t i=0; i<I; i++) {
-        const PackageGroup* packageGroup = mPackageGroups[i];
-        const size_t J = packageGroup->packages.size();
-        for (size_t j=0; j<J; j++) {
-            const Package* package = packageGroup->packages[j];
-            const size_t K = package->types.size();
-            for (size_t k=0; k<K; k++) {
-                const Type* type = package->types[k];
-                if (type == NULL) continue;
-                const size_t L = type->configs.size();
-                for (size_t l=0; l<L; l++) {
-                    const ResTable_type* config = type->configs[l];
-                    const ResTable_config* cfg = &config->config;
-                    // only insert unique
-                    const size_t M = configs->size();
-                    size_t m;
-                    for (m=0; m<M; m++) {
-                        if (0 == (*configs)[m].compare(*cfg)) {
-                            break;
-                        }
-                    }
-                    // if we didn't find it
-                    if (m == M) {
-                        configs->add(*cfg);
-                    }
-                }
-            }
-        }
-    }
-}
-
-void ResTable::getLocales(Vector<String8>* locales) const
-{
-    Vector<ResTable_config> configs;
-    ALOGV("calling getConfigurations");
-    getConfigurations(&configs);
-    ALOGV("called getConfigurations size=%d", (int)configs.size());
-    const size_t I = configs.size();
-    for (size_t i=0; i<I; i++) {
-        char locale[6];
-        configs[i].getLocale(locale);
-        const size_t J = locales->size();
-        size_t j;
-        for (j=0; j<J; j++) {
-            if (0 == strcmp(locale, (*locales)[j].string())) {
-                break;
-            }
-        }
-        if (j == J) {
-            locales->add(String8(locale));
-        }
-    }
-}
-
-ssize_t ResTable::getEntry(
-    const Package* package, int typeIndex, int entryIndex,
-    const ResTable_config* config,
-    const ResTable_type** outType, const ResTable_entry** outEntry,
-    const Type** outTypeClass) const
-{
-    ALOGV("Getting entry from package %p\n", package);
-    const ResTable_package* const pkg = package->package;
-
-    const Type* allTypes = package->getType(typeIndex);
-    ALOGV("allTypes=%p\n", allTypes);
-    if (allTypes == NULL) {
-        ALOGV("Skipping entry type index 0x%02x because type is NULL!\n", typeIndex);
-        return 0;
-    }
-
-    if ((size_t)entryIndex >= allTypes->entryCount) {
-        ALOGW("getEntry failing because entryIndex %d is beyond type entryCount %d",
-            entryIndex, (int)allTypes->entryCount);
-        return BAD_TYPE;
-    }
-        
-    const ResTable_type* type = NULL;
-    uint32_t offset = ResTable_type::NO_ENTRY;
-    ResTable_config bestConfig;
-    memset(&bestConfig, 0, sizeof(bestConfig)); // make the compiler shut up
-    
-    const size_t NT = allTypes->configs.size();
-    for (size_t i=0; i<NT; i++) {
-        const ResTable_type* const thisType = allTypes->configs[i];
-        if (thisType == NULL) continue;
-        
-        ResTable_config thisConfig;
-        thisConfig.copyFromDtoH(thisType->config);
-
-        TABLE_GETENTRY(ALOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n",
-                           entryIndex, typeIndex+1, dtohl(thisType->config.size),
-                           thisConfig.toString().string()));
-        
-        // Check to make sure this one is valid for the current parameters.
-        if (config && !thisConfig.match(*config)) {
-            TABLE_GETENTRY(ALOGI("Does not match config!\n"));
-            continue;
-        }
-        
-        // Check if there is the desired entry in this type.
-        
-        const uint8_t* const end = ((const uint8_t*)thisType)
-            + dtohl(thisType->header.size);
-        const uint32_t* const eindex = (const uint32_t*)
-            (((const uint8_t*)thisType) + dtohs(thisType->header.headerSize));
-        
-        uint32_t thisOffset = dtohl(eindex[entryIndex]);
-        if (thisOffset == ResTable_type::NO_ENTRY) {
-            TABLE_GETENTRY(ALOGI("Skipping because it is not defined!\n"));
-            continue;
-        }
-        
-        if (type != NULL) {
-            // Check if this one is less specific than the last found.  If so,
-            // we will skip it.  We check starting with things we most care
-            // about to those we least care about.
-            if (!thisConfig.isBetterThan(bestConfig, config)) {
-                TABLE_GETENTRY(ALOGI("This config is worse than last!\n"));
-                continue;
-            }
-        }
-        
-        type = thisType;
-        offset = thisOffset;
-        bestConfig = thisConfig;
-        TABLE_GETENTRY(ALOGI("Best entry so far -- using it!\n"));
-        if (!config) break;
-    }
-    
-    if (type == NULL) {
-        TABLE_GETENTRY(ALOGI("No value found for requested entry!\n"));
-        return BAD_INDEX;
-    }
-    
-    offset += dtohl(type->entriesStart);
-    TABLE_NOISY(aout << "Looking in resource table " << package->header->header
-          << ", typeOff="
-          << (void*)(((const char*)type)-((const char*)package->header->header))
-          << ", offset=" << (void*)offset << endl);
-
-    if (offset > (dtohl(type->header.size)-sizeof(ResTable_entry))) {
-        ALOGW("ResTable_entry at 0x%x is beyond type chunk data 0x%x",
-             offset, dtohl(type->header.size));
-        return BAD_TYPE;
-    }
-    if ((offset&0x3) != 0) {
-        ALOGW("ResTable_entry at 0x%x is not on an integer boundary",
-             offset);
-        return BAD_TYPE;
-    }
-
-    const ResTable_entry* const entry = (const ResTable_entry*)
-        (((const uint8_t*)type) + offset);
-    if (dtohs(entry->size) < sizeof(*entry)) {
-        ALOGW("ResTable_entry size 0x%x is too small", dtohs(entry->size));
-        return BAD_TYPE;
-    }
-
-    *outType = type;
-    *outEntry = entry;
-    if (outTypeClass != NULL) {
-        *outTypeClass = allTypes;
-    }
-    return offset + dtohs(entry->size);
-}
-
-status_t ResTable::parsePackage(const ResTable_package* const pkg,
-                                const Header* const header, uint32_t idmap_id)
-{
-    const uint8_t* base = (const uint8_t*)pkg;
-    status_t err = validate_chunk(&pkg->header, sizeof(*pkg),
-                                  header->dataEnd, "ResTable_package");
-    if (err != NO_ERROR) {
-        return (mError=err);
-    }
-
-    const size_t pkgSize = dtohl(pkg->header.size);
-
-    if (dtohl(pkg->typeStrings) >= pkgSize) {
-        ALOGW("ResTable_package type strings at %p are past chunk size %p.",
-             (void*)dtohl(pkg->typeStrings), (void*)pkgSize);
-        return (mError=BAD_TYPE);
-    }
-    if ((dtohl(pkg->typeStrings)&0x3) != 0) {
-        ALOGW("ResTable_package type strings at %p is not on an integer boundary.",
-             (void*)dtohl(pkg->typeStrings));
-        return (mError=BAD_TYPE);
-    }
-    if (dtohl(pkg->keyStrings) >= pkgSize) {
-        ALOGW("ResTable_package key strings at %p are past chunk size %p.",
-             (void*)dtohl(pkg->keyStrings), (void*)pkgSize);
-        return (mError=BAD_TYPE);
-    }
-    if ((dtohl(pkg->keyStrings)&0x3) != 0) {
-        ALOGW("ResTable_package key strings at %p is not on an integer boundary.",
-             (void*)dtohl(pkg->keyStrings));
-        return (mError=BAD_TYPE);
-    }
-    
-    Package* package = NULL;
-    PackageGroup* group = NULL;
-    uint32_t id = idmap_id != 0 ? idmap_id : dtohl(pkg->id);
-    // If at this point id == 0, pkg is an overlay package without a
-    // corresponding idmap. During regular usage, overlay packages are
-    // always loaded alongside their idmaps, but during idmap creation
-    // the package is temporarily loaded by itself.
-    if (id < 256) {
-    
-        package = new Package(this, header, pkg);
-        if (package == NULL) {
-            return (mError=NO_MEMORY);
-        }
-        
-        size_t idx = mPackageMap[id];
-        if (idx == 0) {
-            idx = mPackageGroups.size()+1;
-
-            char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)];
-            strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t));
-            group = new PackageGroup(this, String16(tmpName), id);
-            if (group == NULL) {
-                delete package;
-                return (mError=NO_MEMORY);
-            }
-
-            err = package->typeStrings.setTo(base+dtohl(pkg->typeStrings),
-                                           header->dataEnd-(base+dtohl(pkg->typeStrings)));
-            if (err != NO_ERROR) {
-                delete group;
-                delete package;
-                return (mError=err);
-            }
-            err = package->keyStrings.setTo(base+dtohl(pkg->keyStrings),
-                                          header->dataEnd-(base+dtohl(pkg->keyStrings)));
-            if (err != NO_ERROR) {
-                delete group;
-                delete package;
-                return (mError=err);
-            }
-
-            //printf("Adding new package id %d at index %d\n", id, idx);
-            err = mPackageGroups.add(group);
-            if (err < NO_ERROR) {
-                return (mError=err);
-            }
-            group->basePackage = package;
-            
-            mPackageMap[id] = (uint8_t)idx;
-        } else {
-            group = mPackageGroups.itemAt(idx-1);
-            if (group == NULL) {
-                return (mError=UNKNOWN_ERROR);
-            }
-        }
-        err = group->packages.add(package);
-        if (err < NO_ERROR) {
-            return (mError=err);
-        }
-    } else {
-        LOG_ALWAYS_FATAL("Package id out of range");
-        return NO_ERROR;
-    }
-
-    
-    // Iterate through all chunks.
-    size_t curPackage = 0;
-    
-    const ResChunk_header* chunk =
-        (const ResChunk_header*)(((const uint8_t*)pkg)
-                                 + dtohs(pkg->header.headerSize));
-    const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);
-    while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&
-           ((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {
-        TABLE_NOISY(ALOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
-                         dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
-                         (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
-        const size_t csize = dtohl(chunk->size);
-        const uint16_t ctype = dtohs(chunk->type);
-        if (ctype == RES_TABLE_TYPE_SPEC_TYPE) {
-            const ResTable_typeSpec* typeSpec = (const ResTable_typeSpec*)(chunk);
-            err = validate_chunk(&typeSpec->header, sizeof(*typeSpec),
-                                 endPos, "ResTable_typeSpec");
-            if (err != NO_ERROR) {
-                return (mError=err);
-            }
-            
-            const size_t typeSpecSize = dtohl(typeSpec->header.size);
-            
-            LOAD_TABLE_NOISY(printf("TypeSpec off %p: type=0x%x, headerSize=0x%x, size=%p\n",
-                                    (void*)(base-(const uint8_t*)chunk),
-                                    dtohs(typeSpec->header.type),
-                                    dtohs(typeSpec->header.headerSize),
-                                    (void*)typeSize));
-            // look for block overrun or int overflow when multiplying by 4
-            if ((dtohl(typeSpec->entryCount) > (INT32_MAX/sizeof(uint32_t))
-                    || dtohs(typeSpec->header.headerSize)+(sizeof(uint32_t)*dtohl(typeSpec->entryCount))
-                    > typeSpecSize)) {
-                ALOGW("ResTable_typeSpec entry index to %p extends beyond chunk end %p.",
-                     (void*)(dtohs(typeSpec->header.headerSize)
-                             +(sizeof(uint32_t)*dtohl(typeSpec->entryCount))),
-                     (void*)typeSpecSize);
-                return (mError=BAD_TYPE);
-            }
-            
-            if (typeSpec->id == 0) {
-                ALOGW("ResTable_type has an id of 0.");
-                return (mError=BAD_TYPE);
-            }
-            
-            while (package->types.size() < typeSpec->id) {
-                package->types.add(NULL);
-            }
-            Type* t = package->types[typeSpec->id-1];
-            if (t == NULL) {
-                t = new Type(header, package, dtohl(typeSpec->entryCount));
-                package->types.editItemAt(typeSpec->id-1) = t;
-            } else if (dtohl(typeSpec->entryCount) != t->entryCount) {
-                ALOGW("ResTable_typeSpec entry count inconsistent: given %d, previously %d",
-                    (int)dtohl(typeSpec->entryCount), (int)t->entryCount);
-                return (mError=BAD_TYPE);
-            }
-            t->typeSpecFlags = (const uint32_t*)(
-                    ((const uint8_t*)typeSpec) + dtohs(typeSpec->header.headerSize));
-            t->typeSpec = typeSpec;
-            
-        } else if (ctype == RES_TABLE_TYPE_TYPE) {
-            const ResTable_type* type = (const ResTable_type*)(chunk);
-            err = validate_chunk(&type->header, sizeof(*type)-sizeof(ResTable_config)+4,
-                                 endPos, "ResTable_type");
-            if (err != NO_ERROR) {
-                return (mError=err);
-            }
-            
-            const size_t typeSize = dtohl(type->header.size);
-            
-            LOAD_TABLE_NOISY(printf("Type off %p: type=0x%x, headerSize=0x%x, size=%p\n",
-                                    (void*)(base-(const uint8_t*)chunk),
-                                    dtohs(type->header.type),
-                                    dtohs(type->header.headerSize),
-                                    (void*)typeSize));
-            if (dtohs(type->header.headerSize)+(sizeof(uint32_t)*dtohl(type->entryCount))
-                > typeSize) {
-                ALOGW("ResTable_type entry index to %p extends beyond chunk end %p.",
-                     (void*)(dtohs(type->header.headerSize)
-                             +(sizeof(uint32_t)*dtohl(type->entryCount))),
-                     (void*)typeSize);
-                return (mError=BAD_TYPE);
-            }
-            if (dtohl(type->entryCount) != 0
-                && dtohl(type->entriesStart) > (typeSize-sizeof(ResTable_entry))) {
-                ALOGW("ResTable_type entriesStart at %p extends beyond chunk end %p.",
-                     (void*)dtohl(type->entriesStart), (void*)typeSize);
-                return (mError=BAD_TYPE);
-            }
-            if (type->id == 0) {
-                ALOGW("ResTable_type has an id of 0.");
-                return (mError=BAD_TYPE);
-            }
-            
-            while (package->types.size() < type->id) {
-                package->types.add(NULL);
-            }
-            Type* t = package->types[type->id-1];
-            if (t == NULL) {
-                t = new Type(header, package, dtohl(type->entryCount));
-                package->types.editItemAt(type->id-1) = t;
-            } else if (dtohl(type->entryCount) != t->entryCount) {
-                ALOGW("ResTable_type entry count inconsistent: given %d, previously %d",
-                    (int)dtohl(type->entryCount), (int)t->entryCount);
-                return (mError=BAD_TYPE);
-            }
-            
-            TABLE_GETENTRY(
-                ResTable_config thisConfig;
-                thisConfig.copyFromDtoH(type->config);
-                ALOGI("Adding config to type %d: %s\n",
-                      type->id, thisConfig.toString().string()));
-            t->configs.add(type);
-        } else {
-            status_t err = validate_chunk(chunk, sizeof(ResChunk_header),
-                                          endPos, "ResTable_package:unknown");
-            if (err != NO_ERROR) {
-                return (mError=err);
-            }
-        }
-        chunk = (const ResChunk_header*)
-            (((const uint8_t*)chunk) + csize);
-    }
-
-    if (group->typeCount == 0) {
-        group->typeCount = package->types.size();
-    }
-    
-    return NO_ERROR;
-}
-
-status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, uint32_t overlayCrc,
-                               void** outData, size_t* outSize) const
-{
-    // see README for details on the format of map
-    if (mPackageGroups.size() == 0) {
-        return UNKNOWN_ERROR;
-    }
-    if (mPackageGroups[0]->packages.size() == 0) {
-        return UNKNOWN_ERROR;
-    }
-
-    Vector<Vector<uint32_t> > map;
-    const PackageGroup* pg = mPackageGroups[0];
-    const Package* pkg = pg->packages[0];
-    size_t typeCount = pkg->types.size();
-    // starting size is header + first item (number of types in map)
-    *outSize = (IDMAP_HEADER_SIZE + 1) * sizeof(uint32_t);
-    const String16 overlayPackage(overlay.mPackageGroups[0]->packages[0]->package->name);
-    const uint32_t pkg_id = pkg->package->id << 24;
-
-    for (size_t typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
-        ssize_t first = -1;
-        ssize_t last = -1;
-        const Type* typeConfigs = pkg->getType(typeIndex);
-        ssize_t mapIndex = map.add();
-        if (mapIndex < 0) {
-            return NO_MEMORY;
-        }
-        Vector<uint32_t>& vector = map.editItemAt(mapIndex);
-        for (size_t entryIndex = 0; entryIndex < typeConfigs->entryCount; ++entryIndex) {
-            uint32_t resID = pkg_id
-                | (0x00ff0000 & ((typeIndex+1)<<16))
-                | (0x0000ffff & (entryIndex));
-            resource_name resName;
-            if (!this->getResourceName(resID, true, &resName)) {
-                ALOGW("idmap: resource 0x%08x has spec but lacks values, skipping\n", resID);
-                // add dummy value, or trimming leading/trailing zeroes later will fail
-                vector.push(0);
-                continue;
-            }
-
-            const String16 overlayType(resName.type, resName.typeLen);
-            const String16 overlayName(resName.name, resName.nameLen);
-            uint32_t overlayResID = overlay.identifierForName(overlayName.string(),
-                                                              overlayName.size(),
-                                                              overlayType.string(),
-                                                              overlayType.size(),
-                                                              overlayPackage.string(),
-                                                              overlayPackage.size());
-            if (overlayResID != 0) {
-                overlayResID = pkg_id | (0x00ffffff & overlayResID);
-                last = Res_GETENTRY(resID);
-                if (first == -1) {
-                    first = Res_GETENTRY(resID);
-                }
-            }
-            vector.push(overlayResID);
-#if 0
-            if (overlayResID != 0) {
-                ALOGD("%s/%s 0x%08x -> 0x%08x\n",
-                     String8(String16(resName.type)).string(),
-                     String8(String16(resName.name)).string(),
-                     resID, overlayResID);
-            }
-#endif
-        }
-
-        if (first != -1) {
-            // shave off trailing entries which lack overlay values
-            const size_t last_past_one = last + 1;
-            if (last_past_one < vector.size()) {
-                vector.removeItemsAt(last_past_one, vector.size() - last_past_one);
-            }
-            // shave off leading entries which lack overlay values
-            vector.removeItemsAt(0, first);
-            // store offset to first overlaid resource ID of this type
-            vector.insertAt((uint32_t)first, 0, 1);
-            // reserve space for number and offset of entries, and the actual entries
-            *outSize += (2 + vector.size()) * sizeof(uint32_t);
-        } else {
-            // no entries of current type defined in overlay package
-            vector.clear();
-            // reserve space for type offset
-            *outSize += 1 * sizeof(uint32_t);
-        }
-    }
-
-    if ((*outData = malloc(*outSize)) == NULL) {
-        return NO_MEMORY;
-    }
-    uint32_t* data = (uint32_t*)*outData;
-    *data++ = htodl(IDMAP_MAGIC);
-    *data++ = htodl(originalCrc);
-    *data++ = htodl(overlayCrc);
-    const size_t mapSize = map.size();
-    *data++ = htodl(mapSize);
-    size_t offset = mapSize;
-    for (size_t i = 0; i < mapSize; ++i) {
-        const Vector<uint32_t>& vector = map.itemAt(i);
-        const size_t N = vector.size();
-        if (N == 0) {
-            *data++ = htodl(0);
-        } else {
-            offset++;
-            *data++ = htodl(offset);
-            offset += N;
-        }
-    }
-    for (size_t i = 0; i < mapSize; ++i) {
-        const Vector<uint32_t>& vector = map.itemAt(i);
-        const size_t N = vector.size();
-        if (N == 0) {
-            continue;
-        }
-        if (N == 1) { // vector expected to hold (offset) + (N > 0 entries)
-            ALOGW("idmap: type %d supposedly has entries, but no entries found\n", i);
-            return UNKNOWN_ERROR;
-        }
-        *data++ = htodl(N - 1); // do not count the offset (which is vector's first element)
-        for (size_t j = 0; j < N; ++j) {
-            const uint32_t& overlayResID = vector.itemAt(j);
-            *data++ = htodl(overlayResID);
-        }
-    }
-
-    return NO_ERROR;
-}
-
-bool ResTable::getIdmapInfo(const void* idmap, size_t sizeBytes,
-                            uint32_t* pOriginalCrc, uint32_t* pOverlayCrc)
-{
-    const uint32_t* map = (const uint32_t*)idmap;
-    if (!assertIdmapHeader(map, sizeBytes)) {
-        return false;
-    }
-    *pOriginalCrc = map[1];
-    *pOverlayCrc = map[2];
-    return true;
-}
-
-
-#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string())
-
-#define CHAR16_ARRAY_EQ(constant, var, len) \
-        ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len))))
-
-static void print_complex(uint32_t complex, bool isFraction)
-{
-    const float MANTISSA_MULT =
-        1.0f / (1<<Res_value::COMPLEX_MANTISSA_SHIFT);
-    const float RADIX_MULTS[] = {
-        1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT,
-        1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT
-    };
-
-    float value = (complex&(Res_value::COMPLEX_MANTISSA_MASK
-                   <<Res_value::COMPLEX_MANTISSA_SHIFT))
-            * RADIX_MULTS[(complex>>Res_value::COMPLEX_RADIX_SHIFT)
-                            & Res_value::COMPLEX_RADIX_MASK];
-    printf("%f", value);
-    
-    if (!isFraction) {
-        switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) {
-            case Res_value::COMPLEX_UNIT_PX: printf("px"); break;
-            case Res_value::COMPLEX_UNIT_DIP: printf("dp"); break;
-            case Res_value::COMPLEX_UNIT_SP: printf("sp"); break;
-            case Res_value::COMPLEX_UNIT_PT: printf("pt"); break;
-            case Res_value::COMPLEX_UNIT_IN: printf("in"); break;
-            case Res_value::COMPLEX_UNIT_MM: printf("mm"); break;
-            default: printf(" (unknown unit)"); break;
-        }
-    } else {
-        switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) {
-            case Res_value::COMPLEX_UNIT_FRACTION: printf("%%"); break;
-            case Res_value::COMPLEX_UNIT_FRACTION_PARENT: printf("%%p"); break;
-            default: printf(" (unknown unit)"); break;
-        }
-    }
-}
-
-// Normalize a string for output
-String8 ResTable::normalizeForOutput( const char *input )
-{
-    String8 ret;
-    char buff[2];
-    buff[1] = '\0';
-
-    while (*input != '\0') {
-        switch (*input) {
-            // All interesting characters are in the ASCII zone, so we are making our own lives
-            // easier by scanning the string one byte at a time.
-        case '\\':
-            ret += "\\\\";
-            break;
-        case '\n':
-            ret += "\\n";
-            break;
-        case '"':
-            ret += "\\\"";
-            break;
-        default:
-            buff[0] = *input;
-            ret += buff;
-            break;
-        }
-
-        input++;
-    }
-
-    return ret;
-}
-
-void ResTable::print_value(const Package* pkg, const Res_value& value) const
-{
-    if (value.dataType == Res_value::TYPE_NULL) {
-        printf("(null)\n");
-    } else if (value.dataType == Res_value::TYPE_REFERENCE) {
-        printf("(reference) 0x%08x\n", value.data);
-    } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) {
-        printf("(attribute) 0x%08x\n", value.data);
-    } else if (value.dataType == Res_value::TYPE_STRING) {
-        size_t len;
-        const char* str8 = pkg->header->values.string8At(
-                value.data, &len);
-        if (str8 != NULL) {
-            printf("(string8) \"%s\"\n", normalizeForOutput(str8).string());
-        } else {
-            const char16_t* str16 = pkg->header->values.stringAt(
-                    value.data, &len);
-            if (str16 != NULL) {
-                printf("(string16) \"%s\"\n",
-                    normalizeForOutput(String8(str16, len).string()).string());
-            } else {
-                printf("(string) null\n");
-            }
-        } 
-    } else if (value.dataType == Res_value::TYPE_FLOAT) {
-        printf("(float) %g\n", *(const float*)&value.data);
-    } else if (value.dataType == Res_value::TYPE_DIMENSION) {
-        printf("(dimension) ");
-        print_complex(value.data, false);
-        printf("\n");
-    } else if (value.dataType == Res_value::TYPE_FRACTION) {
-        printf("(fraction) ");
-        print_complex(value.data, true);
-        printf("\n");
-    } else if (value.dataType >= Res_value::TYPE_FIRST_COLOR_INT
-            || value.dataType <= Res_value::TYPE_LAST_COLOR_INT) {
-        printf("(color) #%08x\n", value.data);
-    } else if (value.dataType == Res_value::TYPE_INT_BOOLEAN) {
-        printf("(boolean) %s\n", value.data ? "true" : "false");
-    } else if (value.dataType >= Res_value::TYPE_FIRST_INT
-            || value.dataType <= Res_value::TYPE_LAST_INT) {
-        printf("(int) 0x%08x or %d\n", value.data, value.data);
-    } else {
-        printf("(unknown type) t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)\n",
-               (int)value.dataType, (int)value.data,
-               (int)value.size, (int)value.res0);
-    }
-}
-
-void ResTable::print(bool inclValues) const
-{
-    if (mError != 0) {
-        printf("mError=0x%x (%s)\n", mError, strerror(mError));
-    }
-#if 0
-    printf("mParams=%c%c-%c%c,\n",
-            mParams.language[0], mParams.language[1],
-            mParams.country[0], mParams.country[1]);
-#endif
-    size_t pgCount = mPackageGroups.size();
-    printf("Package Groups (%d)\n", (int)pgCount);
-    for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) {
-        const PackageGroup* pg = mPackageGroups[pgIndex];
-        printf("Package Group %d id=%d packageCount=%d name=%s\n",
-                (int)pgIndex, pg->id, (int)pg->packages.size(),
-                String8(pg->name).string());
-        
-        size_t pkgCount = pg->packages.size();
-        for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) {
-            const Package* pkg = pg->packages[pkgIndex];
-            size_t typeCount = pkg->types.size();
-            printf("  Package %d id=%d name=%s typeCount=%d\n", (int)pkgIndex,
-                    pkg->package->id, String8(String16(pkg->package->name)).string(),
-                    (int)typeCount);
-            for (size_t typeIndex=0; typeIndex<typeCount; typeIndex++) {
-                const Type* typeConfigs = pkg->getType(typeIndex);
-                if (typeConfigs == NULL) {
-                    printf("    type %d NULL\n", (int)typeIndex);
-                    continue;
-                }
-                const size_t NTC = typeConfigs->configs.size();
-                printf("    type %d configCount=%d entryCount=%d\n",
-                       (int)typeIndex, (int)NTC, (int)typeConfigs->entryCount);
-                if (typeConfigs->typeSpecFlags != NULL) {
-                    for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount; entryIndex++) {
-                        uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
-                                    | (0x00ff0000 & ((typeIndex+1)<<16))
-                                    | (0x0000ffff & (entryIndex));
-                        resource_name resName;
-                        if (this->getResourceName(resID, true, &resName)) {
-                            String8 type8;
-                            String8 name8;
-                            if (resName.type8 != NULL) {
-                                type8 = String8(resName.type8, resName.typeLen);
-                            } else {
-                                type8 = String8(resName.type, resName.typeLen);
-                            }
-                            if (resName.name8 != NULL) {
-                                name8 = String8(resName.name8, resName.nameLen);
-                            } else {
-                                name8 = String8(resName.name, resName.nameLen);
-                            }
-                            printf("      spec resource 0x%08x %s:%s/%s: flags=0x%08x\n",
-                                resID,
-                                CHAR16_TO_CSTR(resName.package, resName.packageLen),
-                                type8.string(), name8.string(),
-                                dtohl(typeConfigs->typeSpecFlags[entryIndex]));
-                        } else {
-                            printf("      INVALID TYPE CONFIG FOR RESOURCE 0x%08x\n", resID);
-                        }
-                    }
-                }
-                for (size_t configIndex=0; configIndex<NTC; configIndex++) {
-                    const ResTable_type* type = typeConfigs->configs[configIndex];
-                    if ((((uint64_t)type)&0x3) != 0) {
-                        printf("      NON-INTEGER ResTable_type ADDRESS: %p\n", type);
-                        continue;
-                    }
-                    String8 configStr = type->config.toString();
-                    printf("      config %s:\n", configStr.size() > 0
-                            ? configStr.string() : "(default)");
-                    size_t entryCount = dtohl(type->entryCount);
-                    uint32_t entriesStart = dtohl(type->entriesStart);
-                    if ((entriesStart&0x3) != 0) {
-                        printf("      NON-INTEGER ResTable_type entriesStart OFFSET: %p\n", (void*)entriesStart);
-                        continue;
-                    }
-                    uint32_t typeSize = dtohl(type->header.size);
-                    if ((typeSize&0x3) != 0) {
-                        printf("      NON-INTEGER ResTable_type header.size: %p\n", (void*)typeSize);
-                        continue;
-                    }
-                    for (size_t entryIndex=0; entryIndex<entryCount; entryIndex++) {
-                        
-                        const uint8_t* const end = ((const uint8_t*)type)
-                            + dtohl(type->header.size);
-                        const uint32_t* const eindex = (const uint32_t*)
-                            (((const uint8_t*)type) + dtohs(type->header.headerSize));
-                        
-                        uint32_t thisOffset = dtohl(eindex[entryIndex]);
-                        if (thisOffset == ResTable_type::NO_ENTRY) {
-                            continue;
-                        }
-                        
-                        uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
-                                    | (0x00ff0000 & ((typeIndex+1)<<16))
-                                    | (0x0000ffff & (entryIndex));
-                        resource_name resName;
-                        if (this->getResourceName(resID, true, &resName)) {
-                            String8 type8;
-                            String8 name8;
-                            if (resName.type8 != NULL) {
-                                type8 = String8(resName.type8, resName.typeLen);
-                            } else {
-                                type8 = String8(resName.type, resName.typeLen);
-                            }
-                            if (resName.name8 != NULL) {
-                                name8 = String8(resName.name8, resName.nameLen);
-                            } else {
-                                name8 = String8(resName.name, resName.nameLen);
-                            }
-                            printf("        resource 0x%08x %s:%s/%s: ", resID,
-                                    CHAR16_TO_CSTR(resName.package, resName.packageLen),
-                                    type8.string(), name8.string());
-                        } else {
-                            printf("        INVALID RESOURCE 0x%08x: ", resID);
-                        }
-                        if ((thisOffset&0x3) != 0) {
-                            printf("NON-INTEGER OFFSET: %p\n", (void*)thisOffset);
-                            continue;
-                        }
-                        if ((thisOffset+sizeof(ResTable_entry)) > typeSize) {
-                            printf("OFFSET OUT OF BOUNDS: %p+%p (size is %p)\n",
-                                   (void*)entriesStart, (void*)thisOffset,
-                                   (void*)typeSize);
-                            continue;
-                        }
-                        
-                        const ResTable_entry* ent = (const ResTable_entry*)
-                            (((const uint8_t*)type) + entriesStart + thisOffset);
-                        if (((entriesStart + thisOffset)&0x3) != 0) {
-                            printf("NON-INTEGER ResTable_entry OFFSET: %p\n",
-                                 (void*)(entriesStart + thisOffset));
-                            continue;
-                        }
-                        
-                        uint16_t esize = dtohs(ent->size);
-                        if ((esize&0x3) != 0) {
-                            printf("NON-INTEGER ResTable_entry SIZE: %p\n", (void*)esize);
-                            continue;
-                        }
-                        if ((thisOffset+esize) > typeSize) {
-                            printf("ResTable_entry OUT OF BOUNDS: %p+%p+%p (size is %p)\n",
-                                   (void*)entriesStart, (void*)thisOffset,
-                                   (void*)esize, (void*)typeSize);
-                            continue;
-                        }
-                            
-                        const Res_value* valuePtr = NULL;
-                        const ResTable_map_entry* bagPtr = NULL;
-                        Res_value value;
-                        if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) {
-                            printf("<bag>");
-                            bagPtr = (const ResTable_map_entry*)ent;
-                        } else {
-                            valuePtr = (const Res_value*)
-                                (((const uint8_t*)ent) + esize);
-                            value.copyFrom_dtoh(*valuePtr);
-                            printf("t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)",
-                                   (int)value.dataType, (int)value.data,
-                                   (int)value.size, (int)value.res0);
-                        }
-                        
-                        if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) {
-                            printf(" (PUBLIC)");
-                        }
-                        printf("\n");
-                        
-                        if (inclValues) {
-                            if (valuePtr != NULL) {
-                                printf("          ");
-                                print_value(pkg, value);
-                            } else if (bagPtr != NULL) {
-                                const int N = dtohl(bagPtr->count);
-                                const uint8_t* baseMapPtr = (const uint8_t*)ent;
-                                size_t mapOffset = esize;
-                                const ResTable_map* mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);
-                                printf("          Parent=0x%08x, Count=%d\n",
-                                    dtohl(bagPtr->parent.ident), N);
-                                for (int i=0; i<N && mapOffset < (typeSize-sizeof(ResTable_map)); i++) {
-                                    printf("          #%i (Key=0x%08x): ",
-                                        i, dtohl(mapPtr->name.ident));
-                                    value.copyFrom_dtoh(mapPtr->value);
-                                    print_value(pkg, value);
-                                    const size_t size = dtohs(mapPtr->value.size);
-                                    mapOffset += size + sizeof(*mapPtr)-sizeof(mapPtr->value);
-                                    mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-}   // namespace android
diff --git a/libs/androidfw/StreamingZipInflater.cpp b/libs/androidfw/StreamingZipInflater.cpp
deleted file mode 100644
index 1dfec23..0000000
--- a/libs/androidfw/StreamingZipInflater.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "szipinf"
-#include <utils/Log.h>
-
-#include <androidfw/StreamingZipInflater.h>
-#include <utils/FileMap.h>
-#include <string.h>
-#include <stddef.h>
-#include <assert.h>
-#include <unistd.h>
-#include <errno.h>
-
-/*
- * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
- * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
- * not already defined, then define it here.
- */
-#ifndef TEMP_FAILURE_RETRY
-/* Used to retry syscalls that can return EINTR. */
-#define TEMP_FAILURE_RETRY(exp) ({         \
-    typeof (exp) _rc;                      \
-    do {                                   \
-        _rc = (exp);                       \
-    } while (_rc == -1 && errno == EINTR); \
-    _rc; })
-#endif
-
-static inline size_t min_of(size_t a, size_t b) { return (a < b) ? a : b; }
-
-using namespace android;
-
-/*
- * Streaming access to compressed asset data in an open fd
- */
-StreamingZipInflater::StreamingZipInflater(int fd, off64_t compDataStart,
-        size_t uncompSize, size_t compSize) {
-    mFd = fd;
-    mDataMap = NULL;
-    mInFileStart = compDataStart;
-    mOutTotalSize = uncompSize;
-    mInTotalSize = compSize;
-
-    mInBufSize = StreamingZipInflater::INPUT_CHUNK_SIZE;
-    mInBuf = new uint8_t[mInBufSize];
-
-    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;
-    mOutBuf = new uint8_t[mOutBufSize];
-
-    initInflateState();
-}
-
-/*
- * Streaming access to compressed data held in an mmapped region of memory
- */
-StreamingZipInflater::StreamingZipInflater(FileMap* dataMap, size_t uncompSize) {
-    mFd = -1;
-    mDataMap = dataMap;
-    mOutTotalSize = uncompSize;
-    mInTotalSize = dataMap->getDataLength();
-
-    mInBuf = (uint8_t*) dataMap->getDataPtr();
-    mInBufSize = mInTotalSize;
-
-    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;
-    mOutBuf = new uint8_t[mOutBufSize];
-
-    initInflateState();
-}
-
-StreamingZipInflater::~StreamingZipInflater() {
-    // tear down the in-flight zip state just in case
-    ::inflateEnd(&mInflateState);
-
-    if (mDataMap == NULL) {
-        delete [] mInBuf;
-    }
-    delete [] mOutBuf;
-}
-
-void StreamingZipInflater::initInflateState() {
-    ALOGV("Initializing inflate state");
-
-    memset(&mInflateState, 0, sizeof(mInflateState));
-    mInflateState.zalloc = Z_NULL;
-    mInflateState.zfree = Z_NULL;
-    mInflateState.opaque = Z_NULL;
-    mInflateState.next_in = (Bytef*)mInBuf;
-    mInflateState.next_out = (Bytef*) mOutBuf;
-    mInflateState.avail_out = mOutBufSize;
-    mInflateState.data_type = Z_UNKNOWN;
-
-    mOutLastDecoded = mOutDeliverable = mOutCurPosition = 0;
-    mInNextChunkOffset = 0;
-    mStreamNeedsInit = true;
-
-    if (mDataMap == NULL) {
-        ::lseek(mFd, mInFileStart, SEEK_SET);
-        mInflateState.avail_in = 0; // set when a chunk is read in
-    } else {
-        mInflateState.avail_in = mInBufSize;
-    }
-}
-
-/*
- * Basic approach:
- *
- * 1. If we have undelivered uncompressed data, send it.  At this point
- *    either we've satisfied the request, or we've exhausted the available
- *    output data in mOutBuf.
- *
- * 2. While we haven't sent enough data to satisfy the request:
- *    0. if the request is for more data than exists, bail.
- *    a. if there is no input data to decode, read some into the input buffer
- *       and readjust the z_stream input pointers
- *    b. point the output to the start of the output buffer and decode what we can
- *    c. deliver whatever output data we can
- */
-ssize_t StreamingZipInflater::read(void* outBuf, size_t count) {
-    uint8_t* dest = (uint8_t*) outBuf;
-    size_t bytesRead = 0;
-    size_t toRead = min_of(count, size_t(mOutTotalSize - mOutCurPosition));
-    while (toRead > 0) {
-        // First, write from whatever we already have decoded and ready to go
-        size_t deliverable = min_of(toRead, mOutLastDecoded - mOutDeliverable);
-        if (deliverable > 0) {
-            if (outBuf != NULL) memcpy(dest, mOutBuf + mOutDeliverable, deliverable);
-            mOutDeliverable += deliverable;
-            mOutCurPosition += deliverable;
-            dest += deliverable;
-            bytesRead += deliverable;
-            toRead -= deliverable;
-        }
-
-        // need more data?  time to decode some.
-        if (toRead > 0) {
-            // if we don't have any data to decode, read some in.  If we're working
-            // from mmapped data this won't happen, because the clipping to total size
-            // will prevent reading off the end of the mapped input chunk.
-            if ((mInflateState.avail_in == 0) && (mDataMap == NULL)) {
-                int err = readNextChunk();
-                if (err < 0) {
-                    ALOGE("Unable to access asset data: %d", err);
-                    if (!mStreamNeedsInit) {
-                        ::inflateEnd(&mInflateState);
-                        initInflateState();
-                    }
-                    return -1;
-                }
-            }
-            // we know we've drained whatever is in the out buffer now, so just
-            // start from scratch there, reading all the input we have at present.
-            mInflateState.next_out = (Bytef*) mOutBuf;
-            mInflateState.avail_out = mOutBufSize;
-
-            /*
-            ALOGV("Inflating to outbuf: avail_in=%u avail_out=%u next_in=%p next_out=%p",
-                    mInflateState.avail_in, mInflateState.avail_out,
-                    mInflateState.next_in, mInflateState.next_out);
-            */
-            int result = Z_OK;
-            if (mStreamNeedsInit) {
-                ALOGV("Initializing zlib to inflate");
-                result = inflateInit2(&mInflateState, -MAX_WBITS);
-                mStreamNeedsInit = false;
-            }
-            if (result == Z_OK) result = ::inflate(&mInflateState, Z_SYNC_FLUSH);
-            if (result < 0) {
-                // Whoops, inflation failed
-                ALOGE("Error inflating asset: %d", result);
-                ::inflateEnd(&mInflateState);
-                initInflateState();
-                return -1;
-            } else {
-                if (result == Z_STREAM_END) {
-                    // we know we have to have reached the target size here and will
-                    // not try to read any further, so just wind things up.
-                    ::inflateEnd(&mInflateState);
-                }
-
-                // Note how much data we got, and off we go
-                mOutDeliverable = 0;
-                mOutLastDecoded = mOutBufSize - mInflateState.avail_out;
-            }
-        }
-    }
-    return bytesRead;
-}
-
-int StreamingZipInflater::readNextChunk() {
-    assert(mDataMap == NULL);
-
-    if (mInNextChunkOffset < mInTotalSize) {
-        size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset);
-        if (toRead > 0) {
-            ssize_t didRead = TEMP_FAILURE_RETRY(::read(mFd, mInBuf, toRead));
-            //ALOGV("Reading input chunk, size %08x didread %08x", toRead, didRead);
-            if (didRead < 0) {
-                ALOGE("Error reading asset data: %s", strerror(errno));
-                return didRead;
-            } else {
-                mInNextChunkOffset += didRead;
-                mInflateState.next_in = (Bytef*) mInBuf;
-                mInflateState.avail_in = didRead;
-            }
-        }
-    }
-    return 0;
-}
-
-// seeking backwards requires uncompressing fom the beginning, so is very
-// expensive.  seeking forwards only requires uncompressing from the current
-// position to the destination.
-off64_t StreamingZipInflater::seekAbsolute(off64_t absoluteInputPosition) {
-    if (absoluteInputPosition < mOutCurPosition) {
-        // rewind and reprocess the data from the beginning
-        if (!mStreamNeedsInit) {
-            ::inflateEnd(&mInflateState);
-        }
-        initInflateState();
-        read(NULL, absoluteInputPosition);
-    } else if (absoluteInputPosition > mOutCurPosition) {
-        read(NULL, absoluteInputPosition - mOutCurPosition);
-    }
-    // else if the target position *is* our current position, do nothing
-    return absoluteInputPosition;
-}
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
deleted file mode 100644
index ec5f95c..0000000
--- a/libs/androidfw/ZipFileRO.cpp
+++ /dev/null
@@ -1,995 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Read-only access to Zip archives, with minimal heap allocation.
-//
-#define LOG_TAG "zipro"
-//#define LOG_NDEBUG 0
-#include <androidfw/ZipFileRO.h>
-#include <utils/Log.h>
-#include <utils/Compat.h>
-#include <utils/misc.h>
-#include <utils/threads.h>
-
-#include <zlib.h>
-
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <assert.h>
-#include <unistd.h>
-
-/*
- * We must open binary files using open(path, ... | O_BINARY) under Windows.
- * Otherwise strange read errors will happen.
- */
-#ifndef O_BINARY
-#  define O_BINARY  0
-#endif
-
-using namespace android;
-
-/*
- * Zip file constants.
- */
-#define kEOCDSignature       0x06054b50
-#define kEOCDLen             22
-#define kEOCDDiskNumber      4               // number of the current disk
-#define kEOCDDiskNumberForCD 6               // disk number with the Central Directory
-#define kEOCDNumEntries      8               // offset to #of entries in file
-#define kEOCDTotalNumEntries 10              // offset to total #of entries in spanned archives
-#define kEOCDSize            12              // size of the central directory
-#define kEOCDFileOffset      16              // offset to central directory
-#define kEOCDCommentSize     20              // offset to the length of the file comment
-
-#define kMaxCommentLen       65535           // longest possible in ushort
-#define kMaxEOCDSearch       (kMaxCommentLen + kEOCDLen)
-
-#define kLFHSignature        0x04034b50
-#define kLFHLen              30              // excluding variable-len fields
-#define kLFHGPBFlags          6              // offset to GPB flags
-#define kLFHNameLen          26              // offset to filename length
-#define kLFHExtraLen         28              // offset to extra length
-
-#define kCDESignature        0x02014b50
-#define kCDELen              46              // excluding variable-len fields
-#define kCDEGPBFlags          8              // offset to GPB flags
-#define kCDEMethod           10              // offset to compression method
-#define kCDEModWhen          12              // offset to modification timestamp
-#define kCDECRC              16              // offset to entry CRC
-#define kCDECompLen          20              // offset to compressed length
-#define kCDEUncompLen        24              // offset to uncompressed length
-#define kCDENameLen          28              // offset to filename length
-#define kCDEExtraLen         30              // offset to extra length
-#define kCDECommentLen       32              // offset to comment length
-#define kCDELocalOffset      42              // offset to local hdr
-
-/* General Purpose Bit Flag */
-#define kGPFEncryptedFlag    (1 << 0)
-#define kGPFUnsupportedMask  (kGPFEncryptedFlag)
-
-/*
- * The values we return for ZipEntryRO use 0 as an invalid value, so we
- * want to adjust the hash table index by a fixed amount.  Using a large
- * value helps insure that people don't mix & match arguments, e.g. to
- * findEntryByIndex().
- */
-#define kZipEntryAdj        10000
-
-ZipFileRO::~ZipFileRO() {
-    free(mHashTable);
-    if (mDirectoryMap)
-        mDirectoryMap->release();
-    if (mFd >= 0)
-        TEMP_FAILURE_RETRY(close(mFd));
-    if (mFileName)
-        free(mFileName);
-}
-
-/*
- * Convert a ZipEntryRO to a hash table index, verifying that it's in a
- * valid range.
- */
-int ZipFileRO::entryToIndex(const ZipEntryRO entry) const
-{
-    long ent = ((intptr_t) entry) - kZipEntryAdj;
-    if (ent < 0 || ent >= mHashTableSize || mHashTable[ent].name == NULL) {
-        ALOGW("Invalid ZipEntryRO %p (%ld)\n", entry, ent);
-        return -1;
-    }
-    return ent;
-}
-
-
-/*
- * Open the specified file read-only.  We memory-map the entire thing and
- * close the file before returning.
- */
-status_t ZipFileRO::open(const char* zipFileName)
-{
-    int fd = -1;
-
-    assert(mDirectoryMap == NULL);
-
-    /*
-     * Open and map the specified file.
-     */
-    fd = TEMP_FAILURE_RETRY(::open(zipFileName, O_RDONLY | O_BINARY));
-    if (fd < 0) {
-        ALOGW("Unable to open zip '%s': %s\n", zipFileName, strerror(errno));
-        return NAME_NOT_FOUND;
-    }
-
-    mFileLength = lseek64(fd, 0, SEEK_END);
-    if (mFileLength < kEOCDLen) {
-        TEMP_FAILURE_RETRY(close(fd));
-        return UNKNOWN_ERROR;
-    }
-
-    if (mFileName != NULL) {
-        free(mFileName);
-    }
-    mFileName = strdup(zipFileName);
-
-    mFd = fd;
-
-    /*
-     * Find the Central Directory and store its size and number of entries.
-     */
-    if (!mapCentralDirectory()) {
-        goto bail;
-    }
-
-    /*
-     * Verify Central Directory and create data structures for fast access.
-     */
-    if (!parseZipArchive()) {
-        goto bail;
-    }
-
-    return OK;
-
-bail:
-    free(mFileName);
-    mFileName = NULL;
-    TEMP_FAILURE_RETRY(close(fd));
-    return UNKNOWN_ERROR;
-}
-
-/*
- * Parse the Zip archive, verifying its contents and initializing internal
- * data structures.
- */
-bool ZipFileRO::mapCentralDirectory(void)
-{
-    ssize_t readAmount = kMaxEOCDSearch;
-    if (readAmount > (ssize_t) mFileLength)
-        readAmount = mFileLength;
-
-    if (readAmount < kEOCDSize) {
-        ALOGW("File too short to be a zip file");
-        return false;
-    }
-
-    unsigned char* scanBuf = (unsigned char*) malloc(readAmount);
-    if (scanBuf == NULL) {
-        ALOGW("couldn't allocate scanBuf: %s", strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-    /*
-     * Make sure this is a Zip archive.
-     */
-    if (lseek64(mFd, 0, SEEK_SET) != 0) {
-        ALOGW("seek to start failed: %s", strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-    ssize_t actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, sizeof(int32_t)));
-    if (actual != (ssize_t) sizeof(int32_t)) {
-        ALOGI("couldn't read first signature from zip archive: %s", strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-    unsigned int header = get4LE(scanBuf);
-    if (header != kLFHSignature) {
-        ALOGV("Not a Zip archive (found 0x%08x)\n", header);
-        free(scanBuf);
-        return false;
-    }
-
-    /*
-     * Perform the traditional EOCD snipe hunt.
-     *
-     * We're searching for the End of Central Directory magic number,
-     * which appears at the start of the EOCD block.  It's followed by
-     * 18 bytes of EOCD stuff and up to 64KB of archive comment.  We
-     * need to read the last part of the file into a buffer, dig through
-     * it to find the magic number, parse some values out, and use those
-     * to determine the extent of the CD.
-     *
-     * We start by pulling in the last part of the file.
-     */
-    off64_t searchStart = mFileLength - readAmount;
-
-    if (lseek64(mFd, searchStart, SEEK_SET) != searchStart) {
-        ALOGW("seek %ld failed: %s\n",  (long) searchStart, strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-    actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, readAmount));
-    if (actual != (ssize_t) readAmount) {
-        ALOGW("Zip: read " ZD ", expected " ZD ". Failed: %s\n",
-            (ZD_TYPE) actual, (ZD_TYPE) readAmount, strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-    /*
-     * Scan backward for the EOCD magic.  In an archive without a trailing
-     * comment, we'll find it on the first try.  (We may want to consider
-     * doing an initial minimal read; if we don't find it, retry with a
-     * second read as above.)
-     */
-    int i;
-    for (i = readAmount - kEOCDLen; i >= 0; i--) {
-        if (scanBuf[i] == 0x50 && get4LE(&scanBuf[i]) == kEOCDSignature) {
-            ALOGV("+++ Found EOCD at buf+%d\n", i);
-            break;
-        }
-    }
-    if (i < 0) {
-        ALOGD("Zip: EOCD not found, %s is not zip\n", mFileName);
-        free(scanBuf);
-        return false;
-    }
-
-    off64_t eocdOffset = searchStart + i;
-    const unsigned char* eocdPtr = scanBuf + i;
-
-    assert(eocdOffset < mFileLength);
-
-    /*
-     * Grab the CD offset and size, and the number of entries in the
-     * archive. After that, we can release our EOCD hunt buffer.
-     */
-    unsigned int diskNumber = get2LE(eocdPtr + kEOCDDiskNumber);
-    unsigned int diskWithCentralDir = get2LE(eocdPtr + kEOCDDiskNumberForCD);
-    unsigned int numEntries = get2LE(eocdPtr + kEOCDNumEntries);
-    unsigned int totalNumEntries = get2LE(eocdPtr + kEOCDTotalNumEntries);
-    unsigned int centralDirSize = get4LE(eocdPtr + kEOCDSize);
-    unsigned int centralDirOffset = get4LE(eocdPtr + kEOCDFileOffset);
-    unsigned int commentSize = get2LE(eocdPtr + kEOCDCommentSize);
-    free(scanBuf);
-
-    // Verify that they look reasonable.
-    if ((long long) centralDirOffset + (long long) centralDirSize > (long long) eocdOffset) {
-        ALOGW("bad offsets (dir %ld, size %u, eocd %ld)\n",
-            (long) centralDirOffset, centralDirSize, (long) eocdOffset);
-        return false;
-    }
-    if (numEntries == 0) {
-        ALOGW("empty archive?\n");
-        return false;
-    } else if (numEntries != totalNumEntries || diskNumber != 0 || diskWithCentralDir != 0) {
-        ALOGW("spanned archives not supported");
-        return false;
-    }
-
-    // Check to see if comment is a sane size
-    if ((commentSize > (mFileLength - kEOCDLen))
-            || (eocdOffset > (mFileLength - kEOCDLen) - commentSize)) {
-        ALOGW("comment size runs off end of file");
-        return false;
-    }
-
-    ALOGV("+++ numEntries=%d dirSize=%d dirOffset=%d\n",
-        numEntries, centralDirSize, centralDirOffset);
-
-    mDirectoryMap = new FileMap();
-    if (mDirectoryMap == NULL) {
-        ALOGW("Unable to create directory map: %s", strerror(errno));
-        return false;
-    }
-
-    if (!mDirectoryMap->create(mFileName, mFd, centralDirOffset, centralDirSize, true)) {
-        ALOGW("Unable to map '%s' (" ZD " to " ZD "): %s\n", mFileName,
-                (ZD_TYPE) centralDirOffset, (ZD_TYPE) (centralDirOffset + centralDirSize), strerror(errno));
-        return false;
-    }
-
-    mNumEntries = numEntries;
-    mDirectoryOffset = centralDirOffset;
-
-    return true;
-}
-
-
-/*
- * Round up to the next highest power of 2.
- *
- * Found on http://graphics.stanford.edu/~seander/bithacks.html.
- */
-static unsigned int roundUpPower2(unsigned int val)
-{
-    val--;
-    val |= val >> 1;
-    val |= val >> 2;
-    val |= val >> 4;
-    val |= val >> 8;
-    val |= val >> 16;
-    val++;
-
-    return val;
-}
-
-bool ZipFileRO::parseZipArchive(void)
-{
-    bool result = false;
-    const unsigned char* cdPtr = (const unsigned char*) mDirectoryMap->getDataPtr();
-    size_t cdLength = mDirectoryMap->getDataLength();
-    int numEntries = mNumEntries;
-
-    /*
-     * Create hash table.  We have a minimum 75% load factor, possibly as
-     * low as 50% after we round off to a power of 2.
-     */
-    mHashTableSize = roundUpPower2(1 + (numEntries * 4) / 3);
-    mHashTable = (HashEntry*) calloc(mHashTableSize, sizeof(HashEntry));
-
-    /*
-     * Walk through the central directory, adding entries to the hash
-     * table.
-     */
-    const unsigned char* ptr = cdPtr;
-    for (int i = 0; i < numEntries; i++) {
-        if (get4LE(ptr) != kCDESignature) {
-            ALOGW("Missed a central dir sig (at %d)\n", i);
-            goto bail;
-        }
-        if (ptr + kCDELen > cdPtr + cdLength) {
-            ALOGW("Ran off the end (at %d)\n", i);
-            goto bail;
-        }
-
-        long localHdrOffset = (long) get4LE(ptr + kCDELocalOffset);
-        if (localHdrOffset >= mDirectoryOffset) {
-            ALOGW("bad LFH offset %ld at entry %d\n", localHdrOffset, i);
-            goto bail;
-        }
-
-        unsigned int gpbf = get2LE(ptr + kCDEGPBFlags);
-        if ((gpbf & kGPFUnsupportedMask) != 0) {
-            ALOGW("Invalid General Purpose Bit Flag: %d", gpbf);
-            goto bail;
-        }
-
-        unsigned int nameLen = get2LE(ptr + kCDENameLen);
-        unsigned int extraLen = get2LE(ptr + kCDEExtraLen);
-        unsigned int commentLen = get2LE(ptr + kCDECommentLen);
-
-        const char *name = (const char *) ptr + kCDELen;
-
-        /* Check name for NULL characters */
-        if (memchr(name, 0, nameLen) != NULL) {
-            ALOGW("Filename contains NUL byte");
-            goto bail;
-        }
-
-        /* add the CDE filename to the hash table */
-        unsigned int hash = computeHash(name, nameLen);
-        addToHash(name, nameLen, hash);
-
-        /* We don't care about the comment or extra data. */
-        ptr += kCDELen + nameLen + extraLen + commentLen;
-        if ((size_t)(ptr - cdPtr) > cdLength) {
-            ALOGW("bad CD advance (%d vs " ZD ") at entry %d\n",
-                (int) (ptr - cdPtr), (ZD_TYPE) cdLength, i);
-            goto bail;
-        }
-    }
-    ALOGV("+++ zip good scan %d entries\n", numEntries);
-    result = true;
-
-bail:
-    return result;
-}
-
-/*
- * Simple string hash function for non-null-terminated strings.
- */
-/*static*/ unsigned int ZipFileRO::computeHash(const char* str, int len)
-{
-    unsigned int hash = 0;
-
-    while (len--)
-        hash = hash * 31 + *str++;
-
-    return hash;
-}
-
-/*
- * Add a new entry to the hash table.
- */
-void ZipFileRO::addToHash(const char* str, int strLen, unsigned int hash)
-{
-    int ent = hash & (mHashTableSize-1);
-
-    /*
-     * We over-allocate the table, so we're guaranteed to find an empty slot.
-     */
-    while (mHashTable[ent].name != NULL)
-        ent = (ent + 1) & (mHashTableSize-1);
-
-    mHashTable[ent].name = str;
-    mHashTable[ent].nameLen = strLen;
-}
-
-/*
- * Find a matching entry.
- *
- * Returns NULL if not found.
- */
-ZipEntryRO ZipFileRO::findEntryByName(const char* fileName) const
-{
-    /*
-     * If the ZipFileRO instance is not initialized, the entry number will
-     * end up being garbage since mHashTableSize is -1.
-     */
-    if (mHashTableSize <= 0) {
-        return NULL;
-    }
-
-    int nameLen = strlen(fileName);
-    unsigned int hash = computeHash(fileName, nameLen);
-    int ent = hash & (mHashTableSize-1);
-
-    while (mHashTable[ent].name != NULL) {
-        if (mHashTable[ent].nameLen == nameLen &&
-            memcmp(mHashTable[ent].name, fileName, nameLen) == 0)
-        {
-            /* match */
-            return (ZipEntryRO)(long)(ent + kZipEntryAdj);
-        }
-
-        ent = (ent + 1) & (mHashTableSize-1);
-    }
-
-    return NULL;
-}
-
-/*
- * Find the Nth entry.
- *
- * This currently involves walking through the sparse hash table, counting
- * non-empty entries.  If we need to speed this up we can either allocate
- * a parallel lookup table or (perhaps better) provide an iterator interface.
- */
-ZipEntryRO ZipFileRO::findEntryByIndex(int idx) const
-{
-    if (idx < 0 || idx >= mNumEntries) {
-        ALOGW("Invalid index %d\n", idx);
-        return NULL;
-    }
-
-    for (int ent = 0; ent < mHashTableSize; ent++) {
-        if (mHashTable[ent].name != NULL) {
-            if (idx-- == 0)
-                return (ZipEntryRO) (intptr_t)(ent + kZipEntryAdj);
-        }
-    }
-
-    return NULL;
-}
-
-/*
- * Get the useful fields from the zip entry.
- *
- * Returns "false" if the offsets to the fields or the contents of the fields
- * appear to be bogus.
- */
-bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
-    size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const
-{
-    bool ret = false;
-
-    const int ent = entryToIndex(entry);
-    if (ent < 0) {
-        ALOGW("cannot find entry");
-        return false;
-    }
-
-    HashEntry hashEntry = mHashTable[ent];
-
-    /*
-     * Recover the start of the central directory entry from the filename
-     * pointer.  The filename is the first entry past the fixed-size data,
-     * so we can just subtract back from that.
-     */
-    const unsigned char* ptr = (const unsigned char*) hashEntry.name;
-    off64_t cdOffset = mDirectoryOffset;
-
-    ptr -= kCDELen;
-
-    int method = get2LE(ptr + kCDEMethod);
-    if (pMethod != NULL)
-        *pMethod = method;
-
-    if (pModWhen != NULL)
-        *pModWhen = get4LE(ptr + kCDEModWhen);
-    if (pCrc32 != NULL)
-        *pCrc32 = get4LE(ptr + kCDECRC);
-
-    size_t compLen = get4LE(ptr + kCDECompLen);
-    if (pCompLen != NULL)
-        *pCompLen = compLen;
-    size_t uncompLen = get4LE(ptr + kCDEUncompLen);
-    if (pUncompLen != NULL)
-        *pUncompLen = uncompLen;
-
-    /*
-     * If requested, determine the offset of the start of the data.  All we
-     * have is the offset to the Local File Header, which is variable size,
-     * so we have to read the contents of the struct to figure out where
-     * the actual data starts.
-     *
-     * We also need to make sure that the lengths are not so large that
-     * somebody trying to map the compressed or uncompressed data runs
-     * off the end of the mapped region.
-     *
-     * Note we don't verify compLen/uncompLen if they don't request the
-     * dataOffset, because dataOffset is expensive to determine.  However,
-     * if they don't have the file offset, they're not likely to be doing
-     * anything with the contents.
-     */
-    if (pOffset != NULL) {
-        long localHdrOffset = get4LE(ptr + kCDELocalOffset);
-        if (localHdrOffset + kLFHLen >= cdOffset) {
-            ALOGE("ERROR: bad local hdr offset in zip\n");
-            return false;
-        }
-
-        unsigned char lfhBuf[kLFHLen];
-
-#ifdef HAVE_PREAD
-        /*
-         * This file descriptor might be from zygote's preloaded assets,
-         * so we need to do an pread64() instead of a lseek64() + read() to
-         * guarantee atomicity across the processes with the shared file
-         * descriptors.
-         */
-        ssize_t actual =
-                TEMP_FAILURE_RETRY(pread64(mFd, lfhBuf, sizeof(lfhBuf), localHdrOffset));
-
-        if (actual != sizeof(lfhBuf)) {
-            ALOGW("failed reading lfh from offset %ld\n", localHdrOffset);
-            return false;
-        }
-
-        if (get4LE(lfhBuf) != kLFHSignature) {
-            ALOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
-                    "got: data=0x%08lx\n",
-                    localHdrOffset, kLFHSignature, get4LE(lfhBuf));
-            return false;
-        }
-#else /* HAVE_PREAD */
-        /*
-         * For hosts don't have pread64() we cannot guarantee atomic reads from
-         * an offset in a file. Android should never run on those platforms.
-         * File descriptors inherited from a fork() share file offsets and
-         * there would be nothing to protect from two different processes
-         * calling lseek64() concurrently.
-         */
-
-        {
-            AutoMutex _l(mFdLock);
-
-            if (lseek64(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
-                ALOGW("failed seeking to lfh at offset %ld\n", localHdrOffset);
-                return false;
-            }
-
-            ssize_t actual =
-                    TEMP_FAILURE_RETRY(read(mFd, lfhBuf, sizeof(lfhBuf)));
-            if (actual != sizeof(lfhBuf)) {
-                ALOGW("failed reading lfh from offset %ld\n", localHdrOffset);
-                return false;
-            }
-
-            if (get4LE(lfhBuf) != kLFHSignature) {
-                off64_t actualOffset = lseek64(mFd, 0, SEEK_CUR);
-                ALOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
-                        "got: offset=" ZD " data=0x%08lx\n",
-                        localHdrOffset, kLFHSignature, (ZD_TYPE) actualOffset, get4LE(lfhBuf));
-                return false;
-            }
-        }
-#endif /* HAVE_PREAD */
-
-        unsigned int gpbf = get2LE(lfhBuf + kLFHGPBFlags);
-        if ((gpbf & kGPFUnsupportedMask) != 0) {
-            ALOGW("Invalid General Purpose Bit Flag: %d", gpbf);
-            return false;
-        }
-
-        off64_t dataOffset = localHdrOffset + kLFHLen
-            + get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
-        if (dataOffset >= cdOffset) {
-            ALOGW("bad data offset %ld in zip\n", (long) dataOffset);
-            return false;
-        }
-
-        /* check lengths */
-        if ((dataOffset >= cdOffset) || (compLen > (cdOffset - dataOffset))) {
-            ALOGW("bad compressed length in zip (%ld + " ZD " > %ld)\n",
-                (long) dataOffset, (ZD_TYPE) compLen, (long) cdOffset);
-            return false;
-        }
-
-        if (method == kCompressStored &&
-            ((dataOffset >= cdOffset) ||
-             (uncompLen > (cdOffset - dataOffset))))
-        {
-            ALOGE("ERROR: bad uncompressed length in zip (%ld + " ZD " > %ld)\n",
-                (long) dataOffset, (ZD_TYPE) uncompLen, (long) cdOffset);
-            return false;
-        }
-
-        *pOffset = dataOffset;
-    }
-
-    return true;
-}
-
-/*
- * Copy the entry's filename to the buffer.
- */
-int ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen)
-    const
-{
-    int ent = entryToIndex(entry);
-    if (ent < 0)
-        return -1;
-
-    int nameLen = mHashTable[ent].nameLen;
-    if (bufLen < nameLen+1)
-        return nameLen+1;
-
-    memcpy(buffer, mHashTable[ent].name, nameLen);
-    buffer[nameLen] = '\0';
-    return 0;
-}
-
-/*
- * Create a new FileMap object that spans the data in "entry".
- */
-FileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const
-{
-    /*
-     * TODO: the efficient way to do this is to modify FileMap to allow
-     * sub-regions of a file to be mapped.  A reference-counting scheme
-     * can manage the base memory mapping.  For now, we just create a brand
-     * new mapping off of the Zip archive file descriptor.
-     */
-
-    FileMap* newMap;
-    int method;
-    size_t uncompLen;
-    size_t compLen;
-    off64_t offset;
-
-    if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
-        return NULL;
-    }
-
-    size_t actualLen;
-    if (method == kCompressStored) {
-        actualLen = uncompLen;
-    } else {
-        actualLen = compLen;
-    }
-
-    newMap = new FileMap();
-    if (!newMap->create(mFileName, mFd, offset, actualLen, true)) {
-        newMap->release();
-        return NULL;
-    }
-
-    return newMap;
-}
-
-/*
- * Uncompress an entry, in its entirety, into the provided output buffer.
- *
- * This doesn't verify the data's CRC, which might be useful for
- * uncompressed data.  The caller should be able to manage it.
- */
-bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
-{
-    const size_t kSequentialMin = 32768;
-    bool result = false;
-    int ent = entryToIndex(entry);
-    if (ent < 0) {
-        return false;
-    }
-
-    int method;
-    size_t uncompLen, compLen;
-    off64_t offset;
-    const unsigned char* ptr;
-    FileMap *file;
-
-    if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
-        goto bail;
-    }
-
-    file = createEntryFileMap(entry);
-    if (file == NULL) {
-        goto bail;
-    }
-
-    ptr = (const unsigned char*) file->getDataPtr();
-
-    /*
-     * Experiment with madvise hint.  When we want to uncompress a file,
-     * we pull some stuff out of the central dir entry and then hit a
-     * bunch of compressed or uncompressed data sequentially.  The CDE
-     * visit will cause a limited amount of read-ahead because it's at
-     * the end of the file.  We could end up doing lots of extra disk
-     * access if the file we're prying open is small.  Bottom line is we
-     * probably don't want to turn MADV_SEQUENTIAL on and leave it on.
-     *
-     * So, if the compressed size of the file is above a certain minimum
-     * size, temporarily boost the read-ahead in the hope that the extra
-     * pair of system calls are negated by a reduction in page faults.
-     */
-    if (compLen > kSequentialMin)
-        file->advise(FileMap::SEQUENTIAL);
-
-    if (method == kCompressStored) {
-        memcpy(buffer, ptr, uncompLen);
-    } else {
-        if (!inflateBuffer(buffer, ptr, uncompLen, compLen))
-            goto unmap;
-    }
-
-    if (compLen > kSequentialMin)
-        file->advise(FileMap::NORMAL);
-
-    result = true;
-
-unmap:
-    file->release();
-bail:
-    return result;
-}
-
-/*
- * Uncompress an entry, in its entirety, to an open file descriptor.
- *
- * This doesn't verify the data's CRC, but probably should.
- */
-bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
-{
-    bool result = false;
-    int ent = entryToIndex(entry);
-    if (ent < 0) {
-        return false;
-    }
-
-    int method;
-    size_t uncompLen, compLen;
-    off64_t offset;
-    const unsigned char* ptr;
-    FileMap *file;
-
-    if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
-        goto bail;
-    }
-
-    file = createEntryFileMap(entry);
-    if (file == NULL) {
-        goto bail;
-    }
-
-    ptr = (const unsigned char*) file->getDataPtr();
-
-    if (method == kCompressStored) {
-        ssize_t actual = TEMP_FAILURE_RETRY(write(fd, ptr, uncompLen));
-        if (actual < 0) {
-            ALOGE("Write failed: %s\n", strerror(errno));
-            goto unmap;
-        } else if ((size_t) actual != uncompLen) {
-            ALOGE("Partial write during uncompress (" ZD " of " ZD ")\n",
-                (ZD_TYPE) actual, (ZD_TYPE) uncompLen);
-            goto unmap;
-        } else {
-            ALOGI("+++ successful write\n");
-        }
-    } else {
-        if (!inflateBuffer(fd, ptr, uncompLen, compLen)) {
-            goto unmap;
-        }
-    }
-
-    result = true;
-
-unmap:
-    file->release();
-bail:
-    return result;
-}
-
-/*
- * Uncompress "deflate" data from one buffer to another.
- */
-/*static*/ bool ZipFileRO::inflateBuffer(void* outBuf, const void* inBuf,
-    size_t uncompLen, size_t compLen)
-{
-    bool result = false;
-    z_stream zstream;
-    int zerr;
-
-    /*
-     * Initialize the zlib stream struct.
-     */
-    memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = (Bytef*)inBuf;
-    zstream.avail_in = compLen;
-    zstream.next_out = (Bytef*) outBuf;
-    zstream.avail_out = uncompLen;
-    zstream.data_type = Z_UNKNOWN;
-
-    /*
-     * Use the undocumented "negative window bits" feature to tell zlib
-     * that there's no zlib header waiting for it.
-     */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    /*
-     * Expand data.
-     */
-    zerr = inflate(&zstream, Z_FINISH);
-    if (zerr != Z_STREAM_END) {
-        ALOGW("Zip inflate failed, zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
-            zerr, zstream.next_in, zstream.avail_in,
-            zstream.next_out, zstream.avail_out);
-        goto z_bail;
-    }
-
-    /* paranoia */
-    if (zstream.total_out != uncompLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs " ZD ")\n",
-            zstream.total_out, (ZD_TYPE) uncompLen);
-        goto z_bail;
-    }
-
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-    return result;
-}
-
-/*
- * Uncompress "deflate" data from one buffer to an open file descriptor.
- */
-/*static*/ bool ZipFileRO::inflateBuffer(int fd, const void* inBuf,
-    size_t uncompLen, size_t compLen)
-{
-    bool result = false;
-    const size_t kWriteBufSize = 32768;
-    unsigned char writeBuf[kWriteBufSize];
-    z_stream zstream;
-    int zerr;
-
-    /*
-     * Initialize the zlib stream struct.
-     */
-    memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = (Bytef*)inBuf;
-    zstream.avail_in = compLen;
-    zstream.next_out = (Bytef*) writeBuf;
-    zstream.avail_out = sizeof(writeBuf);
-    zstream.data_type = Z_UNKNOWN;
-
-    /*
-     * Use the undocumented "negative window bits" feature to tell zlib
-     * that there's no zlib header waiting for it.
-     */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    /*
-     * Loop while we have more to do.
-     */
-    do {
-        /*
-         * Expand data.
-         */
-        zerr = inflate(&zstream, Z_NO_FLUSH);
-        if (zerr != Z_OK && zerr != Z_STREAM_END) {
-            ALOGW("zlib inflate: zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
-                zerr, zstream.next_in, zstream.avail_in,
-                zstream.next_out, zstream.avail_out);
-            goto z_bail;
-        }
-
-        /* write when we're full or when we're done */
-        if (zstream.avail_out == 0 ||
-            (zerr == Z_STREAM_END && zstream.avail_out != sizeof(writeBuf)))
-        {
-            long writeSize = zstream.next_out - writeBuf;
-            int cc = TEMP_FAILURE_RETRY(write(fd, writeBuf, writeSize));
-            if (cc < 0) {
-                ALOGW("write failed in inflate: %s", strerror(errno));
-                goto z_bail;
-            } else if (cc != (int) writeSize) {
-                ALOGW("write failed in inflate (%d vs %ld)", cc, writeSize);
-                goto z_bail;
-            }
-
-            zstream.next_out = writeBuf;
-            zstream.avail_out = sizeof(writeBuf);
-        }
-    } while (zerr == Z_OK);
-
-    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
-
-    /* paranoia */
-    if (zstream.total_out != uncompLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs " ZD ")\n",
-            zstream.total_out, (ZD_TYPE) uncompLen);
-        goto z_bail;
-    }
-
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-    return result;
-}
diff --git a/libs/androidfw/ZipUtils.cpp b/libs/androidfw/ZipUtils.cpp
deleted file mode 100644
index 997eb7d..0000000
--- a/libs/androidfw/ZipUtils.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Misc zip/gzip utility functions.
-//
-
-#define LOG_TAG "ziputil"
-
-#include <androidfw/ZipUtils.h>
-#include <androidfw/ZipFileRO.h>
-#include <utils/Log.h>
-#include <utils/Compat.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <zlib.h>
-
-using namespace android;
-
-/*
- * Utility function that expands zip/gzip "deflate" compressed data
- * into a buffer.
- *
- * "fd" is an open file positioned at the start of the "deflate" data
- * "buf" must hold at least "uncompressedLen" bytes.
- */
-/*static*/ bool ZipUtils::inflateToBuffer(int fd, void* buf,
-    long uncompressedLen, long compressedLen)
-{
-    bool result = false;
-	const unsigned long kReadBufSize = 32768;
-	unsigned char* readBuf = NULL;
-    z_stream zstream;
-    int zerr;
-    unsigned long compRemaining;
-
-    assert(uncompressedLen >= 0);
-    assert(compressedLen >= 0);
-
-	readBuf = new unsigned char[kReadBufSize];
-	if (readBuf == NULL)
-        goto bail;
-    compRemaining = compressedLen;
-
-    /*
-     * Initialize the zlib stream.
-     */
-	memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = NULL;
-    zstream.avail_in = 0;
-    zstream.next_out = (Bytef*) buf;
-    zstream.avail_out = uncompressedLen;
-    zstream.data_type = Z_UNKNOWN;
-
-	/*
-	 * Use the undocumented "negative window bits" feature to tell zlib
-	 * that there's no zlib header waiting for it.
-	 */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    /*
-     * Loop while we have data.
-     */
-    do {
-        unsigned long getSize;
-
-        /* read as much as we can */
-        if (zstream.avail_in == 0) {
-            getSize = (compRemaining > kReadBufSize) ?
-                        kReadBufSize : compRemaining;
-            ALOGV("+++ reading %ld bytes (%ld left)\n",
-                getSize, compRemaining);
-
-            int cc = TEMP_FAILURE_RETRY(read(fd, readBuf, getSize));
-            if (cc < 0) {
-                ALOGW("inflate read failed: %s", strerror(errno));
-            } else if (cc != (int) getSize) {
-                ALOGW("inflate read failed (%d vs %ld)", cc, getSize);
-                goto z_bail;
-            }
-
-            compRemaining -= getSize;
-
-            zstream.next_in = readBuf;
-            zstream.avail_in = getSize;
-        }
-
-        /* uncompress the data */
-        zerr = inflate(&zstream, Z_NO_FLUSH);
-        if (zerr != Z_OK && zerr != Z_STREAM_END) {
-            ALOGD("zlib inflate call failed (zerr=%d)\n", zerr);
-            goto z_bail;
-        }
-
-		/* output buffer holds all, so no need to write the output */
-    } while (zerr == Z_OK);
-
-    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
-
-    if ((long) zstream.total_out != uncompressedLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs %ld)\n",
-            zstream.total_out, uncompressedLen);
-        goto z_bail;
-    }
-
-    // success!
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-	delete[] readBuf;
-    return result;
-}
-
-/*
- * Utility function that expands zip/gzip "deflate" compressed data
- * into a buffer.
- *
- * (This is a clone of the previous function, but it takes a FILE* instead
- * of an fd.  We could pass fileno(fd) to the above, but we can run into
- * trouble when "fp" has a different notion of what fd's file position is.)
- *
- * "fp" is an open file positioned at the start of the "deflate" data
- * "buf" must hold at least "uncompressedLen" bytes.
- */
-/*static*/ bool ZipUtils::inflateToBuffer(FILE* fp, void* buf,
-    long uncompressedLen, long compressedLen)
-{
-    bool result = false;
-	const unsigned long kReadBufSize = 32768;
-	unsigned char* readBuf = NULL;
-    z_stream zstream;
-    int zerr;
-    unsigned long compRemaining;
-
-    assert(uncompressedLen >= 0);
-    assert(compressedLen >= 0);
-
-	readBuf = new unsigned char[kReadBufSize];
-	if (readBuf == NULL)
-        goto bail;
-    compRemaining = compressedLen;
-
-    /*
-     * Initialize the zlib stream.
-     */
-	memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = NULL;
-    zstream.avail_in = 0;
-    zstream.next_out = (Bytef*) buf;
-    zstream.avail_out = uncompressedLen;
-    zstream.data_type = Z_UNKNOWN;
-
-	/*
-	 * Use the undocumented "negative window bits" feature to tell zlib
-	 * that there's no zlib header waiting for it.
-	 */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    /*
-     * Loop while we have data.
-     */
-    do {
-        unsigned long getSize;
-
-        /* read as much as we can */
-        if (zstream.avail_in == 0) {
-            getSize = (compRemaining > kReadBufSize) ?
-                        kReadBufSize : compRemaining;
-            ALOGV("+++ reading %ld bytes (%ld left)\n",
-                getSize, compRemaining);
-
-            int cc = fread(readBuf, 1, getSize, fp);
-            if (cc != (int) getSize) {
-                ALOGD("inflate read failed (%d vs %ld)\n",
-                    cc, getSize);
-                goto z_bail;
-            }
-
-            compRemaining -= getSize;
-
-            zstream.next_in = readBuf;
-            zstream.avail_in = getSize;
-        }
-
-        /* uncompress the data */
-        zerr = inflate(&zstream, Z_NO_FLUSH);
-        if (zerr != Z_OK && zerr != Z_STREAM_END) {
-            ALOGD("zlib inflate call failed (zerr=%d)\n", zerr);
-            goto z_bail;
-        }
-
-		/* output buffer holds all, so no need to write the output */
-    } while (zerr == Z_OK);
-
-    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
-
-    if ((long) zstream.total_out != uncompressedLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs %ld)\n",
-            zstream.total_out, uncompressedLen);
-        goto z_bail;
-    }
-
-    // success!
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-	delete[] readBuf;
-    return result;
-}
-
-/*
- * Look at the contents of a gzip archive.  We want to know where the
- * data starts, and how long it will be after it is uncompressed.
- *
- * We expect to find the CRC and length as the last 8 bytes on the file.
- * This is a pretty reasonable thing to expect for locally-compressed
- * files, but there's a small chance that some extra padding got thrown
- * on (the man page talks about compressed data written to tape).  We
- * don't currently deal with that here.  If "gzip -l" whines, we're going
- * to fail too.
- *
- * On exit, "fp" is pointing at the start of the compressed data.
- */
-/*static*/ bool ZipUtils::examineGzip(FILE* fp, int* pCompressionMethod,
-    long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32)
-{
-    enum {  // flags
-        FTEXT       = 0x01,
-        FHCRC       = 0x02,
-        FEXTRA      = 0x04,
-        FNAME       = 0x08,
-        FCOMMENT    = 0x10,
-    };
-    int ic;
-    int method, flags;
-    int i;
-
-    ic = getc(fp);
-    if (ic != 0x1f || getc(fp) != 0x8b)
-        return false;       // not gzip
-    method = getc(fp);
-    flags = getc(fp);
-
-    /* quick sanity checks */
-    if (method == EOF || flags == EOF)
-        return false;
-    if (method != ZipFileRO::kCompressDeflated)
-        return false;
-
-    /* skip over 4 bytes of mod time, 1 byte XFL, 1 byte OS */
-    for (i = 0; i < 6; i++)
-        (void) getc(fp);
-    /* consume "extra" field, if present */
-    if ((flags & FEXTRA) != 0) {
-        int len;
-
-        len = getc(fp);
-        len |= getc(fp) << 8;
-        while (len-- && getc(fp) != EOF)
-            ;
-    }
-    /* consume filename, if present */
-    if ((flags & FNAME) != 0) {
-        do {
-            ic = getc(fp);
-        } while (ic != 0 && ic != EOF);
-    }
-    /* consume comment, if present */
-    if ((flags & FCOMMENT) != 0) {
-        do {
-            ic = getc(fp);
-        } while (ic != 0 && ic != EOF);
-    }
-    /* consume 16-bit header CRC, if present */
-    if ((flags & FHCRC) != 0) {
-        (void) getc(fp);
-        (void) getc(fp);
-    }
-
-    if (feof(fp) || ferror(fp))
-        return false;
-
-    /* seek to the end; CRC and length are in the last 8 bytes */
-    long curPosn = ftell(fp);
-    unsigned char buf[8];
-    fseek(fp, -8, SEEK_END);
-    *pCompressedLen = ftell(fp) - curPosn;
-
-    if (fread(buf, 1, 8, fp) != 8)
-        return false;
-    /* seek back to start of compressed data */
-    fseek(fp, curPosn, SEEK_SET);
-
-    *pCompressionMethod = method;
-    *pCRC32 = ZipFileRO::get4LE(&buf[0]);
-    *pUncompressedLen = ZipFileRO::get4LE(&buf[4]);
-
-    return true;
-}
diff --git a/libs/androidfw/misc.cpp b/libs/androidfw/misc.cpp
deleted file mode 100644
index 29686ef..0000000
--- a/libs/androidfw/misc.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 "misc"
-
-//
-// Miscellaneous utility functions.
-//
-#include <androidfw/misc.h>
-
-#include <sys/stat.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-
-using namespace android;
-
-namespace android {
-
-/*
- * Get a file's type.
- */
-FileType getFileType(const char* fileName)
-{
-    struct stat sb;
-
-    if (stat(fileName, &sb) < 0) {
-        if (errno == ENOENT || errno == ENOTDIR)
-            return kFileTypeNonexistent;
-        else {
-            fprintf(stderr, "getFileType got errno=%d on '%s'\n",
-                errno, fileName);
-            return kFileTypeUnknown;
-        }
-    } else {
-        if (S_ISREG(sb.st_mode))
-            return kFileTypeRegular;
-        else if (S_ISDIR(sb.st_mode))
-            return kFileTypeDirectory;
-        else if (S_ISCHR(sb.st_mode))
-            return kFileTypeCharDev;
-        else if (S_ISBLK(sb.st_mode))
-            return kFileTypeBlockDev;
-        else if (S_ISFIFO(sb.st_mode))
-            return kFileTypeFifo;
-#ifdef HAVE_SYMLINKS
-        else if (S_ISLNK(sb.st_mode))
-            return kFileTypeSymlink;
-        else if (S_ISSOCK(sb.st_mode))
-            return kFileTypeSocket;
-#endif
-        else
-            return kFileTypeUnknown;
-    }
-}
-
-/*
- * Get a file's modification date.
- */
-time_t getFileModDate(const char* fileName)
-{
-    struct stat sb;
-
-    if (stat(fileName, &sb) < 0)
-        return (time_t) -1;
-
-    return sb.st_mtime;
-}
-
-}; // namespace android
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
deleted file mode 100644
index 0522212..0000000
--- a/libs/androidfw/tests/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# Build the unit tests.
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# Build the unit tests.
-test_src_files := \
-    ObbFile_test.cpp \
-    ZipFileRO_test.cpp
-
-shared_libraries := \
-    libandroidfw \
-    libcutils \
-    libutils \
-    libui \
-    libstlport
-
-static_libraries := \
-    libgtest \
-    libgtest_main
-
-$(foreach file,$(test_src_files), \
-    $(eval include $(CLEAR_VARS)) \
-    $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
-    $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
-    $(eval LOCAL_SRC_FILES := $(file)) \
-    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
-    $(eval include $(BUILD_NATIVE_TEST)) \
-)
-
-# Build the manual test programs.
-include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/libs/androidfw/tests/ObbFile_test.cpp b/libs/androidfw/tests/ObbFile_test.cpp
deleted file mode 100644
index 2c9f650..0000000
--- a/libs/androidfw/tests/ObbFile_test.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ObbFile_test"
-#include <androidfw/ObbFile.h>
-#include <utils/Log.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-#include <gtest/gtest.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <string.h>
-
-namespace android {
-
-#define TEST_FILENAME "/test.obb"
-
-class ObbFileTest : public testing::Test {
-protected:
-    sp<ObbFile> mObbFile;
-    char* mExternalStorage;
-    char* mFileName;
-
-    virtual void SetUp() {
-        mObbFile = new ObbFile();
-        mExternalStorage = getenv("EXTERNAL_STORAGE");
-
-        const int totalLen = strlen(mExternalStorage) + strlen(TEST_FILENAME) + 1;
-        mFileName = new char[totalLen];
-        snprintf(mFileName, totalLen, "%s%s", mExternalStorage, TEST_FILENAME);
-
-        int fd = ::open(mFileName, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
-        if (fd < 0) {
-            FAIL() << "Couldn't create " << mFileName << " for tests";
-        }
-    }
-
-    virtual void TearDown() {
-    }
-};
-
-TEST_F(ObbFileTest, ReadFailure) {
-    EXPECT_FALSE(mObbFile->readFrom(-1))
-            << "No failure on invalid file descriptor";
-}
-
-TEST_F(ObbFileTest, WriteThenRead) {
-    const char* packageName = "com.example.obbfile";
-    const int32_t versionNum = 1;
-
-    mObbFile->setPackageName(String8(packageName));
-    mObbFile->setVersion(versionNum);
-#define SALT_SIZE 8
-    unsigned char salt[SALT_SIZE] = {0x01, 0x10, 0x55, 0xAA, 0xFF, 0x00, 0x5A, 0xA5};
-    EXPECT_TRUE(mObbFile->setSalt(salt, SALT_SIZE))
-            << "Salt should be successfully set";
-
-    EXPECT_TRUE(mObbFile->writeTo(mFileName))
-            << "couldn't write to fake .obb file";
-
-    mObbFile = new ObbFile();
-
-    EXPECT_TRUE(mObbFile->readFrom(mFileName))
-            << "couldn't read from fake .obb file";
-
-    EXPECT_EQ(versionNum, mObbFile->getVersion())
-            << "version didn't come out the same as it went in";
-    const char* currentPackageName = mObbFile->getPackageName().string();
-    EXPECT_STREQ(packageName, currentPackageName)
-            << "package name didn't come out the same as it went in";
-
-    size_t saltLen;
-    const unsigned char* newSalt = mObbFile->getSalt(&saltLen);
-
-    EXPECT_EQ(sizeof(salt), saltLen)
-            << "salt sizes were not the same";
-
-    for (int i = 0; i < sizeof(salt); i++) {
-        EXPECT_EQ(salt[i], newSalt[i])
-                << "salt character " << i << " should be equal";
-    }
-    EXPECT_TRUE(memcmp(newSalt, salt, sizeof(salt)) == 0)
-            << "salts should be the same";
-}
-
-}
diff --git a/libs/androidfw/tests/ZipFileRO_test.cpp b/libs/androidfw/tests/ZipFileRO_test.cpp
deleted file mode 100644
index cb9c721..0000000
--- a/libs/androidfw/tests/ZipFileRO_test.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ZipFileRO_test"
-#include <utils/Log.h>
-#include <androidfw/ZipFileRO.h>
-
-#include <gtest/gtest.h>
-
-#include <fcntl.h>
-#include <string.h>
-
-namespace android {
-
-class ZipFileROTest : public testing::Test {
-protected:
-    virtual void SetUp() {
-    }
-
-    virtual void TearDown() {
-    }
-};
-
-TEST_F(ZipFileROTest, ZipTimeConvertSuccess) {
-    struct tm t;
-
-    // 2011-06-29 14:40:40
-    long when = 0x3EDD7514;
-
-    ZipFileRO::zipTimeToTimespec(when, &t);
-
-    EXPECT_EQ(2011, t.tm_year + 1900)
-            << "Year was improperly converted.";
-
-    EXPECT_EQ(6, t.tm_mon)
-            << "Month was improperly converted.";
-
-    EXPECT_EQ(29, t.tm_mday)
-            << "Day was improperly converted.";
-
-    EXPECT_EQ(14, t.tm_hour)
-            << "Hour was improperly converted.";
-
-    EXPECT_EQ(40, t.tm_min)
-            << "Minute was improperly converted.";
-
-    EXPECT_EQ(40, t.tm_sec)
-            << "Second was improperly converted.";
-}
-
-}
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 411c133..ce8364e 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -58,6 +58,7 @@
 		external/skia/include/utils
 
 	LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES
+	LOCAL_CFLAGS += -Wno-unused-parameter
 	LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 	LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libEGL libGLESv2 libskia libui
 	LOCAL_MODULE := libhwui
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 282aee9..f8f2284 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -62,7 +62,7 @@
 static const uint32_t gMaxNumberOfQuads = 2048;
 
 // Generates simple and textured vertices
-#define FV(x, y, u, v) { { x, y }, { u, v } }
+#define FV(x, y, u, v) { x, y, u, v }
 
 // This array is never used directly but used as a memcpy source in the
 // OpenGLRenderer constructor
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index bb6526e..a3e4bb4 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -526,7 +526,7 @@
 
     setViewProperties<T>(renderer, handler, level + 1);
 
-    if (mClipToBounds && renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
+    if (mClipToBounds && renderer.quickRejectConservative(0, 0, mWidth, mHeight)) {
         DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (level + 1) * 2, "", restoreTo);
         handler(mRestoreToCountOp->reinit(restoreTo), PROPERTY_SAVECOUNT, mClipToBounds);
         renderer.restoreToCount(restoreTo);
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 326805a..88077d4 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -182,9 +182,12 @@
     }
 
     inline float strokeWidthOutset() {
-        float width = mPaint->getStrokeWidth();
-        if (width == 0) return 0.5f; // account for hairline
-        return width * 0.5f;
+        // since anything AA stroke with less than 1.0 pixel width is drawn with an alpha-reduced
+        // 1.0 stroke, treat 1.0 as minimum.
+
+        // TODO: it would be nice if this could take scale into account, but scale isn't stable
+        // since higher levels of the view hierarchy can change scale out from underneath it.
+        return fmaxf(mPaint->getStrokeWidth(), 1) * 0.5f;
     }
 
 protected:
@@ -1028,8 +1031,8 @@
             TextureVertex* opVertices = opMesh->vertices;
             for (uint32_t j = 0; j < vertexCount; j++, opVertices++) {
                 TextureVertex::set(vertex++,
-                        opVertices->position[0] + tx, opVertices->position[1] + ty,
-                        opVertices->texture[0], opVertices->texture[1]);
+                        opVertices->x + tx, opVertices->y + ty,
+                        opVertices->u, opVertices->v);
             }
 
             // Dirty the current layer if possible. When the 9-patch does not
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 8866029..d024923 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -506,7 +506,7 @@
 void DisplayListRenderer::addDrawOp(DrawOp* op) {
     Rect localBounds;
     if (op->getLocalBounds(mDrawModifiers, localBounds)) {
-        bool rejected = quickRejectNoScissor(localBounds.left, localBounds.top,
+        bool rejected = quickRejectConservative(localBounds.left, localBounds.top,
                 localBounds.right, localBounds.bottom);
         op->setQuickRejected(rejected);
     }
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 00e7870..48613fe 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -76,7 +76,8 @@
     renderer->setupDrawShader();
     renderer->setupDrawBlending(true, mode);
     renderer->setupDrawProgram();
-    renderer->setupDrawModelView(x, y, x, y, pureTranslate, true);
+    renderer->setupDrawModelView(kModelViewMode_Translate, false,
+            0.0f, 0.0f, 0.0f, 0.0f, pureTranslate);
     // Calling setupDrawTexture with the name 0 will enable the
     // uv attributes and increase the texture unit count
     // texture binding will be performed by the font renderer as
@@ -514,8 +515,8 @@
             texture->setLinearFiltering(mLinearFiltering, false);
 
             TextureVertex* mesh = texture->mesh();
-            caches.bindPositionVertexPointer(force, &mesh[0].position[0]);
-            caches.bindTexCoordsVertexPointer(force, &mesh[0].texture[0]);
+            caches.bindPositionVertexPointer(force, &mesh[0].x);
+            caches.bindTexCoordsVertexPointer(force, &mesh[0].u);
             force = false;
 
             glDrawElements(GL_TRIANGLES, texture->meshElementCount(),
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 0916942..ffd1e8c 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -115,7 +115,7 @@
 // Callbacks
 ///////////////////////////////////////////////////////////////////////////////
 
-void GradientCache::operator()(GradientCacheEntry& shader, Texture*& texture) {
+void GradientCache::operator()(GradientCacheEntry&, Texture*& texture) {
     if (texture) {
         const uint32_t size = texture->width * texture->height * bytesPerPixel();
         mSize -= size;
@@ -185,7 +185,7 @@
         mCache.removeOldest();
     }
 
-    generateTexture(colors, positions, count, texture);
+    generateTexture(colors, positions, texture);
 
     mSize += size;
     mCache.put(gradient, texture);
@@ -238,8 +238,7 @@
     dst += 4 * sizeof(float);
 }
 
-void GradientCache::generateTexture(uint32_t* colors, float* positions,
-        int count, Texture* texture) {
+void GradientCache::generateTexture(uint32_t* colors, float* positions, Texture* texture) {
     const uint32_t width = texture->width;
     const GLsizei rowBytes = width * bytesPerPixel();
     uint8_t pixels[rowBytes * texture->height];
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index 43934d9..6a783b1 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -151,7 +151,7 @@
     Texture* addLinearGradient(GradientCacheEntry& gradient,
             uint32_t* colors, float* positions, int count);
 
-    void generateTexture(uint32_t* colors, float* positions, int count, Texture* texture);
+    void generateTexture(uint32_t* colors, float* positions, Texture* texture);
 
     struct GradientInfo {
         uint32_t width;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 35fc804..82c74da 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -779,11 +779,10 @@
 
 int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom,
         int alpha, SkXfermode::Mode mode, int flags) {
-    const GLuint previousFbo = mSnapshot->fbo;
     const int count = saveSnapshot(flags);
 
     if (!mSnapshot->isIgnored()) {
-        createLayer(left, top, right, bottom, alpha, mode, flags, previousFbo);
+        createLayer(left, top, right, bottom, alpha, mode, flags);
     }
 
     return count;
@@ -835,7 +834,6 @@
 
 int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float bottom,
         int alpha, SkXfermode::Mode mode, int flags) {
-    const GLuint previousFbo = mSnapshot->fbo;
     const int count = saveSnapshot(flags);
 
     if (!mSnapshot->isIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) {
@@ -911,7 +909,7 @@
  *     something actually gets drawn are the layers regions cleared.
  */
 bool OpenGLRenderer::createLayer(float left, float top, float right, float bottom,
-        int alpha, SkXfermode::Mode mode, int flags, GLuint previousFbo) {
+        int alpha, SkXfermode::Mode mode, int flags) {
     LAYER_LOGD("Requesting layer %.2fx%.2f", right - left, bottom - top);
     LAYER_LOGD("Layer cache size = %d", mCaches.layerCache.getSize());
 
@@ -948,7 +946,7 @@
 
     startMark("SaveLayer");
     if (fboLayer) {
-        return createFboLayer(layer, bounds, clip, previousFbo);
+        return createFboLayer(layer, bounds, clip);
     } else {
         // Copy the framebuffer into the layer
         layer->bindTexture();
@@ -974,7 +972,7 @@
     return true;
 }
 
-bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLuint previousFbo) {
+bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip) {
     layer->clipRect.set(clip);
     layer->setFbo(mCaches.fboCache.get());
 
@@ -1034,7 +1032,8 @@
     const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer;
 
     bool clipRequired = false;
-    quickRejectNoScissor(rect, &clipRequired); // safely ignore return, should never be rejected
+    calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom,
+            &clipRequired, false); // safely ignore return, should never be rejected
     mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired);
 
     if (fboLayer) {
@@ -1076,7 +1075,13 @@
         }
     } else if (!rect.isEmpty()) {
         dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
+
+        save(0);
+        // the layer contains screen buffer content that shouldn't be alpha modulated
+        // (and any necessary alpha modulation was handled drawing into the layer)
+        mSnapshot->alpha = 1.0f;
         composeLayerRect(layer, rect, true);
+        restore();
     }
 
     dirtyClip();
@@ -1116,13 +1121,15 @@
         const float y = (int) floorf(rect.top + currentTransform().getTranslateY() + 0.5f);
 
         layer->setFilter(GL_NEAREST);
-        setupDrawModelView(x, y, x + rect.getWidth(), y + rect.getHeight(), true);
+        setupDrawModelView(kModelViewMode_TranslateAndScale, false,
+                x, y, x + rect.getWidth(), y + rect.getHeight(), true);
     } else {
         layer->setFilter(GL_LINEAR);
-        setupDrawModelView(rect.left, rect.top, rect.right, rect.bottom);
+        setupDrawModelView(kModelViewMode_TranslateAndScale, false,
+                rect.left, rect.top, rect.right, rect.bottom);
     }
     setupDrawTextureTransformUniforms(layer->getTexTransform());
-    setupDrawMesh(&mMeshVertices[0].position[0], &mMeshVertices[0].texture[0]);
+    setupDrawMesh(&mMeshVertices[0].x, &mMeshVertices[0].u);
 
     glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
 }
@@ -1155,7 +1162,7 @@
         bool blend = layer->isBlend() || alpha < 1.0f;
         drawTextureMesh(x, y, x + rect.getWidth(), y + rect.getHeight(),
                 layer->getTexture(), alpha, layer->getMode(), blend,
-                &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
+                &mMeshVertices[0].x, &mMeshVertices[0].u,
                 GL_TRIANGLE_STRIP, gMeshCount, swap, swap || simpleTransform);
 
         resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
@@ -1231,12 +1238,14 @@
             const float y = (int) floorf(rect.top + currentTransform().getTranslateY() + 0.5f);
 
             layer->setFilter(GL_NEAREST);
-            setupDrawModelViewTranslate(x, y, x + rect.getWidth(), y + rect.getHeight(), true);
+            setupDrawModelView(kModelViewMode_Translate, false,
+                    x, y, x + rect.getWidth(), y + rect.getHeight(), true);
         } else {
             layer->setFilter(GL_LINEAR);
-            setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom);
+            setupDrawModelView(kModelViewMode_Translate, false,
+                    rect.left, rect.top, rect.right, rect.bottom);
         }
-        setupDrawMeshIndices(&mesh[0].position[0], &mesh[0].texture[0]);
+        setupDrawMeshIndices(&mesh[0].x, &mesh[0].u);
 
         for (size_t i = 0; i < count; i++) {
             const android::Rect* r = &rects[i];
@@ -1268,15 +1277,15 @@
         }
 
 #if DEBUG_LAYERS_AS_REGIONS
-        drawRegionRects(layer->region);
+        drawRegionRectsDebug(layer->region);
 #endif
 
         layer->region.clear();
     }
 }
 
-void OpenGLRenderer::drawRegionRects(const Region& region) {
 #if DEBUG_LAYERS_AS_REGIONS
+void OpenGLRenderer::drawRegionRectsDebug(const Region& region) {
     size_t count;
     const android::Rect* rects = region.getArray(&count);
 
@@ -1298,8 +1307,8 @@
         drawColorRect(r.left, r.top, r.right, r.bottom, colors[offset + (i & 0x1)],
                 SkXfermode::kSrcOver_Mode);
     }
-#endif
 }
+#endif
 
 void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color,
         SkXfermode::Mode mode, bool dirty) {
@@ -1345,12 +1354,12 @@
     }
 }
 
-void OpenGLRenderer::drawIndexedQuads(Vertex* mesh, GLsizei quadsCount) {
+void OpenGLRenderer::issueIndexedQuadDraw(Vertex* mesh, GLsizei quadsCount) {
     GLsizei elementsCount = quadsCount * 6;
     while (elementsCount > 0) {
         GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6);
 
-        setupDrawIndexedVertices(&mesh[0].position[0]);
+        setupDrawIndexedVertices(&mesh[0].x);
         glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL);
 
         elementsCount -= drawCount;
@@ -1397,9 +1406,10 @@
         setupDrawBlending(true, SkXfermode::kClear_Mode);
         setupDrawProgram();
         setupDrawPureColorUniforms();
-        setupDrawModelViewTranslate(0.0f, 0.0f, 0.0f, 0.0f, true);
+        setupDrawModelView(kModelViewMode_Translate, false,
+                0.0f, 0.0f, 0.0f, 0.0f, true);
 
-        drawIndexedQuads(&mesh[0], count);
+        issueIndexedQuadDraw(&mesh[0], count);
 
         if (scissorChanged) mCaches.enableScissor();
     } else {
@@ -1620,8 +1630,18 @@
     return mSnapshot->getLocalClip();
 }
 
-bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom,
-        bool snapOut, bool* clipRequired) {
+/**
+ * Calculates whether content drawn within the passed bounds would be outside of, or intersect with
+ * the clipRect. Does not modify the scissor.
+ *
+ * @param clipRequired if not null, will be set to true if element intersects clip
+ *         (and wasn't rejected)
+ *
+ * @param snapOut if set, the geometry will be treated as having an AA ramp.
+ *         See Rect::snapGeometryToPixelBoundaries()
+ */
+bool OpenGLRenderer::calculateQuickRejectForScissor(float left, float top,
+        float right, float bottom, bool* clipRequired, bool snapOut) const {
     if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
         return true;
     }
@@ -1635,31 +1655,65 @@
 
     if (!clipRect.intersects(r)) return true;
 
+    // clip is required if geometry intersects clip rect
     if (clipRequired) *clipRequired = !clipRect.contains(r);
     return false;
 }
 
-bool OpenGLRenderer::quickRejectPreStroke(float left, float top, float right, float bottom,
-        SkPaint* paint) {
-    // AA geometry will likely have a ramp around it (not accounted for in local bounds). Snap out
-    // the final mapped rect to ensure correct clipping behavior for the ramp.
-    bool snapOut = paint->isAntiAlias();
-
-    if (paint->getStyle() != SkPaint::kFill_Style) {
-        float outset = paint->getStrokeWidth() * 0.5f;
-        return quickReject(left - outset, top - outset, right + outset, bottom + outset, snapOut);
-    } else {
-        return quickReject(left, top, right, bottom, snapOut);
+/**
+ * Returns false if drawing won't be clipped out.
+ *
+ * Makes the decision conservatively, by rounding out the mapped rect before comparing with the
+ * clipRect. To be used when perfect, pixel accuracy is not possible (esp. with tessellation) but
+ * rejection is still desired.
+ *
+ * This function, unlike quickRejectSetupScissor, should be used where precise geometry information
+ * isn't known (esp. when geometry adjusts based on scale). Generally, this will be first pass
+ * rejection where precise rejection isn't important, or precise information isn't available.
+ */
+bool OpenGLRenderer::quickRejectConservative(float left, float top,
+        float right, float bottom) const {
+    if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
+        return true;
     }
+
+    Rect r(left, top, right, bottom);
+    currentTransform().mapRect(r);
+    r.roundOut(); // rounded out to be conservative
+
+    Rect clipRect(*mSnapshot->clipRect);
+    clipRect.snapToPixelBoundaries();
+
+    if (!clipRect.intersects(r)) return true;
+
+    return false;
 }
 
-bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom, bool snapOut) {
+/**
+ * Returns false and sets scissor enable based upon bounds if drawing won't be clipped out.
+ *
+ * @param paint if not null, the bounds will be expanded to account for stroke depending on paint
+ *         style, and tessellated AA ramp
+ */
+bool OpenGLRenderer::quickRejectSetupScissor(float left, float top, float right, float bottom,
+        SkPaint* paint) {
     bool clipRequired = false;
-    if (quickRejectNoScissor(left, top, right, bottom, snapOut, &clipRequired)) {
+    bool snapOut = paint && paint->isAntiAlias();
+
+    if (paint && paint->getStyle() != SkPaint::kFill_Style) {
+        float outset = paint->getStrokeWidth() * 0.5f;
+        left -= outset;
+        top -= outset;
+        right += outset;
+        bottom += outset;
+    }
+
+    if (calculateQuickRejectForScissor(left, top, right, bottom, &clipRequired, snapOut)) {
         return true;
     }
 
     if (!isDeferred()) {
+        // not quick rejected, so enable the scissor if clipRequired
         mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired);
     }
     return false;
@@ -1734,7 +1788,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void OpenGLRenderer::setupDraw(bool clear) {
-    // TODO: It would be best if we could do this before quickReject()
+    // TODO: It would be best if we could do this before quickRejectSetupScissor()
     //       changes the scissor test state
     if (clear) clearLayerRegions();
     // Make sure setScissor & setStencil happen at the beginning of
@@ -1792,7 +1846,7 @@
     mColorG = mColorA * ((color >>  8) & 0xFF) / 255.0f;
     mColorB = mColorA * ((color      ) & 0xFF) / 255.0f;
     mColorSet = true;
-    mSetShaderColor = mDescription.setColor(mColorR, mColorG, mColorB, mColorA);
+    mSetShaderColor = mDescription.setColorModulate(mColorA);
 }
 
 void OpenGLRenderer::setupDrawAlpha8Color(int color, int alpha) {
@@ -1801,7 +1855,7 @@
     mColorG = mColorA * ((color >>  8) & 0xFF) / 255.0f;
     mColorB = mColorA * ((color      ) & 0xFF) / 255.0f;
     mColorSet = true;
-    mSetShaderColor = mDescription.setAlpha8Color(mColorR, mColorG, mColorB, mColorA);
+    mSetShaderColor = mDescription.setAlpha8ColorModulate(mColorR, mColorG, mColorB, mColorA);
 }
 
 void OpenGLRenderer::setupDrawTextGamma(const SkPaint* paint) {
@@ -1814,7 +1868,7 @@
     mColorG = g;
     mColorB = b;
     mColorSet = true;
-    mSetShaderColor = mDescription.setColor(r, g, b, a);
+    mSetShaderColor = mDescription.setColorModulate(a);
 }
 
 void OpenGLRenderer::setupDrawShader() {
@@ -1864,39 +1918,20 @@
     mTrackDirtyRegions = false;
 }
 
-void OpenGLRenderer::setupDrawModelViewTranslate(float left, float top, float right, float bottom,
-        bool ignoreTransform) {
+void OpenGLRenderer::setupDrawModelView(ModelViewMode mode, bool offset,
+        float left, float top, float right, float bottom, bool ignoreTransform) {
     mModelView.loadTranslate(left, top, 0.0f);
-    if (!ignoreTransform) {
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, currentTransform());
-        if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, currentTransform());
-    } else {
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, mat4::identity());
-        if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom);
-    }
-}
-
-void OpenGLRenderer::setupDrawModelViewIdentity(bool offset) {
-    mCaches.currentProgram->set(mOrthoMatrix, mat4::identity(), currentTransform(), offset);
-}
-
-void OpenGLRenderer::setupDrawModelView(float left, float top, float right, float bottom,
-        bool ignoreTransform, bool ignoreModelView) {
-    if (!ignoreModelView) {
-        mModelView.loadTranslate(left, top, 0.0f);
+    if (mode == kModelViewMode_TranslateAndScale) {
         mModelView.scale(right - left, bottom - top, 1.0f);
-    } else {
-        mModelView.loadIdentity();
     }
+
     bool dirty = right - left > 0.0f && bottom - top > 0.0f;
     if (!ignoreTransform) {
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, currentTransform());
-        if (mTrackDirtyRegions && dirty) {
-            dirtyLayer(left, top, right, bottom, currentTransform());
-        }
+        mCaches.currentProgram->set(mOrthoMatrix, mModelView, currentTransform(), offset);
+        if (dirty && mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, currentTransform());
     } else {
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, mat4::identity());
-        if (mTrackDirtyRegions && dirty) dirtyLayer(left, top, right, bottom);
+        mCaches.currentProgram->set(mOrthoMatrix, mModelView, mat4::identity(), offset);
+        if (dirty && mTrackDirtyRegions) dirtyLayer(left, top, right, bottom);
     }
 }
 
@@ -1915,20 +1950,19 @@
 void OpenGLRenderer::setupDrawShaderUniforms(bool ignoreTransform) {
     if (mDrawModifiers.mShader) {
         if (ignoreTransform) {
-            mModelView.loadInverse(currentTransform());
+            // if ignoreTransform=true was passed to setupDrawModelView, undo currentTransform()
+            // because it was built into modelView / the geometry, and the SkiaShader needs to
+            // compensate.
+            mat4 modelViewWithoutTransform;
+            modelViewWithoutTransform.loadInverse(currentTransform());
+            modelViewWithoutTransform.multiply(mModelView);
+            mModelView.load(modelViewWithoutTransform);
         }
         mDrawModifiers.mShader->setupProgram(mCaches.currentProgram,
                 mModelView, *mSnapshot, &mTextureUnit);
     }
 }
 
-void OpenGLRenderer::setupDrawShaderIdentityUniforms() {
-    if (mDrawModifiers.mShader) {
-        mDrawModifiers.mShader->setupProgram(mCaches.currentProgram,
-                mat4::identity(), *mSnapshot, &mTextureUnit);
-    }
-}
-
 void OpenGLRenderer::setupDrawColorFilterUniforms() {
     if (mDrawModifiers.mColorFilter) {
         mDrawModifiers.mColorFilter->setupProgram(mCaches.currentProgram);
@@ -2112,17 +2146,19 @@
 
     const float x = (int) floorf(bounds.left + 0.5f);
     const float y = (int) floorf(bounds.top + 0.5f);
-    if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
+    if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) {
         int color = paint != NULL ? paint->getColor() : 0;
         drawAlpha8TextureMesh(x, y, x + bounds.getWidth(), y + bounds.getHeight(),
                 texture->id, paint != NULL, color, alpha, mode,
-                &vertices[0].position[0], &vertices[0].texture[0],
-                GL_TRIANGLES, bitmapCount * 6, true, true, false);
+                &vertices[0].x, &vertices[0].u,
+                GL_TRIANGLES, bitmapCount * 6, true,
+                kModelViewMode_Translate, false);
     } else {
         drawTextureMesh(x, y, x + bounds.getWidth(), y + bounds.getHeight(),
                 texture->id, alpha / 255.0f, mode, texture->blend,
-                &vertices[0].position[0], &vertices[0].texture[0],
-                GL_TRIANGLES, bitmapCount * 6, false, true, 0, true, false);
+                &vertices[0].x, &vertices[0].u,
+                GL_TRIANGLES, bitmapCount * 6, false, true, 0,
+                kModelViewMode_Translate, false);
     }
 
     return DrawGlInfo::kStatusDrew;
@@ -2132,7 +2168,7 @@
     const float right = left + bitmap->width();
     const float bottom = top + bitmap->height();
 
-    if (quickReject(left, top, right, bottom)) {
+    if (quickRejectSetupScissor(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2141,7 +2177,7 @@
     if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
-    if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
+    if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) {
         drawAlphaBitmap(texture, left, top, paint);
     } else {
         drawTextureRect(left, top, right, bottom, texture, paint);
@@ -2155,7 +2191,7 @@
     const mat4 transform(*matrix);
     transform.mapRect(r);
 
-    if (quickReject(r.left, r.top, r.right, r.bottom)) {
+    if (quickRejectSetupScissor(r.left, r.top, r.right, r.bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2168,7 +2204,7 @@
     // to the vertex shader. The save/restore is a bit overkill.
     save(SkCanvas::kMatrix_SaveFlag);
     concatMatrix(matrix);
-    if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
+    if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) {
         drawAlphaBitmap(texture, 0.0f, 0.0f, paint);
     } else {
         drawTextureRect(0.0f, 0.0f, bitmap->width(), bitmap->height(), texture, paint);
@@ -2182,7 +2218,7 @@
     const float right = left + bitmap->width();
     const float bottom = top + bitmap->height();
 
-    if (quickReject(left, top, right, bottom)) {
+    if (quickRejectSetupScissor(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2190,7 +2226,7 @@
     Texture* texture = mCaches.textureCache.getTransient(bitmap);
     const AutoTexture autoCleanup(texture);
 
-    if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
+    if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) {
         drawAlphaBitmap(texture, left, top, paint);
     } else {
         drawTextureRect(left, top, right, bottom, texture, paint);
@@ -2265,7 +2301,7 @@
         }
     }
 
-    if (quickReject(left, top, right, bottom)) {
+    if (quickRejectSetupScissor(left, top, right, bottom)) {
         if (cleanupColors) delete[] colors;
         return DrawGlInfo::kStatusDone;
     }
@@ -2299,11 +2335,11 @@
     setupDrawBlending(true, mode, false);
     setupDrawProgram();
     setupDrawDirtyRegionsDisabled();
-    setupDrawModelView(0.0f, 0.0f, 1.0f, 1.0f, false);
+    setupDrawModelView(kModelViewMode_TranslateAndScale, false, 0.0f, 0.0f, 1.0f, 1.0f);
     setupDrawTexture(texture->id);
     setupDrawPureColorUniforms();
     setupDrawColorFilterUniforms();
-    setupDrawMesh(&mesh[0].position[0], &mesh[0].texture[0], &mesh[0].color[0]);
+    setupDrawMesh(&mesh[0].x, &mesh[0].u, &mesh[0].r);
 
     glDrawArrays(GL_TRIANGLES, 0, count);
 
@@ -2321,7 +2357,7 @@
          float srcLeft, float srcTop, float srcRight, float srcBottom,
          float dstLeft, float dstTop, float dstRight, float dstBottom,
          SkPaint* paint) {
-    if (quickReject(dstLeft, dstTop, dstRight, dstBottom)) {
+    if (quickRejectSetupScissor(dstLeft, dstTop, dstRight, dstBottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2387,16 +2423,16 @@
         dstBottom = srcBottom - srcTop;
     }
 
-    if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
+    if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) {
         int color = paint ? paint->getColor() : 0;
         drawAlpha8TextureMesh(dstLeft, dstTop, dstRight, dstBottom,
                 texture->id, paint != NULL, color, alpha, mode,
-                &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
+                &mMeshVertices[0].x, &mMeshVertices[0].u,
                 GL_TRIANGLE_STRIP, gMeshCount, ignoreTransform);
     } else {
         drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom,
                 texture->id, alpha / 255.0f, mode, texture->blend,
-                &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
+                &mMeshVertices[0].x, &mMeshVertices[0].u,
                 GL_TRIANGLE_STRIP, gMeshCount, false, ignoreTransform);
     }
 
@@ -2411,7 +2447,7 @@
 
 status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
         float left, float top, float right, float bottom, SkPaint* paint) {
-    if (quickReject(left, top, right, bottom)) {
+    if (quickRejectSetupScissor(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2424,7 +2460,7 @@
 
 status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
         float left, float top, float right, float bottom, SkPaint* paint) {
-    if (quickReject(left, top, right, bottom)) {
+    if (quickRejectSetupScissor(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2460,22 +2496,21 @@
             }
         }
 
+        bool ignoreTransform = false;
         if (CC_LIKELY(pureTranslate)) {
             const float x = (int) floorf(left + currentTransform().getTranslateX() + 0.5f);
             const float y = (int) floorf(top + currentTransform().getTranslateY() + 0.5f);
 
             right = x + right - left;
             bottom = y + bottom - top;
-            drawIndexedTextureMesh(x, y, right, bottom, texture->id, alpha / 255.0f,
-                    mode, texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset,
-                    GL_TRIANGLES, mesh->indexCount, false, true,
-                    mCaches.patchCache.getMeshBuffer(), true, !mesh->hasEmptyQuads);
-        } else {
-            drawIndexedTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f,
-                    mode, texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset,
-                    GL_TRIANGLES, mesh->indexCount, false, false,
-                    mCaches.patchCache.getMeshBuffer(), true, !mesh->hasEmptyQuads);
+            left = x;
+            top = y;
+            ignoreTransform = true;
         }
+        drawIndexedTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f,
+                mode, texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset,
+                GL_TRIANGLES, mesh->indexCount, false, ignoreTransform,
+                mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads);
     }
 
     return DrawGlInfo::kStatusDrew;
@@ -2501,14 +2536,16 @@
     getAlphaAndMode(paint, &alpha, &mode);
 
     drawIndexedTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, alpha / 255.0f,
-            mode, texture->blend, &vertices[0].position[0], &vertices[0].texture[0],
-            GL_TRIANGLES, indexCount, false, true, 0, true, false);
+            mode, texture->blend, &vertices[0].x, &vertices[0].u,
+            GL_TRIANGLES, indexCount, false, true, 0, kModelViewMode_Translate, false);
 
     return DrawGlInfo::kStatusDrew;
 }
 
 status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPaint* paint,
         bool useOffset) {
+    // not missing call to quickReject/dirtyLayer, always done at a higher level
+
     if (!vertexBuffer.getVertexCount()) {
         // no vertices to draw
         return DrawGlInfo::kStatusDone;
@@ -2526,10 +2563,10 @@
     setupDrawShader();
     setupDrawBlending(isAA, mode);
     setupDrawProgram();
-    setupDrawModelViewIdentity(useOffset);
+    setupDrawModelView(kModelViewMode_Translate, useOffset, 0, 0, 0, 0);
     setupDrawColorUniforms();
     setupDrawColorFilterUniforms();
-    setupDrawShaderIdentityUniforms();
+    setupDrawShaderUniforms();
 
     void* vertices = vertexBuffer.getBuffer();
     bool force = mCaches.unbindMeshBuffer();
@@ -2572,7 +2609,7 @@
 
     if (hasLayer()) {
         SkRect bounds = path.getBounds();
-        PathTessellator::expandBoundsForStroke(bounds, paint, false);
+        PathTessellator::expandBoundsForStroke(bounds, paint);
         dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, currentTransform());
     }
 
@@ -2599,7 +2636,8 @@
     SkRect bounds;
     PathTessellator::tessellateLines(points, count, paint, mSnapshot->transform, bounds, buffer);
 
-    if (quickReject(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) {
+    // can't pass paint, since style would be checked for outset. outset done by tessellation.
+    if (quickRejectSetupScissor(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2618,7 +2656,8 @@
     SkRect bounds;
     PathTessellator::tessellatePoints(points, count, paint, mSnapshot->transform, bounds, buffer);
 
-    if (quickReject(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) {
+    // can't pass paint, since style would be checked for outset. outset done by tessellation.
+    if (quickRejectSetupScissor(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2655,7 +2694,7 @@
 
 status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
         float rx, float ry, SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
+    if (mSnapshot->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2680,7 +2719,7 @@
 }
 
 status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectPreStroke(x - radius, y - radius,
+    if (mSnapshot->isIgnored() || quickRejectSetupScissor(x - radius, y - radius,
             x + radius, y + radius, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
@@ -2702,7 +2741,7 @@
 
 status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
         SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
+    if (mSnapshot->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2724,7 +2763,7 @@
 
 status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
         float startAngle, float sweepAngle, bool useCenter, SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
+    if (mSnapshot->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2761,7 +2800,7 @@
 #define SkPaintDefaults_MiterLimit SkIntToScalar(4)
 
 status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
+    if (mSnapshot->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2826,7 +2865,8 @@
     setupDrawShader();
     setupDrawBlending(true, mode);
     setupDrawProgram();
-    setupDrawModelView(sx, sy, sx + shadow->width, sy + shadow->height);
+    setupDrawModelView(kModelViewMode_TranslateAndScale, false,
+            sx, sy, sx + shadow->width, sy + shadow->height);
     setupDrawTexture(shadow->id);
     setupDrawPureColorUniforms();
     setupDrawColorFilterUniforms();
@@ -2924,7 +2964,7 @@
         // The checks for corner-case ignorable text and quick rejection is only done for immediate
         // drawing as ops from DeferredDisplayList are already filtered for these
         if (text == NULL || count == 0 || mSnapshot->isIgnored() || canSkipText(paint) ||
-                quickReject(bounds)) {
+                quickRejectSetupScissor(bounds)) {
             return DrawGlInfo::kStatusDone;
         }
     }
@@ -2998,7 +3038,7 @@
         dirtyLayerUnchecked(layerBounds, getRegion());
     }
 
-    drawTextDecorations(text, bytesCount, totalAdvance, oldX, oldY, paint);
+    drawTextDecorations(totalAdvance, oldX, oldY, paint);
 
     return DrawGlInfo::kStatusDrew;
 }
@@ -3069,8 +3109,8 @@
     }
 
     bool clipRequired = false;
-    const bool rejected = quickRejectNoScissor(x, y,
-            x + layer->layer.getWidth(), y + layer->layer.getHeight(), false, &clipRequired);
+    const bool rejected = calculateQuickRejectForScissor(x, y,
+            x + layer->layer.getWidth(), y + layer->layer.getHeight(), &clipRequired, false);
 
     if (rejected) {
         if (transform && !transform->isIdentity()) {
@@ -3107,11 +3147,11 @@
                 int ty = (int) floorf(y + currentTransform().getTranslateY() + 0.5f);
 
                 layer->setFilter(GL_NEAREST);
-                setupDrawModelViewTranslate(tx, ty,
+                setupDrawModelView(kModelViewMode_Translate, false, tx, ty,
                         tx + layer->layer.getWidth(), ty + layer->layer.getHeight(), true);
             } else {
                 layer->setFilter(GL_LINEAR);
-                setupDrawModelViewTranslate(x, y,
+                setupDrawModelView(kModelViewMode_Translate, false, x, y,
                         x + layer->layer.getWidth(), y + layer->layer.getHeight());
             }
 
@@ -3121,7 +3161,7 @@
             while (elementsCount > 0) {
                 GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6);
 
-                setupDrawMeshIndices(&mesh[0].position[0], &mesh[0].texture[0]);
+                setupDrawMeshIndices(&mesh[0].x, &mesh[0].u);
                 DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate,
                         glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL));
 
@@ -3132,7 +3172,7 @@
             }
 
 #if DEBUG_LAYERS_AS_REGIONS
-            drawRegionRects(layer->region);
+            drawRegionRectsDebug(layer->region);
 #endif
         }
 
@@ -3242,7 +3282,7 @@
 
 void OpenGLRenderer::drawPathTexture(const PathTexture* texture,
         float x, float y, SkPaint* paint) {
-    if (quickReject(x, y, x + texture->width, y + texture->height)) {
+    if (quickRejectSetupScissor(x, y, x + texture->width, y + texture->height)) {
         return;
     }
 
@@ -3257,7 +3297,8 @@
     setupDrawShader();
     setupDrawBlending(true, mode);
     setupDrawProgram();
-    setupDrawModelView(x, y, x + texture->width, y + texture->height);
+    setupDrawModelView(kModelViewMode_TranslateAndScale, false,
+            x, y, x + texture->width, y + texture->height);
     setupDrawTexture(texture->id);
     setupDrawPureColorUniforms();
     setupDrawColorFilterUniforms();
@@ -3272,8 +3313,7 @@
 #define kStdUnderline_Offset    (1.0f / 9.0f)
 #define kStdUnderline_Thickness (1.0f / 18.0f)
 
-void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float underlineWidth,
-        float x, float y, SkPaint* paint) {
+void OpenGLRenderer::drawTextDecorations(float underlineWidth, float x, float y, SkPaint* paint) {
     // Handle underline and strike-through
     uint32_t flags = paint->getFlags();
     if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) {
@@ -3363,7 +3403,7 @@
         bottom = fmaxf(bottom, b);
     }
 
-    if (clip && quickReject(left, top, right, bottom)) {
+    if (clip && quickRejectSetupScissor(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -3375,7 +3415,8 @@
     setupDrawBlending(mode);
     setupDrawProgram();
     setupDrawDirtyRegionsDisabled();
-    setupDrawModelView(0.0f, 0.0f, 1.0f, 1.0f, ignoreTransform, true);
+    setupDrawModelView(kModelViewMode_Translate, false,
+            0.0f, 0.0f, 0.0f, 0.0f, ignoreTransform);
     setupDrawColorUniforms();
     setupDrawShaderUniforms();
     setupDrawColorFilterUniforms();
@@ -3384,7 +3425,7 @@
         dirtyLayer(left, top, right, bottom, currentTransform());
     }
 
-    drawIndexedQuads(&mesh[0], count / 4);
+    issueIndexedQuadDraw(&mesh[0], count / 4);
 
     return DrawGlInfo::kStatusDrew;
 }
@@ -3403,7 +3444,8 @@
     setupDrawColorFilter();
     setupDrawBlending(mode);
     setupDrawProgram();
-    setupDrawModelView(left, top, right, bottom, ignoreTransform);
+    setupDrawModelView(kModelViewMode_TranslateAndScale, false,
+            left, top, right, bottom, ignoreTransform);
     setupDrawColorUniforms();
     setupDrawShaderUniforms(ignoreTransform);
     setupDrawColorFilterUniforms();
@@ -3424,8 +3466,8 @@
     GLvoid* texCoords = (GLvoid*) gMeshTextureOffset;
 
     if (texture->uvMapper) {
-        vertices = &mMeshVertices[0].position[0];
-        texCoords = &mMeshVertices[0].texture[0];
+        vertices = &mMeshVertices[0].x;
+        texCoords = &mMeshVertices[0].u;
 
         Rect uvs(0.0f, 0.0f, 1.0f, 1.0f);
         texture->uvMapper->map(uvs);
@@ -3461,7 +3503,8 @@
 void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float bottom,
         GLuint texture, float alpha, SkXfermode::Mode mode, bool blend,
         GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
-        bool swapSrcDst, bool ignoreTransform, GLuint vbo, bool ignoreScale, bool dirty) {
+        bool swapSrcDst, bool ignoreTransform, GLuint vbo,
+        ModelViewMode modelViewMode, bool dirty) {
 
     setupDraw();
     setupDrawWithTexture();
@@ -3470,11 +3513,7 @@
     setupDrawBlending(blend, mode, swapSrcDst);
     setupDrawProgram();
     if (!dirty) setupDrawDirtyRegionsDisabled();
-    if (!ignoreScale) {
-        setupDrawModelView(left, top, right, bottom, ignoreTransform);
-    } else {
-        setupDrawModelViewTranslate(left, top, right, bottom, ignoreTransform);
-    }
+    setupDrawModelView(modelViewMode, false, left, top, right, bottom, ignoreTransform);
     setupDrawTexture(texture);
     setupDrawPureColorUniforms();
     setupDrawColorFilterUniforms();
@@ -3486,7 +3525,8 @@
 void OpenGLRenderer::drawIndexedTextureMesh(float left, float top, float right, float bottom,
         GLuint texture, float alpha, SkXfermode::Mode mode, bool blend,
         GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
-        bool swapSrcDst, bool ignoreTransform, GLuint vbo, bool ignoreScale, bool dirty) {
+        bool swapSrcDst, bool ignoreTransform, GLuint vbo,
+        ModelViewMode modelViewMode, bool dirty) {
 
     setupDraw();
     setupDrawWithTexture();
@@ -3495,11 +3535,7 @@
     setupDrawBlending(blend, mode, swapSrcDst);
     setupDrawProgram();
     if (!dirty) setupDrawDirtyRegionsDisabled();
-    if (!ignoreScale) {
-        setupDrawModelView(left, top, right, bottom, ignoreTransform);
-    } else {
-        setupDrawModelViewTranslate(left, top, right, bottom, ignoreTransform);
-    }
+    setupDrawModelView(modelViewMode, false, left, top, right, bottom, ignoreTransform);
     setupDrawTexture(texture);
     setupDrawPureColorUniforms();
     setupDrawColorFilterUniforms();
@@ -3511,7 +3547,7 @@
 void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, float bottom,
         GLuint texture, bool hasColor, int color, int alpha, SkXfermode::Mode mode,
         GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
-        bool ignoreTransform, bool ignoreScale, bool dirty) {
+        bool ignoreTransform, ModelViewMode modelViewMode, bool dirty) {
 
     setupDraw();
     setupDrawWithTexture(true);
@@ -3523,15 +3559,11 @@
     setupDrawBlending(true, mode);
     setupDrawProgram();
     if (!dirty) setupDrawDirtyRegionsDisabled();
-    if (!ignoreScale) {
-        setupDrawModelView(left, top, right, bottom, ignoreTransform);
-    } else {
-        setupDrawModelViewTranslate(left, top, right, bottom, ignoreTransform);
-    }
+    setupDrawModelView(modelViewMode, false, left, top, right, bottom, ignoreTransform);
     setupDrawTexture(texture);
     setupDrawPureColorUniforms();
     setupDrawColorFilterUniforms();
-    setupDrawShaderUniforms();
+    setupDrawShaderUniforms(ignoreTransform);
     setupDrawMesh(vertices, texCoords);
 
     glDrawArrays(drawMode, 0, elementsCount);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 9afb7ad..cfc5931 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -98,6 +98,24 @@
     kClipSide_ConservativeFull = 0x1F
 };
 
+/**
+ * Defines additional transformation that should be applied by the model view matrix, beyond that of
+ * the currentTransform()
+ */
+enum ModelViewMode {
+    /**
+     * Used when the model view should simply translate geometry passed to the shader. The resulting
+     * matrix will be a simple translation.
+     */
+    kModelViewMode_Translate = 0,
+
+    /**
+     * Used when the model view should translate and scale geometry. The resulting matrix will be a
+     * translation + scale. This is frequently used together with VBO 0, the (0,0,1,1) rect.
+     */
+    kModelViewMode_TranslateAndScale = 1,
+};
+
 ///////////////////////////////////////////////////////////////////////////////
 // Renderer
 ///////////////////////////////////////////////////////////////////////////////
@@ -250,30 +268,8 @@
 
     ANDROID_API const Rect& getClipBounds();
 
-    /**
-     * Performs a quick reject but adjust the bounds to account for stroke width if necessary,
-     * and handling snapOut for AA geometry.
-     */
-    bool quickRejectPreStroke(float left, float top, float right, float bottom, SkPaint* paint);
-
-    /**
-     * Returns false and sets scissor based upon bounds if drawing won't be clipped out
-     */
-    bool quickReject(float left, float top, float right, float bottom, bool snapOut = false);
-    bool quickReject(const Rect& bounds) {
-        return quickReject(bounds.left, bounds.top, bounds.right, bounds.bottom);
-    }
-
-    /**
-     * Same as quickReject, without the scissor, instead returning clipRequired through pointer.
-     * clipRequired will be only set if not rejected
-     */
-    ANDROID_API bool quickRejectNoScissor(float left, float top, float right, float bottom,
-            bool snapOut = false, bool* clipRequired = NULL);
-    bool quickRejectNoScissor(const Rect& bounds, bool* clipRequired = NULL) {
-        return quickRejectNoScissor(bounds.left, bounds.top, bounds.right, bounds.bottom,
-                clipRequired);
-    }
+    ANDROID_API bool quickRejectConservative(float left, float top,
+            float right, float bottom) const;
 
     virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
     virtual bool clipPath(SkPath* path, SkRegion::Op op);
@@ -477,6 +473,16 @@
      */
     void attachStencilBufferToLayer(Layer* layer);
 
+    bool calculateQuickRejectForScissor(float left, float top, float right, float bottom,
+            bool* clipRequired, bool snapOut) const;
+
+    bool quickRejectSetupScissor(float left, float top, float right, float bottom,
+            SkPaint* paint = NULL);
+    bool quickRejectSetupScissor(const Rect& bounds, SkPaint* paint = NULL) {
+        return quickRejectSetupScissor(bounds.left, bounds.top,
+                bounds.right, bounds.bottom, paint);
+    }
+
     /**
      * Compose the layer defined in the current snapshot with the layer
      * defined by the previous snapshot.
@@ -654,12 +660,11 @@
      * @param alpha The translucency of the layer
      * @param mode The blending mode of the layer
      * @param flags The layer save flags
-     * @param previousFbo The name of the current framebuffer
      *
      * @return True if the layer was successfully created, false otherwise
      */
     bool createLayer(float left, float top, float right, float bottom,
-            int alpha, SkXfermode::Mode mode, int flags, GLuint previousFbo);
+            int alpha, SkXfermode::Mode mode, int flags);
 
     /**
      * Creates a new layer stored in the specified snapshot as an FBO.
@@ -667,9 +672,8 @@
      * @param layer The layer to store as an FBO
      * @param snapshot The snapshot associated with the new layer
      * @param bounds The bounds of the layer
-     * @param previousFbo The name of the current framebuffer
      */
-    bool createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLuint previousFbo);
+    bool createFboLayer(Layer* layer, Rect& bounds, Rect& clip);
 
     /**
      * Compose the specified layer as a region.
@@ -831,32 +835,33 @@
      * @param swapSrcDst Whether or not the src and dst blending operations should be swapped
      * @param ignoreTransform True if the current transform should be ignored
      * @param vbo The VBO used to draw the mesh
-     * @param ignoreScale True if the model view matrix should not be scaled
+     * @param modelViewMode Defines whether the model view matrix should be scaled
      * @param dirty True if calling this method should dirty the current layer
      */
     void drawTextureMesh(float left, float top, float right, float bottom, GLuint texture,
             float alpha, SkXfermode::Mode mode, bool blend,
             GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
             bool swapSrcDst = false, bool ignoreTransform = false, GLuint vbo = 0,
-            bool ignoreScale = false, bool dirty = true);
+            ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale, bool dirty = true);
 
     void drawIndexedTextureMesh(float left, float top, float right, float bottom, GLuint texture,
             float alpha, SkXfermode::Mode mode, bool blend,
             GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
             bool swapSrcDst = false, bool ignoreTransform = false, GLuint vbo = 0,
-            bool ignoreScale = false, bool dirty = true);
+            ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale, bool dirty = true);
 
     void drawAlpha8TextureMesh(float left, float top, float right, float bottom,
             GLuint texture, bool hasColor, int color, int alpha, SkXfermode::Mode mode,
             GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
-            bool ignoreTransform, bool ignoreScale = false, bool dirty = true);
+            bool ignoreTransform, ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale,
+            bool dirty = true);
 
     /**
      * Draws the specified list of vertices as quads using indexed GL_TRIANGLES.
      * If the number of vertices to draw exceeds the number of indices we have
      * pre-allocated, this method will generate several glDrawElements() calls.
      */
-    void drawIndexedQuads(Vertex* mesh, GLsizei quadsCount);
+    void issueIndexedQuadDraw(Vertex* mesh, GLsizei quadsCount);
 
     /**
      * Draws text underline and strike-through if needed.
@@ -868,8 +873,7 @@
      * @param y The y coordinate where the text will be drawn
      * @param paint The paint to draw the text with
      */
-    void drawTextDecorations(const char* text, int bytesCount, float totalAdvance,
-            float x, float y, SkPaint* paint);
+    void drawTextDecorations(float totalAdvance, float x, float y, SkPaint* paint);
 
    /**
      * Draws shadow layer on text (with optional positions).
@@ -978,14 +982,26 @@
             bool swapSrcDst = false);
     void setupDrawProgram();
     void setupDrawDirtyRegionsDisabled();
-    void setupDrawModelViewIdentity(bool offset = false);
-    void setupDrawModelView(float left, float top, float right, float bottom,
-            bool ignoreTransform = false, bool ignoreModelView = false);
-    void setupDrawModelViewTranslate(float left, float top, float right, float bottom,
-            bool ignoreTransform = false);
+
+    /**
+     * Setup the current program matrices based upon the nature of the geometry.
+     *
+     * @param mode If kModelViewMode_Translate, the geometry must be translated by the left and top
+     * parameters. If kModelViewMode_TranslateAndScale, the geometry that exists in the (0,0, 1,1)
+     * space must be scaled up and translated to fill the quad provided in (l,t,r,b). These
+     * transformations are stored in the modelView matrix and uploaded to the shader.
+     *
+     * @param offset Set to true if the the matrix should be fudged (translated) slightly to disambiguate
+     * geometry pixel positioning. See Vertex::gGeometryFudgeFactor.
+     *
+     * @param ignoreTransform Set to true if l,t,r,b coordinates already in layer space,
+     * currentTransform() will be ignored. (e.g. when drawing clip in layer coordinates to stencil,
+     * or when simple translation has been extracted)
+     */
+    void setupDrawModelView(ModelViewMode mode, bool offset,
+            float left, float top, float right, float bottom, bool ignoreTransform = false);
     void setupDrawColorUniforms();
     void setupDrawPureColorUniforms();
-    void setupDrawShaderIdentityUniforms();
     void setupDrawShaderUniforms(bool ignoreTransform = false);
     void setupDrawColorFilterUniforms();
     void setupDrawSimpleMesh();
@@ -1004,11 +1020,13 @@
     void updateLayers();
     void flushLayers();
 
+#if DEBUG_LAYERS_AS_REGIONS
     /**
      * Renders the specified region as a series of rectangles. This method
      * is used for debugging only.
      */
-    void drawRegionRects(const Region& region);
+    void drawRegionRectsDebug(const Region& region);
+#endif
 
     /**
      * Renders the specified region as a series of rectangles. The region
@@ -1055,7 +1073,20 @@
     // Matrix used for ortho projection in shaders
     mat4 mOrthoMatrix;
 
-    // Model-view matrix used to position/size objects
+    /**
+     * Model-view matrix used to position/size objects
+     *
+     * Stores operation-local modifications to the draw matrix that aren't incorporated into the
+     * currentTransform().
+     *
+     * If generated with kModelViewMode_Translate, the mModelView will reflect an x/y offset,
+     * e.g. the offset in drawLayer(). If generated with kModelViewMode_TranslateAndScale,
+     * mModelView will reflect a translation and scale, e.g. the translation and scale required to
+     * make VBO 0 (a rect of (0,0,1,1)) scaled to match the x,y offset, and width/height of a
+     * bitmap.
+     *
+     * Used as input to SkiaShader transformation.
+     */
     mat4 mModelView;
 
     // Number of saved states
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index 3970913..7e8a45b 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "PathTessellator"
+#define LOG_TAG "OpenGLRenderer"
 #define LOG_NDEBUG 1
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
@@ -24,11 +24,11 @@
 #define DEBUG_DUMP_ALPHA_BUFFER() \
     for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) { \
         ALOGD("point %d at %f %f, alpha %f", \
-        i, buffer[i].position[0], buffer[i].position[1], buffer[i].alpha); \
+        i, buffer[i].x, buffer[i].y, buffer[i].alpha); \
     }
 #define DEBUG_DUMP_BUFFER() \
     for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) { \
-        ALOGD("point %d at %f %f", i, buffer[i].position[0], buffer[i].position[1]); \
+        ALOGD("point %d at %f %f", i, buffer[i].x, buffer[i].y); \
     }
 #else
 #define DEBUG_DUMP_ALPHA_BUFFER()
@@ -57,9 +57,12 @@
 #define ROUND_CAP_THRESH 0.25f
 #define PI 3.1415926535897932f
 
-void PathTessellator::expandBoundsForStroke(SkRect& bounds, const SkPaint* paint,
-        bool forceExpand) {
-    if (forceExpand || paint->getStyle() != SkPaint::kFill_Style) {
+/**
+ * Note: this function doesn't account for the AA case with sub-pixel line thickness (not just 0 <
+ * width < 1.0, canvas scale factors in as well) so this can't be used for points/lines
+ */
+void PathTessellator::expandBoundsForStroke(SkRect& bounds, const SkPaint* paint) {
+    if (paint->getStyle() != SkPaint::kFill_Style) {
         float outset = paint->getStrokeWidth() * 0.5f;
         if (outset == 0) outset = 0.5f; // account for hairline
         bounds.outset(outset, outset);
@@ -67,11 +70,11 @@
 }
 
 inline static void copyVertex(Vertex* destPtr, const Vertex* srcPtr) {
-    Vertex::set(destPtr, srcPtr->position[0], srcPtr->position[1]);
+    Vertex::set(destPtr, srcPtr->x, srcPtr->y);
 }
 
 inline static void copyAlphaVertex(AlphaVertex* destPtr, const AlphaVertex* srcPtr) {
-    AlphaVertex::set(destPtr, srcPtr->position[0], srcPtr->position[1], srcPtr->alpha);
+    AlphaVertex::set(destPtr, srcPtr->x, srcPtr->y, srcPtr->alpha);
 }
 
 /**
@@ -159,6 +162,17 @@
         }
         return 0;
     }
+
+    /**
+     * Outset the bounds of point data (for line endpoints or points) to account for AA stroke
+     * geometry.
+     */
+    void expandBoundsForStrokeAA(SkRect& bounds) const {
+        float outset = halfStrokeWidth;
+        if (outset == 0) outset = 0.5f;
+        bounds.outset(outset * inverseScaleX + Vertex::gGeometryFudgeFactor,
+                outset * inverseScaleY + Vertex::gGeometryFudgeFactor);
+    }
 };
 
 void getFillVerticesFromPerimeter(const Vector<Vertex>& perimeter, VertexBuffer& vertexBuffer) {
@@ -192,25 +206,25 @@
     int currentIndex = 0;
     const Vertex* last = &(perimeter[perimeter.size() - 1]);
     const Vertex* current = &(perimeter[0]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-            last->position[0] - current->position[0]);
+    vec2 lastNormal(current->y - last->y,
+            last->x - current->x);
     lastNormal.normalize();
     for (unsigned int i = 0; i < perimeter.size(); i++) {
         const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
+        vec2 nextNormal(next->y - current->y,
+                current->x - next->x);
         nextNormal.normalize();
 
         vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
         paintInfo.scaleOffsetForStrokeWidth(totalOffset);
 
         Vertex::set(&buffer[currentIndex++],
-                current->position[0] + totalOffset.x,
-                current->position[1] + totalOffset.y);
+                current->x + totalOffset.x,
+                current->y + totalOffset.y);
 
         Vertex::set(&buffer[currentIndex++],
-                current->position[0] - totalOffset.x,
-                current->position[1] - totalOffset.y);
+                current->x - totalOffset.x,
+                current->y - totalOffset.y);
 
         last = current;
         current = next;
@@ -229,7 +243,7 @@
     vec2 strokeOffset = normal;
     paintInfo.scaleOffsetForStrokeWidth(strokeOffset);
 
-    vec2 referencePoint(center.position[0], center.position[1]);
+    vec2 referencePoint(center.x, center.y);
     if (paintInfo.cap == SkPaint::kSquare_Cap) {
         referencePoint += vec2(-strokeOffset.y, strokeOffset.x) * (begin ? -1 : 1);
     }
@@ -255,11 +269,11 @@
     if (extra > 0) {
         // tessellate both round caps
         float beginTheta = atan2(
-                    - (vertices[0].position[0] - vertices[1].position[0]),
-                    vertices[0].position[1] - vertices[1].position[1]);
+                    - (vertices[0].x - vertices[1].x),
+                    vertices[0].y - vertices[1].y);
         float endTheta = atan2(
-                    - (vertices[lastIndex].position[0] - vertices[lastIndex - 1].position[0]),
-                    vertices[lastIndex].position[1] - vertices[lastIndex - 1].position[1]);
+                    - (vertices[lastIndex].x - vertices[lastIndex - 1].x),
+                    vertices[lastIndex].y - vertices[lastIndex - 1].y);
         const float dTheta = PI / (extra + 1);
         const float radialScale = 2.0f / (1 + cos(dTheta));
 
@@ -275,37 +289,37 @@
             vec2 beginRadialOffset(cos(beginTheta), sin(beginTheta));
             paintInfo.scaleOffsetForStrokeWidth(beginRadialOffset);
             Vertex::set(&buffer[capOffset],
-                    vertices[0].position[0] + beginRadialOffset.x,
-                    vertices[0].position[1] + beginRadialOffset.y);
+                    vertices[0].x + beginRadialOffset.x,
+                    vertices[0].y + beginRadialOffset.y);
 
             endTheta += dTheta;
             vec2 endRadialOffset(cos(endTheta), sin(endTheta));
             paintInfo.scaleOffsetForStrokeWidth(endRadialOffset);
             Vertex::set(&buffer[allocSize - 1 - capOffset],
-                    vertices[lastIndex].position[0] + endRadialOffset.x,
-                    vertices[lastIndex].position[1] + endRadialOffset.y);
+                    vertices[lastIndex].x + endRadialOffset.x,
+                    vertices[lastIndex].y + endRadialOffset.y);
         }
     }
 
     int currentIndex = extra;
     const Vertex* last = &(vertices[0]);
     const Vertex* current = &(vertices[1]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-                last->position[0] - current->position[0]);
+    vec2 lastNormal(current->y - last->y,
+                last->x - current->x);
     lastNormal.normalize();
 
     storeBeginEnd(paintInfo, vertices[0], lastNormal, buffer, currentIndex, true);
 
     for (unsigned int i = 1; i < vertices.size() - 1; i++) {
         const Vertex* next = &(vertices[i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
+        vec2 nextNormal(next->y - current->y,
+                current->x - next->x);
         nextNormal.normalize();
 
         vec2 strokeOffset  = totalOffsetFromNormals(lastNormal, nextNormal);
         paintInfo.scaleOffsetForStrokeWidth(strokeOffset);
 
-        vec2 center(current->position[0], current->position[1]);
+        vec2 center(current->x, current->y);
         Vertex::set(&buffer[currentIndex++], center + strokeOffset);
         Vertex::set(&buffer[currentIndex++], center - strokeOffset);
 
@@ -329,7 +343,7 @@
  * 3 - zig zag back and forth inside the shape to fill it (using perimeter.size() vertices)
  */
 void getFillVerticesFromPerimeterAA(const PaintInfo& paintInfo, const Vector<Vertex>& perimeter,
-        VertexBuffer& vertexBuffer) {
+        VertexBuffer& vertexBuffer, float maxAlpha = 1.0f) {
     AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(perimeter.size() * 3 + 2);
 
     // generate alpha points - fill Alpha vertex gaps in between each point with
@@ -337,13 +351,13 @@
     int currentIndex = 0;
     const Vertex* last = &(perimeter[perimeter.size() - 1]);
     const Vertex* current = &(perimeter[0]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-            last->position[0] - current->position[0]);
+    vec2 lastNormal(current->y - last->y,
+            last->x - current->x);
     lastNormal.normalize();
     for (unsigned int i = 0; i < perimeter.size(); i++) {
         const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
+        vec2 nextNormal(next->y - current->y,
+                current->x - next->x);
         nextNormal.normalize();
 
         // AA point offset from original point is that point's normal, such that each side is offset
@@ -351,13 +365,13 @@
         vec2 totalOffset = paintInfo.deriveAAOffset(totalOffsetFromNormals(lastNormal, nextNormal));
 
         AlphaVertex::set(&buffer[currentIndex++],
-                current->position[0] + totalOffset.x,
-                current->position[1] + totalOffset.y,
+                current->x + totalOffset.x,
+                current->y + totalOffset.y,
                 0.0f);
         AlphaVertex::set(&buffer[currentIndex++],
-                current->position[0] - totalOffset.x,
-                current->position[1] - totalOffset.y,
-                1.0f);
+                current->x - totalOffset.x,
+                current->y - totalOffset.y,
+                maxAlpha);
 
         last = current;
         current = next;
@@ -416,7 +430,7 @@
 
     // determine referencePoint, the center point for the 4 primary cap vertices
     const Vertex* point = isFirst ? vertices.begin() : (vertices.end() - 1);
-    vec2 referencePoint(point->position[0], point->position[1]);
+    vec2 referencePoint(point->x, point->y);
     if (paintInfo.cap == SkPaint::kSquare_Cap) {
         // To account for square cap, move the primary cap vertices (that create the AA edge) by the
         // stroke offset vector (rotated to be parallel to the stroke)
@@ -576,8 +590,8 @@
 
     const Vertex* last = &(vertices[0]);
     const Vertex* current = &(vertices[1]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-            last->position[0] - current->position[0]);
+    vec2 lastNormal(current->y - last->y,
+            last->x - current->x);
     lastNormal.normalize();
 
     // TODO: use normal from bezier traversal for cap, instead of from vertices
@@ -585,8 +599,8 @@
 
     for (unsigned int i = 1; i < vertices.size() - 1; i++) {
         const Vertex* next = &(vertices[i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
+        vec2 nextNormal(next->y - current->y,
+                current->x - next->x);
         nextNormal.normalize();
 
         vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
@@ -598,30 +612,30 @@
         innerOffset -= AAOffset;
 
         AlphaVertex::set(&buffer[currentAAOuterIndex++],
-                current->position[0] + outerOffset.x,
-                current->position[1] + outerOffset.y,
+                current->x + outerOffset.x,
+                current->y + outerOffset.y,
                 0.0f);
         AlphaVertex::set(&buffer[currentAAOuterIndex++],
-                current->position[0] + innerOffset.x,
-                current->position[1] + innerOffset.y,
+                current->x + innerOffset.x,
+                current->y + innerOffset.y,
                 paintInfo.maxAlpha);
 
         AlphaVertex::set(&buffer[currentStrokeIndex++],
-                current->position[0] + innerOffset.x,
-                current->position[1] + innerOffset.y,
+                current->x + innerOffset.x,
+                current->y + innerOffset.y,
                 paintInfo.maxAlpha);
         AlphaVertex::set(&buffer[currentStrokeIndex++],
-                current->position[0] - innerOffset.x,
-                current->position[1] - innerOffset.y,
+                current->x - innerOffset.x,
+                current->y - innerOffset.y,
                 paintInfo.maxAlpha);
 
         AlphaVertex::set(&buffer[currentAAInnerIndex--],
-                current->position[0] - innerOffset.x,
-                current->position[1] - innerOffset.y,
+                current->x - innerOffset.x,
+                current->y - innerOffset.y,
                 paintInfo.maxAlpha);
         AlphaVertex::set(&buffer[currentAAInnerIndex--],
-                current->position[0] - outerOffset.x,
-                current->position[1] - outerOffset.y,
+                current->x - outerOffset.x,
+                current->y - outerOffset.y,
                 0.0f);
 
         current = next;
@@ -646,13 +660,13 @@
 
     const Vertex* last = &(perimeter[perimeter.size() - 1]);
     const Vertex* current = &(perimeter[0]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-            last->position[0] - current->position[0]);
+    vec2 lastNormal(current->y - last->y,
+            last->x - current->x);
     lastNormal.normalize();
     for (unsigned int i = 0; i < perimeter.size(); i++) {
         const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
+        vec2 nextNormal(next->y - current->y,
+                current->x - next->x);
         nextNormal.normalize();
 
         vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
@@ -664,30 +678,30 @@
         innerOffset -= AAOffset;
 
         AlphaVertex::set(&buffer[currentAAOuterIndex++],
-                current->position[0] + outerOffset.x,
-                current->position[1] + outerOffset.y,
+                current->x + outerOffset.x,
+                current->y + outerOffset.y,
                 0.0f);
         AlphaVertex::set(&buffer[currentAAOuterIndex++],
-                current->position[0] + innerOffset.x,
-                current->position[1] + innerOffset.y,
+                current->x + innerOffset.x,
+                current->y + innerOffset.y,
                 paintInfo.maxAlpha);
 
         AlphaVertex::set(&buffer[currentStrokeIndex++],
-                current->position[0] + innerOffset.x,
-                current->position[1] + innerOffset.y,
+                current->x + innerOffset.x,
+                current->y + innerOffset.y,
                 paintInfo.maxAlpha);
         AlphaVertex::set(&buffer[currentStrokeIndex++],
-                current->position[0] - innerOffset.x,
-                current->position[1] - innerOffset.y,
+                current->x - innerOffset.x,
+                current->y - innerOffset.y,
                 paintInfo.maxAlpha);
 
         AlphaVertex::set(&buffer[currentAAInnerIndex++],
-                current->position[0] - innerOffset.x,
-                current->position[1] - innerOffset.y,
+                current->x - innerOffset.x,
+                current->y - innerOffset.y,
                 paintInfo.maxAlpha);
         AlphaVertex::set(&buffer[currentAAInnerIndex++],
-                current->position[0] - outerOffset.x,
-                current->position[1] - outerOffset.y,
+                current->x - outerOffset.x,
+                current->y - outerOffset.y,
                 0.0f);
 
         last = current;
@@ -743,7 +757,7 @@
 #if VERTEX_DEBUG
     for (unsigned int i = 0; i < tempVertices.size(); i++) {
         ALOGD("orig path: point at %f %f",
-                tempVertices[i].position[0], tempVertices[i].position[1]);
+                tempVertices[i].x, tempVertices[i].y);
     }
 #endif
 
@@ -780,7 +794,7 @@
     rect.fBottom = fmaxf(rect.fBottom, y);
 }
 static void expandRectToCoverVertex(SkRect& rect, const Vertex& vertex) {
-    expandRectToCoverVertex(rect, vertex.position[0], vertex.position[1]);
+    expandRectToCoverVertex(rect, vertex.x, vertex.y);
 }
 
 template <class TYPE>
@@ -829,11 +843,14 @@
         getFillVerticesFromPerimeter(outlineVertices, tempBuffer);
         instanceVertices<Vertex>(tempBuffer, vertexBuffer, points, count, bounds);
     } else {
-        getFillVerticesFromPerimeterAA(paintInfo, outlineVertices, tempBuffer);
+        // note: pass maxAlpha directly, since we want fill to be alpha modulated
+        getFillVerticesFromPerimeterAA(paintInfo, outlineVertices, tempBuffer, paintInfo.maxAlpha);
         instanceVertices<AlphaVertex>(tempBuffer, vertexBuffer, points, count, bounds);
     }
 
-    expandBoundsForStroke(bounds, paint, true); // force-expand bounds to incorporate stroke
+    // expand bounds from vertex coords to pixel data
+    paintInfo.expandBoundsForStrokeAA(bounds);
+
 }
 
 void PathTessellator::tessellateLines(const float* points, int count, SkPaint* paint,
@@ -873,14 +890,15 @@
         expandRectToCoverVertex(bounds, tempVerticesData[1]);
     }
 
-    expandBoundsForStroke(bounds, paint, true); // force-expand bounds to incorporate stroke
-
     // since multiple objects tessellated into buffer, separate them with degen tris
     if (paintInfo.isAA) {
         vertexBuffer.createDegenerateSeparators<AlphaVertex>(lineAllocSize);
     } else {
         vertexBuffer.createDegenerateSeparators<Vertex>(lineAllocSize);
     }
+
+    // expand bounds from vertex coords to pixel data
+    paintInfo.expandBoundsForStrokeAA(bounds);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -939,8 +957,8 @@
     }
 
     int size = outputVertices.size();
-    if (size >= 2 && outputVertices[0].position[0] == outputVertices[size - 1].position[0] &&
-            outputVertices[0].position[1] == outputVertices[size - 1].position[1]) {
+    if (size >= 2 && outputVertices[0].x == outputVertices[size - 1].x &&
+            outputVertices[0].y == outputVertices[size - 1].y) {
         outputVertices.pop();
         return true;
     }
diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h
index 85797fc..e0044e8 100644
--- a/libs/hwui/PathTessellator.h
+++ b/libs/hwui/PathTessellator.h
@@ -102,7 +102,7 @@
 
 class PathTessellator {
 public:
-    static void expandBoundsForStroke(SkRect& bounds, const SkPaint* paint, bool forceExpand);
+    static void expandBoundsForStroke(SkRect& bounds, const SkPaint* paint);
 
     static void tessellatePath(const SkPath& path, const SkPaint* paint,
             const mat4 *transform, VertexBuffer& vertexBuffer);
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index 4f94afc..bc0f211 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -207,7 +207,7 @@
      * the fragment shader. When this method returns true, the program should
      * be provided with a modulation color.
      */
-    bool setColor(const float r, const float g, const float b, const float a) {
+    bool setColorModulate(const float a) {
         modulate = a < COLOR_COMPONENT_THRESHOLD;
         return modulate;
     }
@@ -217,7 +217,7 @@
      * the fragment shader. When this method returns true, the program should
      * be provided with a modulation color.
      */
-    bool setAlpha8Color(const float r, const float g, const float b, const float a) {
+    bool setAlpha8ColorModulate(const float r, const float g, const float b, const float a) {
         modulate = a < COLOR_COMPONENT_THRESHOLD || r > COLOR_COMPONENT_INV_THRESHOLD ||
                 g > COLOR_COMPONENT_INV_THRESHOLD || b > COLOR_COMPONENT_INV_THRESHOLD;
         return modulate;
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index dabd8d4..83b3436 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -213,6 +213,13 @@
         bottom = floorf(bottom + 0.5f);
     }
 
+    void roundOut() {
+        left = floorf(left);
+        top = floorf(top);
+        right = ceilf(right);
+        bottom = ceilf(bottom);
+    }
+
     void dump() const {
         ALOGD("Rect[l=%f t=%f r=%f b=%f]", left, top, right, bottom);
     }
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 797ed10..4f2a432 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -142,7 +142,7 @@
 }
 
 void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView,
-        const Snapshot& snapshot, GLuint* textureUnit) {
+        const Snapshot&, GLuint* textureUnit) {
     GLuint textureSlot = (*textureUnit)++;
     Caches::getInstance().activeTexture(textureSlot);
 
@@ -228,7 +228,7 @@
 }
 
 void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelView,
-        const Snapshot& snapshot, GLuint* textureUnit) {
+        const Snapshot&, GLuint* textureUnit) {
     if (CC_UNLIKELY(!mIsSimple)) {
         GLuint textureSlot = (*textureUnit)++;
         Caches::getInstance().activeTexture(textureSlot);
@@ -264,7 +264,7 @@
 SkiaCircularGradientShader::SkiaCircularGradientShader(float x, float y, float radius,
         uint32_t* colors, float* positions, int count, SkShader* key, SkShader::TileMode tileMode,
         SkMatrix* matrix, bool blend):
-        SkiaSweepGradientShader(kCircularGradient, x, y, colors, positions, count, key,
+        SkiaSweepGradientShader(kCircularGradient, colors, positions, count, key,
                 tileMode, matrix, blend) {
     SkMatrix unitMatrix;
     toCircularUnitMatrix(x, y, radius, &unitMatrix);
@@ -314,11 +314,12 @@
     mIsSimple = count == 2;
 }
 
-SkiaSweepGradientShader::SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors,
+SkiaSweepGradientShader::SkiaSweepGradientShader(Type type, uint32_t* colors,
         float* positions, int count, SkShader* key, SkShader::TileMode tileMode,
         SkMatrix* matrix, bool blend):
         SkiaShader(type, key, tileMode, tileMode, matrix, blend),
         mColors(colors), mPositions(positions), mCount(count) {
+    // protected method, that doesn't setup mUnitMatrix - should be handled by subclass
 
     mIsSimple = count == 2 && tileMode == SkShader::kClamp_TileMode;
 }
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index a63431c..9fc99a4 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -192,7 +192,7 @@
             GLuint* textureUnit);
 
 protected:
-    SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions,
+    SkiaSweepGradientShader(Type type, uint32_t* colors, float* positions,
             int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
     SkiaSweepGradientShader() {
     }
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index 0b2c130..6f27b36 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -147,7 +147,7 @@
 // Callbacks
 ///////////////////////////////////////////////////////////////////////////////
 
-void TextDropShadowCache::operator()(ShadowText& text, ShadowTexture*& texture) {
+void TextDropShadowCache::operator()(ShadowText&, ShadowTexture*& texture) {
     if (texture) {
         mSize -= texture->bitmapSize;
 
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index ed0a79a..1d4af7f 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -103,7 +103,7 @@
 // Callbacks
 ///////////////////////////////////////////////////////////////////////////////
 
-void TextureCache::operator()(SkBitmap*& bitmap, Texture*& texture) {
+void TextureCache::operator()(SkBitmap*&, Texture*& texture) {
     // This will be called already locked
     if (texture) {
         mSize -= texture->bitmapSize;
@@ -237,7 +237,7 @@
 
     Caches::getInstance().bindTexture(texture->id);
 
-    switch (bitmap->getConfig()) {
+    switch (bitmap->config()) {
     case SkBitmap::kA8_Config:
         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
         uploadToTexture(resize, GL_ALPHA, bitmap->rowBytesAsPixels(),
@@ -265,7 +265,7 @@
         texture->blend = !bitmap->isOpaque();
         break;
     default:
-        ALOGW("Unsupported bitmap config: %d", bitmap->getConfig());
+        ALOGW("Unsupported bitmap config: %d", bitmap->config());
         break;
     }
 
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index 790d4fc..351ce71 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -35,11 +35,11 @@
      */
     static const float gGeometryFudgeFactor = 0.0656f;
 
-    float position[2];
+    float x, y;
 
     static inline void set(Vertex* vertex, float x, float y) {
-        vertex[0].position[0] = x;
-        vertex[0].position[1] = y;
+        vertex[0].x = x;
+        vertex[0].y = y;
     }
 
     static inline void set(Vertex* vertex, vec2 val) {
@@ -47,7 +47,7 @@
     }
 
     static inline void copyWithOffset(Vertex* vertex, const Vertex& src, float x, float y) {
-        set(vertex, src.position[0] + x, src.position[1] + y);
+        set(vertex, src.x + x, src.y + y);
     }
 
 }; // struct Vertex
@@ -56,19 +56,19 @@
  * Simple structure to describe a vertex with a position and texture UV.
  */
 struct TextureVertex {
-    float position[2];
-    float texture[2];
+    float x, y;
+    float u, v;
 
     static inline void set(TextureVertex* vertex, float x, float y, float u, float v) {
-        vertex[0].position[0] = x;
-        vertex[0].position[1] = y;
-        vertex[0].texture[0] = u;
-        vertex[0].texture[1] = v;
+        vertex[0].x = x;
+        vertex[0].y = y;
+        vertex[0].u = u;
+        vertex[0].v = v;
     }
 
     static inline void setUV(TextureVertex* vertex, float u, float v) {
-        vertex[0].texture[0] = u;
-        vertex[0].texture[1] = v;
+        vertex[0].u = u;
+        vertex[0].v = v;
     }
 }; // struct TextureVertex
 
@@ -76,17 +76,17 @@
  * Simple structure to describe a vertex with a position, texture UV and ARGB color.
  */
 struct ColorTextureVertex : TextureVertex {
-    float color[4];
+    float r, g, b, a;
 
     static inline void set(ColorTextureVertex* vertex, float x, float y,
             float u, float v, int color) {
         TextureVertex::set(vertex, x, y, u, v);
 
         const float a = ((color >> 24) & 0xff) / 255.0f;
-        vertex[0].color[0] = a * ((color >> 16) & 0xff) / 255.0f;
-        vertex[0].color[1] = a * ((color >>  8) & 0xff) / 255.0f;
-        vertex[0].color[2] = a * ((color      ) & 0xff) / 255.0f;
-        vertex[0].color[3] = a;
+        vertex[0].r = a * ((color >> 16) & 0xff) / 255.0f;
+        vertex[0].g = a * ((color >>  8) & 0xff) / 255.0f;
+        vertex[0].b = a * ((color      ) & 0xff) / 255.0f;
+        vertex[0].a = a;
     }
 }; // struct ColorTextureVertex
 
@@ -103,7 +103,7 @@
 
     static inline void copyWithOffset(AlphaVertex* vertex, const AlphaVertex& src,
             float x, float y) {
-        Vertex::set(vertex, src.position[0] + x, src.position[1] + y);
+        Vertex::set(vertex, src.x + x, src.y + y);
         vertex[0].alpha = src.alpha;
     }
 
diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp
index d5f38b5..24ffb80 100644
--- a/libs/hwui/font/CacheTexture.cpp
+++ b/libs/hwui/font/CacheTexture.cpp
@@ -114,7 +114,7 @@
             mMesh(NULL), mCurrentQuad(0), mMaxQuadCount(maxQuadCount),
             mCaches(Caches::getInstance()) {
     mCacheBlocks = new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE,
-            mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE, true);
+            mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE);
 
     // OpenGL ES 3.0+ lets us specify the row length for unpack operations such
     // as glTexSubImage2D(). This allows us to upload a sub-rectangle of a texture.
@@ -143,7 +143,7 @@
     // reset, then create a new remainder space to start again
     reset();
     mCacheBlocks = new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE,
-            mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE, true);
+            mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE);
 }
 
 void CacheTexture::releaseMesh() {
diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h
index 61b38f8..4cc4f22 100644
--- a/libs/hwui/font/CacheTexture.h
+++ b/libs/hwui/font/CacheTexture.h
@@ -54,7 +54,7 @@
     CacheBlock* mNext;
     CacheBlock* mPrev;
 
-    CacheBlock(uint16_t x, uint16_t y, uint16_t width, uint16_t height, bool empty = false):
+    CacheBlock(uint16_t x, uint16_t y, uint16_t width, uint16_t height):
             mX(x), mY(y), mWidth(width), mHeight(height), mNext(NULL), mPrev(NULL) {
     }
 
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index 18983d8..3e0124c 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -23,6 +23,7 @@
 #include <utils/Trace.h>
 
 #include <SkGlyph.h>
+#include <SkGlyphCache.h>
 #include <SkUtils.h>
 
 #include "FontUtil.h"
@@ -271,8 +272,8 @@
     if (cachedGlyph) {
         // Is the glyph still in texture cache?
         if (!cachedGlyph->mIsValid) {
-            const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit,
-                    &mDescription.mLookupTransform);
+            SkAutoGlyphCache autoCache(*paint, NULL, &mDescription.mLookupTransform);
+            const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), textUnit);
             updateGlyphCache(paint, skiaGlyph, cachedGlyph, precaching);
         }
     } else {
@@ -428,8 +429,9 @@
     uint32_t startY = 0;
 
     // Get the bitmap for the glyph
+    SkAutoGlyphCache autoCache(*paint, NULL, &mDescription.mLookupTransform);
     if (!skiaGlyph.fImage) {
-        paint->findImage(skiaGlyph, &mDescription.mLookupTransform);
+        autoCache.getCache()->findImage(skiaGlyph);
     }
     mState->cacheBitmap(skiaGlyph, glyph, &startX, &startY, precaching);
 
@@ -463,7 +465,8 @@
     CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
     mCachedGlyphs.add(glyph, newGlyph);
 
-    const SkGlyph& skiaGlyph = GET_METRICS(paint, glyph, &mDescription.mLookupTransform);
+    SkAutoGlyphCache autoCache(*paint, NULL, &mDescription.mLookupTransform);
+    const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), glyph);
     newGlyph->mIsValid = false;
     newGlyph->mGlyphIndex = skiaGlyph.fID;
 
diff --git a/libs/hwui/font/FontUtil.h b/libs/hwui/font/FontUtil.h
index cdcb23c..c2fd5f5 100644
--- a/libs/hwui/font/FontUtil.h
+++ b/libs/hwui/font/FontUtil.h
@@ -40,7 +40,7 @@
 #if RENDER_TEXT_AS_GLYPHS
     typedef uint16_t glyph_t;
     #define TO_GLYPH(g) g
-    #define GET_METRICS(paint, glyph, matrix) paint->getGlyphMetrics(glyph, matrix)
+    #define GET_METRICS(cache, glyph) cache->getGlyphIDMetrics(glyph)
     #define GET_GLYPH(text) nextGlyph((const uint16_t**) &text)
     #define IS_END_OF_STRING(glyph) false
 
@@ -53,7 +53,7 @@
 #else
     typedef SkUnichar glyph_t;
     #define TO_GLYPH(g) ((SkUnichar) g)
-    #define GET_METRICS(paint, glyph, matrix) paint->getUnicharMetrics(glyph, matrix)
+    #define GET_METRICS(cache, glyph) cache->getUnicharMetrics(glyph)
     #define GET_GLYPH(text) SkUTF16_NextUnichar((const uint16_t**) &text)
     #define IS_END_OF_STRING(glyph) glyph < 0
 #endif
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 57e2786..b33ba00 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -25,7 +25,6 @@
 import android.content.Intent;
 import android.location.LocationManager;
 import android.os.Bundle;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
 
diff --git a/location/lib/java/com/android/location/provider/GeofenceProvider.java b/location/lib/java/com/android/location/provider/GeofenceProvider.java
index 2618f34..fafaa84 100644
--- a/location/lib/java/com/android/location/provider/GeofenceProvider.java
+++ b/location/lib/java/com/android/location/provider/GeofenceProvider.java
@@ -21,9 +21,6 @@
 import android.os.IBinder;
 
 import android.location.IGeofenceProvider;
-import android.util.Log;
-
-import java.lang.Long;
 
 /**
  * Base class for geofence providers implemented as unbundled services.
diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java
index 150c289..d717f40 100644
--- a/location/lib/java/com/android/location/provider/LocationProviderBase.java
+++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java
@@ -24,7 +24,6 @@
 import android.location.ILocationManager;
 import android.location.Location;
 import android.location.LocationManager;
-import android.location.LocationRequest;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
diff --git a/media/java/android/media/AmrInputStream.java b/media/java/android/media/AmrInputStream.java
index 8b7eee2..abee9e9 100644
--- a/media/java/android/media/AmrInputStream.java
+++ b/media/java/android/media/AmrInputStream.java
@@ -16,8 +16,6 @@
 
 package android.media;
 
-import android.util.Log;
-
 import java.io.InputStream;
 import java.io.IOException;
 
diff --git a/media/java/android/media/AsyncPlayer.java b/media/java/android/media/AsyncPlayer.java
index 804528e..14b199e 100644
--- a/media/java/android/media/AsyncPlayer.java
+++ b/media/java/android/media/AsyncPlayer.java
@@ -22,8 +22,6 @@
 import android.os.SystemClock;
 import android.util.Log;
 
-import java.io.IOException;
-import java.lang.IllegalStateException;
 import java.util.LinkedList;
 
 /**
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index d652cae..8ae06e0 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -26,7 +26,6 @@
 import android.content.Intent;
 import android.media.RemoteController.OnClientUpdateListener;
 import android.os.Binder;
-import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index f49ef2e..53afb6b 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -186,6 +186,9 @@
     //--------------------
     /**
      * Class constructor.
+     * Though some invalid parameters will result in an {@link IllegalArgumentException} exception,
+     * other errors do not.  Thus you should call {@link #getState()} immediately after construction
+     * to confirm that the object is usable.
      * @param audioSource the recording source. See {@link MediaRecorder.AudioSource} for
      *    recording source definitions.
      * @param sampleRateInHz the sample rate expressed in Hertz. 44100Hz is currently the only
@@ -239,7 +242,7 @@
 
 
     // Convenience method for the constructor's parameter checks.
-    // This is where constructor IllegalArgumentException-s are thrown
+    // This and audioBuffSizeCheck are where constructor IllegalArgumentException-s are thrown
     // postconditions:
     //    mRecordSource is valid
     //    mChannelCount is valid
@@ -247,7 +250,8 @@
     //    mAudioFormat is valid
     //    mSampleRate is valid
     private void audioParamCheck(int audioSource, int sampleRateInHz,
-                                 int channelConfig, int audioFormat) {
+                                 int channelConfig, int audioFormat)
+            throws IllegalArgumentException {
 
         //--------------
         // audio source
@@ -311,7 +315,7 @@
     //    mAudioFormat is AudioFormat.ENCODING_PCM_8BIT OR AudioFormat.ENCODING_PCM_16BIT
     // postcondition:
     //    mNativeBufferSizeInBytes is valid (multiple of frame size, positive)
-    private void audioBuffSizeCheck(int audioBufferSize) {
+    private void audioBuffSizeCheck(int audioBufferSize) throws IllegalArgumentException {
         // NB: this section is only valid with PCM data.
         // To update when supporting compressed formats
         int frameSizeInBytes = mChannelCount
@@ -800,7 +804,7 @@
     //--------------------
 
     private native final int native_setup(Object audiorecord_this,
-            int recordSource, int sampleRate, int nbChannels, int audioFormat,
+            int recordSource, int sampleRate, int channelMask, int audioFormat,
             int buffSizeInBytes, int[] sessionId);
 
     private native final void native_finalize();
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index b836f50..68ac15a 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -21,20 +21,17 @@
 import static android.media.AudioManager.RINGER_MODE_SILENT;
 import static android.media.AudioManager.RINGER_MODE_VIBRATE;
 
-import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.app.KeyguardManager;
 import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothProfile;
-import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -48,10 +45,8 @@
 import android.database.ContentObserver;
 import android.media.MediaPlayer.OnCompletionListener;
 import android.media.MediaPlayer.OnErrorListener;
-import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
@@ -66,9 +61,6 @@
 import android.os.Vibrator;
 import android.provider.Settings;
 import android.provider.Settings.System;
-import android.speech.RecognizerIntent;
-import android.telephony.PhoneStateListener;
-import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -88,13 +80,11 @@
 import java.util.ArrayList;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Set;
-import java.util.Stack;
 
 /**
  * The implementation of the volume manager service.
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 78a37c5..8756806 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1319,7 +1319,7 @@
     //--------------------
 
     private native final int native_setup(Object audiotrack_this,
-            int streamType, int sampleRate, int nbChannels, int audioFormat,
+            int streamType, int sampleRate, int channelMask, int audioFormat,
             int buffSizeInBytes, int mode, int[] sessionId);
 
     private native final void native_finalize();
diff --git a/media/java/android/media/EncoderCapabilities.java b/media/java/android/media/EncoderCapabilities.java
index 71cb1b3..332e360 100644
--- a/media/java/android/media/EncoderCapabilities.java
+++ b/media/java/android/media/EncoderCapabilities.java
@@ -18,7 +18,6 @@
 
 import java.util.List;
 import java.util.ArrayList;
-import android.util.Log;
 
 /**
  * The EncoderCapabilities class is used to retrieve the
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 23abce7..a346e17 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -21,7 +21,8 @@
 
 /**
  * <p>A single complete image buffer to use with a media source such as a
- * {@link MediaCodec}.</p>
+ * {@link MediaCodec} or a
+ * {@link android.hardware.camera2.CameraDevice CameraDevice}.</p>
  *
  * <p>This class allows for efficient direct application access to the pixel
  * data of the Image through one or more
@@ -82,6 +83,15 @@
      *     plane (4:2:0 subsampling). Each pixel sample in each plane has 8 bits.
      *     Each plane has its own row stride and pixel stride.</td>
      * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}</td>
+     *   <td>1</td>
+     *   <td>A single plane of raw sensor image data, with 16 bits per color
+     *     sample. The details of the layout need to be queried from the source of
+     *     the raw sensor data, such as
+     *     {@link android.hardware.camera2.CameraDevice CameraDevice}.
+     *   </td>
+     * </tr>
      * </table>
      *
      * @see android.graphics.ImageFormat
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index d454c42..1bd32c4 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -32,7 +32,8 @@
  * rendered into a {@link android.view.Surface}</p>
  *
  * <p>Several Android media API classes accept Surface objects as targets to
- * render to, including {@link MediaPlayer}, {@link MediaCodec}, and
+ * render to, including {@link MediaPlayer}, {@link MediaCodec},
+ * {@link android.hardware.camera2.CameraDevice}, and
  * {@link android.renderscript.Allocation RenderScript Allocations}. The image
  * sizes and formats that can be used with each source vary, and should be
  * checked in the documentation for the specific API.</p>
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 6b278d4..be408a1 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.media.MediaDrmException;
 import java.lang.ref.WeakReference;
 import java.util.UUID;
 import java.util.HashMap;
@@ -24,7 +23,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Bundle;
 import android.os.Parcel;
 import android.util.Log;
 
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 761ecca..526656a 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -16,17 +16,12 @@
 
 package android.media;
 
-import android.content.ContentValues;
-import android.provider.MediaStore.Audio;
-import android.provider.MediaStore.Images;
-import android.provider.MediaStore.Video;
 import android.media.DecoderCapabilities;
 import android.media.DecoderCapabilities.VideoDecoder;
 import android.media.DecoderCapabilities.AudioDecoder;
 import android.mtp.MtpConstants;
 
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 
diff --git a/media/java/android/media/MediaFocusControl.java b/media/java/android/media/MediaFocusControl.java
index 34008bb..25ab99d 100644
--- a/media/java/android/media/MediaFocusControl.java
+++ b/media/java/android/media/MediaFocusControl.java
@@ -51,7 +51,6 @@
 import android.util.Slog;
 import android.view.KeyEvent;
 
-import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Iterator;
diff --git a/media/java/android/media/MediaMetadataEditor.java b/media/java/android/media/MediaMetadataEditor.java
index 373ba11..3bfdb5a 100644
--- a/media/java/android/media/MediaMetadataEditor.java
+++ b/media/java/android/media/MediaMetadataEditor.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Bitmap;
 import android.os.Bundle;
-import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
 import android.util.SparseIntArray;
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 706258a..0e6e8b1 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -31,18 +31,15 @@
 import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.PowerManager;
 import android.util.Log;
 import android.view.Surface;
 import android.view.SurfaceHolder;
-import android.graphics.Bitmap;
 import android.graphics.SurfaceTexture;
 import android.media.AudioManager;
 import android.media.MediaFormat;
 import android.media.MediaTimeProvider;
-import android.media.MediaTimeProvider.OnMediaTimeListener;
 import android.media.SubtitleController;
 import android.media.SubtitleData;
 
diff --git a/media/java/android/media/Metadata.java b/media/java/android/media/Metadata.java
index b566653..eb543b4 100644
--- a/media/java/android/media/Metadata.java
+++ b/media/java/android/media/Metadata.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.graphics.Bitmap;
 import android.os.Parcel;
 import android.util.Log;
 
diff --git a/media/java/android/media/MiniThumbFile.java b/media/java/android/media/MiniThumbFile.java
index 63b149c..23c3652 100644
--- a/media/java/android/media/MiniThumbFile.java
+++ b/media/java/android/media/MiniThumbFile.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Environment;
 import android.util.Log;
diff --git a/media/java/android/media/Rating.java b/media/java/android/media/Rating.java
index 82c0392..b94db18 100644
--- a/media/java/android/media/Rating.java
+++ b/media/java/android/media/Rating.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.graphics.Bitmap;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 0c00aba..c2c61d3 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -24,13 +24,11 @@
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.RectF;
-import android.media.MediaMetadataRetriever;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index 6dbb3cd..cdeb4fe 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.Manifest;
 import android.app.ActivityManager;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
@@ -29,8 +28,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.util.DisplayMetrics;
 import android.util.Log;
diff --git a/media/java/android/media/ResampleInputStream.java b/media/java/android/media/ResampleInputStream.java
index b025e25..80919f7 100644
--- a/media/java/android/media/ResampleInputStream.java
+++ b/media/java/android/media/ResampleInputStream.java
@@ -16,8 +16,6 @@
 
 package android.media;
 
-import android.util.Log;
-
 import java.io.InputStream;
 import java.io.IOException;
 
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 8e4004b..e211b99 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -23,7 +23,6 @@
 import android.app.Activity;
 import android.content.ContentUris;
 import android.content.Context;
-import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Environment;
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index 06af5de..b0c077b 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -18,7 +18,6 @@
 
 import java.io.File;
 import java.io.FileDescriptor;
-import java.io.IOException;
 import java.lang.ref.WeakReference;
 
 import android.content.Context;
diff --git a/media/java/android/media/SubtitleData.java b/media/java/android/media/SubtitleData.java
index f552e82..3e6f6f9 100644
--- a/media/java/android/media/SubtitleData.java
+++ b/media/java/android/media/SubtitleData.java
@@ -17,7 +17,6 @@
 package android.media;
 
 import android.os.Parcel;
-import android.util.Log;
 
 /**
  * @hide
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index 756638c..daa5fa5 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -17,9 +17,6 @@
 package android.media;
 
 import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
@@ -29,15 +26,12 @@
 import android.media.MediaFile.MediaFileType;
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
-import android.provider.BaseColumns;
 import android.provider.MediaStore.Images;
-import android.provider.MediaStore.Images.Thumbnails;
 import android.util.Log;
 
 import java.io.FileInputStream;
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.io.OutputStream;
 
 /**
  * Thumbnail generation routines for media provider.
diff --git a/media/java/android/media/WebVttRenderer.java b/media/java/android/media/WebVttRenderer.java
index 4dec081..b09c5bd 100644
--- a/media/java/android/media/WebVttRenderer.java
+++ b/media/java/android/media/WebVttRenderer.java
@@ -1136,11 +1136,15 @@
     }
 
     public WebVttRenderingWidget(Context context, AttributeSet attrs) {
-        this(context, null, 0);
+        this(context, attrs, 0);
     }
 
-    public WebVttRenderingWidget(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public WebVttRenderingWidget(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public WebVttRenderingWidget(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         // Cannot render text over video when layer type is hardware.
         setLayerType(View.LAYER_TYPE_SOFTWARE, null);
diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java
index 1e1ef8c..3706884 100644
--- a/media/java/android/media/audiofx/AudioEffect.java
+++ b/media/java/android/media/audiofx/AudioEffect.java
@@ -22,7 +22,6 @@
 import android.os.Looper;
 import android.os.Message;
 import android.util.Log;
-import java.io.IOException;
 import java.lang.ref.WeakReference;
 import java.nio.ByteOrder;
 import java.nio.ByteBuffer;
diff --git a/media/java/android/media/audiofx/BassBoost.java b/media/java/android/media/audiofx/BassBoost.java
index 91459ed..a46cc22 100644
--- a/media/java/android/media/audiofx/BassBoost.java
+++ b/media/java/android/media/audiofx/BassBoost.java
@@ -16,16 +16,9 @@
 
 package android.media.audiofx;
 
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
 import android.media.audiofx.AudioEffect;
-import android.os.Bundle;
 import android.util.Log;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
 import java.util.StringTokenizer;
 
 
diff --git a/media/java/android/media/audiofx/EnvironmentalReverb.java b/media/java/android/media/audiofx/EnvironmentalReverb.java
index f1f582e..ef1c4c3 100644
--- a/media/java/android/media/audiofx/EnvironmentalReverb.java
+++ b/media/java/android/media/audiofx/EnvironmentalReverb.java
@@ -16,15 +16,7 @@
 
 package android.media.audiofx;
 
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
 import android.media.audiofx.AudioEffect;
-import android.os.Bundle;
-import android.util.Log;
-
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
 import java.util.StringTokenizer;
 
 /**
diff --git a/media/java/android/media/audiofx/Equalizer.java b/media/java/android/media/audiofx/Equalizer.java
index 7f38955..7abada0 100644
--- a/media/java/android/media/audiofx/Equalizer.java
+++ b/media/java/android/media/audiofx/Equalizer.java
@@ -16,16 +16,9 @@
 
 package android.media.audiofx;
 
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
 import android.media.audiofx.AudioEffect;
-import android.os.Bundle;
 import android.util.Log;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
 import java.util.StringTokenizer;
 
 
diff --git a/media/java/android/media/audiofx/PresetReverb.java b/media/java/android/media/audiofx/PresetReverb.java
index 7a89ae7..ef91667 100644
--- a/media/java/android/media/audiofx/PresetReverb.java
+++ b/media/java/android/media/audiofx/PresetReverb.java
@@ -16,15 +16,7 @@
 
 package android.media.audiofx;
 
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
 import android.media.audiofx.AudioEffect;
-import android.os.Bundle;
-import android.util.Log;
-
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
 import java.util.StringTokenizer;
 
 
diff --git a/media/java/android/media/audiofx/Virtualizer.java b/media/java/android/media/audiofx/Virtualizer.java
index 68a7b88..6b20006 100644
--- a/media/java/android/media/audiofx/Virtualizer.java
+++ b/media/java/android/media/audiofx/Virtualizer.java
@@ -16,16 +16,9 @@
 
 package android.media.audiofx;
 
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
 import android.media.audiofx.AudioEffect;
-import android.os.Bundle;
 import android.util.Log;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
 import java.util.StringTokenizer;
 
 
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index fb7f718..6bc3f09 100644
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -18,7 +18,6 @@
 
 import android.util.Log;
 import java.lang.ref.WeakReference;
-import java.io.IOException;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index f4fccbe..da68674 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -28,7 +28,6 @@
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Paint;
-import android.graphics.Rect;
 import android.graphics.Matrix;
 import android.media.videoeditor.VideoEditor.ExportProgressListener;
 import android.media.videoeditor.VideoEditor.PreviewProgressListener;
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index cf1238a..187500d 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -25,12 +25,10 @@
 import android.database.sqlite.SQLiteDatabase;
 import android.media.MediaScanner;
 import android.net.Uri;
-import android.os.Environment;
 import android.os.RemoteException;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Audio;
 import android.provider.MediaStore.Files;
-import android.provider.MediaStore.Images;
 import android.provider.MediaStore.MediaColumns;
 import android.util.Log;
 import android.view.Display;
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index 3272fed..926364f 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -18,8 +18,6 @@
 
 import android.hardware.usb.UsbDevice;
 import android.hardware.usb.UsbDeviceConnection;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
 
 /**
  * This class represents an MTP or PTP device connected on the USB host bus. An application can
diff --git a/media/java/android/mtp/MtpPropertyGroup.java b/media/java/android/mtp/MtpPropertyGroup.java
index 48da40f..781988d 100644
--- a/media/java/android/mtp/MtpPropertyGroup.java
+++ b/media/java/android/mtp/MtpPropertyGroup.java
@@ -20,7 +20,6 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.RemoteException;
-import android.provider.MediaStore;
 import android.provider.MediaStore.Audio;
 import android.provider.MediaStore.Files;
 import android.provider.MediaStore.Images;
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index d134667..4be9cd6 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -115,6 +115,7 @@
             nativeParcel->setData(obj->data(), obj->dataSize());
             env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
                     msg, ext1, ext2, jParcel);
+            env->DeleteLocalRef(jParcel);
         }
     } else {
         env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
diff --git a/media/lib/java/com/android/media/remotedisplay/RemoteDisplay.java b/media/lib/java/com/android/media/remotedisplay/RemoteDisplay.java
index 5e15702..c2461e6 100644
--- a/media/lib/java/com/android/media/remotedisplay/RemoteDisplay.java
+++ b/media/lib/java/com/android/media/remotedisplay/RemoteDisplay.java
@@ -18,7 +18,6 @@
 
 import com.android.internal.util.Objects;
 
-import android.media.MediaRouter;
 import android.media.RemoteDisplayState.RemoteDisplayInfo;
 import android.text.TextUtils;
 
diff --git a/media/mca/effect/java/android/media/effect/EffectContext.java b/media/mca/effect/java/android/media/effect/EffectContext.java
index ef03229..a11b9c4 100644
--- a/media/mca/effect/java/android/media/effect/EffectContext.java
+++ b/media/mca/effect/java/android/media/effect/EffectContext.java
@@ -19,10 +19,7 @@
 
 import android.filterfw.core.CachedFrameManager;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.FilterFactory;
 import android.filterfw.core.GLEnvironment;
-import android.filterfw.core.GLFrame;
-import android.filterfw.core.FrameManager;
 import android.opengl.GLES20;
 
 /**
diff --git a/media/mca/effect/java/android/media/effect/EffectFactory.java b/media/mca/effect/java/android/media/effect/EffectFactory.java
index 4330279..f6fcba7 100644
--- a/media/mca/effect/java/android/media/effect/EffectFactory.java
+++ b/media/mca/effect/java/android/media/effect/EffectFactory.java
@@ -18,7 +18,6 @@
 package android.media.effect;
 
 import java.lang.reflect.Constructor;
-import java.util.HashMap;
 
 /**
  * <p>The EffectFactory class defines the list of available Effects, and provides functionality to
diff --git a/media/mca/effect/java/android/media/effect/FilterEffect.java b/media/mca/effect/java/android/media/effect/FilterEffect.java
index d7c319e..34b3549 100644
--- a/media/mca/effect/java/android/media/effect/FilterEffect.java
+++ b/media/mca/effect/java/android/media/effect/FilterEffect.java
@@ -17,10 +17,7 @@
 
 package android.media.effect;
 
-import android.filterfw.core.CachedFrameManager;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.FilterFactory;
-import android.filterfw.core.GLEnvironment;
 import android.filterfw.core.GLFrame;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
diff --git a/media/mca/effect/java/android/media/effect/FilterGraphEffect.java b/media/mca/effect/java/android/media/effect/FilterGraphEffect.java
index b18bea8..80c695b 100644
--- a/media/mca/effect/java/android/media/effect/FilterGraphEffect.java
+++ b/media/mca/effect/java/android/media/effect/FilterGraphEffect.java
@@ -19,17 +19,13 @@
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterGraph;
 import android.filterfw.core.GraphRunner;
-import android.filterfw.core.SimpleScheduler;
 import android.filterfw.core.SyncRunner;
-import android.media.effect.Effect;
 import android.media.effect.FilterEffect;
 import android.media.effect.EffectContext;
 import android.filterfw.io.GraphIOException;
 import android.filterfw.io.GraphReader;
 import android.filterfw.io.TextGraphReader;
 
-import android.util.Log;
-
 /**
  * Effect subclass for effects based on a single Filter. Subclasses need only invoke the
  * constructor with the correct arguments to obtain an Effect implementation.
diff --git a/media/mca/effect/java/android/media/effect/SingleFilterEffect.java b/media/mca/effect/java/android/media/effect/SingleFilterEffect.java
index 6f85861..47900df 100644
--- a/media/mca/effect/java/android/media/effect/SingleFilterEffect.java
+++ b/media/mca/effect/java/android/media/effect/SingleFilterEffect.java
@@ -21,11 +21,8 @@
 import android.filterfw.core.FilterFactory;
 import android.filterfw.core.FilterFunction;
 import android.filterfw.core.Frame;
-import android.media.effect.Effect;
 import android.media.effect.EffectContext;
 
-import android.util.Log;
-
 /**
  * Effect subclass for effects based on a single Filter. Subclasses need only invoke the
  * constructor with the correct arguments to obtain an Effect implementation.
diff --git a/media/mca/effect/java/android/media/effect/SizeChangeEffect.java b/media/mca/effect/java/android/media/effect/SizeChangeEffect.java
index 4d27bae..1bf7d40 100644
--- a/media/mca/effect/java/android/media/effect/SizeChangeEffect.java
+++ b/media/mca/effect/java/android/media/effect/SizeChangeEffect.java
@@ -16,15 +16,9 @@
 
 package android.media.effect;
 
-import android.filterfw.core.Filter;
-import android.filterfw.core.FilterFactory;
-import android.filterfw.core.FilterFunction;
 import android.filterfw.core.Frame;
-import android.media.effect.Effect;
 import android.media.effect.EffectContext;
 
-import android.util.Log;
-
 /**
  * Effect subclass for effects based on a single Filter with output size differnet
  * from input.  Subclasses need only invoke the constructor with the correct arguments
diff --git a/media/mca/effect/java/android/media/effect/effects/CropEffect.java b/media/mca/effect/java/android/media/effect/effects/CropEffect.java
index 3e8d78a..7e1c495 100644
--- a/media/mca/effect/java/android/media/effect/effects/CropEffect.java
+++ b/media/mca/effect/java/android/media/effect/effects/CropEffect.java
@@ -19,7 +19,6 @@
 
 import android.media.effect.EffectContext;
 import android.media.effect.SizeChangeEffect;
-import android.media.effect.SingleFilterEffect;
 import android.filterpacks.imageproc.CropRectFilter;
 
 /**
diff --git a/media/mca/filterfw/java/android/filterfw/FilterFunctionEnvironment.java b/media/mca/filterfw/java/android/filterfw/FilterFunctionEnvironment.java
index 3f36d98..feaf6e8 100644
--- a/media/mca/filterfw/java/android/filterfw/FilterFunctionEnvironment.java
+++ b/media/mca/filterfw/java/android/filterfw/FilterFunctionEnvironment.java
@@ -20,7 +20,6 @@
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterFactory;
 import android.filterfw.core.FilterFunction;
-import android.filterfw.core.Frame;
 import android.filterfw.core.FrameManager;
 
 /**
diff --git a/media/mca/filterfw/java/android/filterfw/core/AsyncRunner.java b/media/mca/filterfw/java/android/filterfw/core/AsyncRunner.java
index 70cbad4..819774a 100644
--- a/media/mca/filterfw/java/android/filterfw/core/AsyncRunner.java
+++ b/media/mca/filterfw/java/android/filterfw/core/AsyncRunner.java
@@ -18,17 +18,9 @@
 package android.filterfw.core;
 
 import android.os.AsyncTask;
-import android.os.Handler;
 
 import android.util.Log;
 
-import java.lang.InterruptedException;
-import java.lang.Runnable;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.TimeUnit;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterfw/java/android/filterfw/core/Filter.java b/media/mca/filterfw/java/android/filterfw/core/Filter.java
index 73b009d..062b6ba 100644
--- a/media/mca/filterfw/java/android/filterfw/core/Filter.java
+++ b/media/mca/filterfw/java/android/filterfw/core/Filter.java
@@ -33,7 +33,6 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map.Entry;
-import java.util.LinkedList;
 import java.util.Set;
 
 /**
diff --git a/media/mca/filterfw/java/android/filterfw/core/Frame.java b/media/mca/filterfw/java/android/filterfw/core/Frame.java
index ef8c542..7dd0783 100644
--- a/media/mca/filterfw/java/android/filterfw/core/Frame.java
+++ b/media/mca/filterfw/java/android/filterfw/core/Frame.java
@@ -20,7 +20,6 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.FrameManager;
 import android.graphics.Bitmap;
-import android.util.Log;
 
 import java.nio.ByteBuffer;
 
diff --git a/media/mca/filterfw/java/android/filterfw/core/NativeFrame.java b/media/mca/filterfw/java/android/filterfw/core/NativeFrame.java
index bfd09ba..7d1553f 100644
--- a/media/mca/filterfw/java/android/filterfw/core/NativeFrame.java
+++ b/media/mca/filterfw/java/android/filterfw/core/NativeFrame.java
@@ -24,8 +24,6 @@
 import android.filterfw.core.NativeBuffer;
 import android.graphics.Bitmap;
 
-import android.util.Log;
-
 import java.nio.ByteBuffer;
 
 /**
diff --git a/media/mca/filterfw/java/android/filterfw/core/OneShotScheduler.java b/media/mca/filterfw/java/android/filterfw/core/OneShotScheduler.java
index dbc8d16..83c475f 100644
--- a/media/mca/filterfw/java/android/filterfw/core/OneShotScheduler.java
+++ b/media/mca/filterfw/java/android/filterfw/core/OneShotScheduler.java
@@ -18,7 +18,6 @@
 package android.filterfw.core;
 
 import android.filterfw.core.Filter;
-import android.filterfw.core.Scheduler;
 import android.filterfw.core.RoundRobinScheduler;
 import android.util.Log;
 
diff --git a/media/mca/filterfw/java/android/filterfw/core/SerializedFrame.java b/media/mca/filterfw/java/android/filterfw/core/SerializedFrame.java
index f493fd2..35ba04f 100644
--- a/media/mca/filterfw/java/android/filterfw/core/SerializedFrame.java
+++ b/media/mca/filterfw/java/android/filterfw/core/SerializedFrame.java
@@ -20,7 +20,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.FrameManager;
-import android.filterfw.core.NativeBuffer;
 import android.filterfw.format.ObjectFormat;
 import android.graphics.Bitmap;
 
@@ -28,10 +27,7 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-import java.io.OptionalDataException;
 import java.io.OutputStream;
-import java.io.StreamCorruptedException;
-import java.lang.reflect.Constructor;
 import java.nio.ByteBuffer;
 
 /**
diff --git a/media/mca/filterfw/java/android/filterfw/core/SimpleFrame.java b/media/mca/filterfw/java/android/filterfw/core/SimpleFrame.java
index 534a30d..7ddd1d4 100644
--- a/media/mca/filterfw/java/android/filterfw/core/SimpleFrame.java
+++ b/media/mca/filterfw/java/android/filterfw/core/SimpleFrame.java
@@ -20,11 +20,9 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.FrameManager;
-import android.filterfw.core.NativeBuffer;
 import android.filterfw.format.ObjectFormat;
 import android.graphics.Bitmap;
 
-import java.lang.reflect.Constructor;
 import java.nio.ByteBuffer;
 
 /**
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/CallbackFilter.java b/media/mca/filterpacks/java/android/filterpacks/base/CallbackFilter.java
index 4185343..4a47fa4 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/CallbackFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/CallbackFilter.java
@@ -20,13 +20,8 @@
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.os.Handler;
 import android.os.Looper;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/FrameBranch.java b/media/mca/filterpacks/java/android/filterpacks/base/FrameBranch.java
index 6b8cbc7..f909c3f 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/FrameBranch.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/FrameBranch.java
@@ -22,7 +22,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFinalPort;
-import android.filterfw.core.KeyValueMap;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/FrameFetch.java b/media/mca/filterpacks/java/android/filterpacks/base/FrameFetch.java
index 518b837..87d8f0b 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/FrameFetch.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/FrameFetch.java
@@ -24,8 +24,6 @@
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
 
-import android.util.Log;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/FrameStore.java b/media/mca/filterpacks/java/android/filterpacks/base/FrameStore.java
index 3aadaac..05ac50d 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/FrameStore.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/FrameStore.java
@@ -20,7 +20,6 @@
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 
 /**
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/GLTextureSource.java b/media/mca/filterpacks/java/android/filterpacks/base/GLTextureSource.java
index 1776820..af61d9a 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/GLTextureSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/GLTextureSource.java
@@ -23,11 +23,8 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.format.ImageFormat;
 
-import java.util.Set;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/GLTextureTarget.java b/media/mca/filterpacks/java/android/filterpacks/base/GLTextureTarget.java
index b2285cd..91bb417 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/GLTextureTarget.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/GLTextureTarget.java
@@ -23,11 +23,8 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.format.ImageFormat;
 
-import java.util.Set;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/InputStreamSource.java b/media/mca/filterpacks/java/android/filterpacks/base/InputStreamSource.java
index 6c22ee7..0ef9055 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/InputStreamSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/InputStreamSource.java
@@ -23,7 +23,6 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.format.PrimitiveFormat;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/NullFilter.java b/media/mca/filterpacks/java/android/filterpacks/base/NullFilter.java
index f3e08e4..73434d4 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/NullFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/NullFilter.java
@@ -19,8 +19,6 @@
 
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/ObjectSource.java b/media/mca/filterpacks/java/android/filterpacks/base/ObjectSource.java
index d511e44..78e2b50 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/ObjectSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/ObjectSource.java
@@ -17,15 +17,12 @@
 
 package android.filterpacks.base;
 
-import java.util.Set;
-
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
-import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.format.ObjectFormat;
 
 /**
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/OutputStreamTarget.java b/media/mca/filterpacks/java/android/filterpacks/base/OutputStreamTarget.java
index 3d3d0f1..fd65a9d 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/OutputStreamTarget.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/OutputStreamTarget.java
@@ -20,7 +20,6 @@
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 
 import java.io.OutputStream;
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/RetargetFilter.java b/media/mca/filterpacks/java/android/filterpacks/base/RetargetFilter.java
index 254167a..0e988820 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/RetargetFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/RetargetFilter.java
@@ -21,9 +21,7 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 
 /**
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/AlphaBlendFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/AlphaBlendFilter.java
index 473369c..c3cc282 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/AlphaBlendFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/AlphaBlendFilter.java
@@ -17,18 +17,9 @@
 
 package android.filterpacks.imageproc;
 
-import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
-import android.filterfw.format.ImageFormat;
-
-import java.util.Set;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/AutoFixFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/AutoFixFilter.java
index c71c1c94..ac83db2 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/AutoFixFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/AutoFixFilter.java
@@ -21,13 +21,10 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.NativeProgram;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 public class AutoFixFilter extends Filter {
 
     @GenerateFieldPort(name = "tile_size", hasDefault = true)
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapOverlayFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapOverlayFilter.java
index e4bb6cf..92b177c 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapOverlayFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapOverlayFilter.java
@@ -21,17 +21,11 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
-import android.filterpacks.imageproc.ImageCombineFilter;
 import android.graphics.Bitmap;
 
-import android.util.Log;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapSource.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapSource.java
index 978fc94..89e8723 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapSource.java
@@ -17,17 +17,11 @@
 
 package android.filterpacks.imageproc;
 
-import android.content.Context;
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
-import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.format.ImageFormat;
 import android.graphics.Bitmap;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java
index 20b02d2..38221b4 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BlendFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BlendFilter.java
index 29bc8a3..aff5e9e 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BlendFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BlendFilter.java
@@ -16,18 +16,9 @@
 
 package android.filterpacks.imageproc;
 
-import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
-import android.filterfw.format.ImageFormat;
-
-import java.util.Set;
 
 /**
  * The filter linearly blends "left" and "right" frames. The blending weight is
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BrightnessFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BrightnessFilter.java
index 046e69d..bc62e19 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BrightnessFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BrightnessFilter.java
@@ -17,13 +17,8 @@
 
 package android.filterpacks.imageproc;
 
-import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ColorTemperatureFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ColorTemperatureFilter.java
index 7488980..1d408be 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ColorTemperatureFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ColorTemperatureFilter.java
@@ -21,13 +21,9 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
-import android.util.Log;
 
 public class ColorTemperatureFilter extends Filter {
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ContrastFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ContrastFilter.java
index 70e987f..7043c72 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ContrastFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ContrastFilter.java
@@ -17,18 +17,11 @@
 
 package android.filterpacks.imageproc;
 
-import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 
-import java.util.Set;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/CropFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/CropFilter.java
index 5222d9c..0ef323c 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/CropFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/CropFilter.java
@@ -22,19 +22,13 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
-import android.filterfw.geometry.Point;
 import android.filterfw.geometry.Quad;
 import android.filterfw.format.ImageFormat;
 import android.filterfw.format.ObjectFormat;
 
-import android.util.Log;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/CropRectFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/CropRectFilter.java
index d423d06..010ee21 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/CropRectFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/CropRectFilter.java
@@ -21,14 +21,9 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
-import android.util.Log;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/CrossProcessFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/CrossProcessFilter.java
index e0514f8..d565e65 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/CrossProcessFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/CrossProcessFilter.java
@@ -21,15 +21,10 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 public class CrossProcessFilter extends Filter {
 
     @GenerateFieldPort(name = "tile_size", hasDefault = true)
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java
index f93a82c..72745c0 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawOverlayFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawOverlayFilter.java
index 3f1711e..d10a6ef 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawOverlayFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawOverlayFilter.java
@@ -21,17 +21,11 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.GLFrame;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.geometry.Quad;
 import android.filterfw.format.ImageFormat;
 import android.filterfw.format.ObjectFormat;
 
-import android.opengl.GLES20;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawRectFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawRectFilter.java
index 83c9348..b288e6e 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawRectFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawRectFilter.java
@@ -23,9 +23,6 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.geometry.Quad;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/DuotoneFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/DuotoneFilter.java
index d8c88ee..ef82ee9 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/DuotoneFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/DuotoneFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/FillLightFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/FillLightFilter.java
index fc917a1..c7fb55d 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/FillLightFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/FillLightFilter.java
@@ -21,10 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.GenerateFinalPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/FisheyeFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/FisheyeFilter.java
index 5d7929f..2ff6588 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/FisheyeFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/FisheyeFilter.java
@@ -22,17 +22,11 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 import java.lang.Math;
-import java.util.Set;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/FixedRotationFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/FixedRotationFilter.java
index 3d319ea..340f308 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/FixedRotationFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/FixedRotationFilter.java
@@ -22,7 +22,6 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.filterfw.geometry.Point;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/FlipFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/FlipFilter.java
index f8b857b..68c760f 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/FlipFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/FlipFilter.java
@@ -21,10 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/GrainFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/GrainFilter.java
index 577243a..528eaa2 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/GrainFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/GrainFilter.java
@@ -21,14 +21,9 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
-import android.filterfw.geometry.Quad;
-import android.filterfw.geometry.Point;
 
 import java.util.Date;
 import java.util.Random;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageCombineFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageCombineFilter.java
index 858489b..c9a6956 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageCombineFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageCombineFilter.java
@@ -21,16 +21,10 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
-import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
 import java.lang.reflect.Field;
-import java.util.HashSet;
-import java.util.Set;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageEncoder.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageEncoder.java
index a5405cb..e8bf482 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageEncoder.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageEncoder.java
@@ -17,21 +17,16 @@
 
 package android.filterpacks.imageproc;
 
-import android.content.Context;
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.format.ImageFormat;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
 
-import android.util.Log;
-
 import java.io.OutputStream;
-import java.io.IOException;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageSlicer.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageSlicer.java
index b996eb8..8bf80b2 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageSlicer.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageSlicer.java
@@ -20,9 +20,7 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageStitcher.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageStitcher.java
index 20aba91..5e3d15b 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageStitcher.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageStitcher.java
@@ -20,16 +20,12 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 public class ImageStitcher extends Filter {
 
     @GenerateFieldPort(name = "xSlices")
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/Invert.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/Invert.java
index 400fd5d..881e30f 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/Invert.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/Invert.java
@@ -17,12 +17,8 @@
 
 package android.filterpacks.imageproc;
 
-import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
 import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java
index 726ffff..4e53f92 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/NegativeFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/NegativeFilter.java
index 440d6a6..f66fc23 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/NegativeFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/NegativeFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/PosterizeFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/PosterizeFilter.java
index bc2e553..864d7e2 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/PosterizeFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/PosterizeFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java
index 8618804..48b2fdf 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
@@ -31,8 +28,6 @@
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
-import android.graphics.PointF;
-import android.util.Log;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ResizeFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ResizeFilter.java
index 411e061..c79c11b 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ResizeFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ResizeFilter.java
@@ -23,10 +23,7 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/RotateFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/RotateFilter.java
index 3da7939..43d8d6c 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/RotateFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/RotateFilter.java
@@ -22,16 +22,11 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.filterfw.geometry.Quad;
 import android.filterfw.geometry.Point;
-import android.util.Log;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/SaturateFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/SaturateFilter.java
index b83af39..757fac1 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/SaturateFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/SaturateFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/SepiaFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/SepiaFilter.java
index 7a83fdf..a9f4e2c 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/SepiaFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/SepiaFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/SharpenFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/SharpenFilter.java
index 256b769..a290996 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/SharpenFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/SharpenFilter.java
@@ -21,15 +21,10 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import java.util.Set;
-
 public class SharpenFilter extends Filter {
 
     @GenerateFieldPort(name = "scale", hasDefault = true)
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/SimpleImageFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/SimpleImageFilter.java
index f4fc271e..afe92de 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/SimpleImageFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/SimpleImageFilter.java
@@ -21,16 +21,10 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
-import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
 import java.lang.reflect.Field;
-import java.util.HashSet;
-import java.util.Set;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/StraightenFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/StraightenFilter.java
index c9f097d..9db296b 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/StraightenFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/StraightenFilter.java
@@ -22,16 +22,11 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.filterfw.geometry.Quad;
 import android.filterfw.geometry.Point;
-import android.util.Log;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/TintFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/TintFilter.java
index 0da54a5..2b140ba 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/TintFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/TintFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToGrayFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToGrayFilter.java
index 00e7bf4..760ce3a 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToGrayFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToGrayFilter.java
@@ -17,23 +17,14 @@
 
 package android.filterpacks.imageproc;
 
-import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
-import java.lang.reflect.Field;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToPackedGrayFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToPackedGrayFilter.java
index bc4a65e..3c121d0 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToPackedGrayFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToPackedGrayFilter.java
@@ -27,8 +27,6 @@
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 import java.lang.Math;
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBAFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBAFilter.java
index ab4814f..f0084fa 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBAFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBAFilter.java
@@ -21,16 +21,11 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
-import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBFilter.java
index 9258502..bbb0fc3 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBFilter.java
@@ -21,16 +21,11 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
-import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/VignetteFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/VignetteFilter.java
index 715fec6..249cc6f 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/VignetteFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/VignetteFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/text/StringSource.java b/media/mca/filterpacks/java/android/filterpacks/text/StringSource.java
index cc33b89..2fe519f 100644
--- a/media/mca/filterpacks/java/android/filterpacks/text/StringSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/text/StringSource.java
@@ -22,8 +22,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.format.ObjectFormat;
 
 /**
diff --git a/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceRenderFilter.java b/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceRenderFilter.java
index a5c1ccb..ba88736 100644
--- a/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceRenderFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceRenderFilter.java
@@ -26,19 +26,11 @@
 import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLEnvironment;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.view.Surface;
 import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-import android.graphics.Rect;
 
 import android.util.Log;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceTargetFilter.java b/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceTargetFilter.java
index 308d168..05cb81b 100644
--- a/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceTargetFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceTargetFilter.java
@@ -25,19 +25,11 @@
 import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLEnvironment;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
 import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-import android.graphics.Rect;
 
 import android.util.Log;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/videoproc/BackDropperFilter.java b/media/mca/filterpacks/java/android/filterpacks/videoproc/BackDropperFilter.java
index 78f7f3e..a31ac2c 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videoproc/BackDropperFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videoproc/BackDropperFilter.java
@@ -24,7 +24,6 @@
 import android.filterfw.core.GLFrame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.opengl.GLES20;
@@ -32,7 +31,6 @@
 import android.os.SystemProperties;
 import android.util.Log;
 
-import java.lang.ArrayIndexOutOfBoundsException;
 import java.lang.Math;
 import java.util.Arrays;
 import java.nio.ByteBuffer;
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosink/MediaEncoderFilter.java b/media/mca/filterpacks/java/android/filterpacks/videosink/MediaEncoderFilter.java
index 8bb653b..d034051 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosink/MediaEncoderFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosink/MediaEncoderFilter.java
@@ -17,32 +17,23 @@
 
 package android.filterpacks.videosink;
 
-import android.content.Context;
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.filterfw.geometry.Point;
 import android.filterfw.geometry.Quad;
-import android.os.ConditionVariable;
 import android.media.MediaRecorder;
 import android.media.CamcorderProfile;
 import android.filterfw.core.GLEnvironment;
 
 import java.io.IOException;
 import java.io.FileDescriptor;
-import java.util.List;
-import java.util.Set;
 
 import android.util.Log;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosink/MediaRecorderStopException.java b/media/mca/filterpacks/java/android/filterpacks/videosink/MediaRecorderStopException.java
index dbf9768..ce7a8c1 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosink/MediaRecorderStopException.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosink/MediaRecorderStopException.java
@@ -18,7 +18,6 @@
 package android.filterpacks.videosink;
 
 import java.lang.RuntimeException;
-import android.util.Log;
 
 /** @hide **/
 public class MediaRecorderStopException extends RuntimeException {
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosrc/CameraSource.java b/media/mca/filterpacks/java/android/filterpacks/videosrc/CameraSource.java
index 2c474ab..d260684 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosrc/CameraSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosrc/CameraSource.java
@@ -17,29 +17,22 @@
 
 package android.filterpacks.videosrc;
 
-import android.content.Context;
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.graphics.SurfaceTexture;
 import android.hardware.Camera;
-import android.os.ConditionVariable;
 import android.opengl.Matrix;
 
 import java.io.IOException;
 import java.util.List;
-import java.util.Set;
 
 import android.util.Log;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosrc/MediaSource.java b/media/mca/filterpacks/java/android/filterpacks/videosrc/MediaSource.java
index 0be6c62..53a39a7 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosrc/MediaSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosrc/MediaSource.java
@@ -23,28 +23,20 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.graphics.SurfaceTexture;
 import android.media.MediaPlayer;
 import android.net.Uri;
-import android.os.ConditionVariable;
 import android.opengl.Matrix;
 import android.view.Surface;
 
 import java.io.IOException;
-import java.io.FileDescriptor;
 import java.lang.IllegalArgumentException;
-import java.util.List;
-import java.util.Set;
 
 import android.util.Log;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java
index 37fa242..6595baa 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java
@@ -16,31 +16,20 @@
 
 package android.filterpacks.videosrc;
 
-import android.content.Context;
-import android.content.res.AssetFileDescriptor;
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.graphics.SurfaceTexture;
-import android.media.MediaPlayer;
 import android.os.ConditionVariable;
 import android.opengl.Matrix;
 
-import java.io.IOException;
-import java.io.FileDescriptor;
-import java.lang.IllegalArgumentException;
-import java.util.List;
-import java.util.Set;
-
 import android.util.Log;
 
 /** <p>A filter that converts textures from a SurfaceTexture object into frames for
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureTarget.java b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureTarget.java
index b6d9f94..5d03627 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureTarget.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureTarget.java
@@ -19,29 +19,19 @@
 
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.FilterSurfaceView;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLEnvironment;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
 import android.filterfw.geometry.Quad;
 import android.filterfw.geometry.Point;
 
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
 
 import android.util.Log;
diff --git a/packages/BackupRestoreConfirmation/res/values-az-rAZ/strings.xml b/packages/BackupRestoreConfirmation/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..1f9e6aa
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-az-rAZ/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="backup_confirm_title" msgid="827563724209303345">"Tam yedəkləmə"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Tam bərpa"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Bütün datanın qoşulmuş masaüstü kompüterə rezerv olunması sorğusu göndərilib. Buna icazə vermək istəyirsiniz mi?\n\nƏgər bu sorğunu göndərməmisinizsə, bu prosesin davam etməsinə icazə verməyin."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Məlumatlarımı yedəklə"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Rezerv etməyin"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Qoşulmuş stolüstü kompüterdən tam bərpa tələb olunur. Buna icazə verilsin?\n\nBərpanı siz özünüz tələb etməmisinizsə, bu əməliyyatı davam etdirməyin. Bu cihazdakı istənilən məlumatı dəyişdirəcək."</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Məlumatlarımı bərpa et"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Bərpa etməyin"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Lütfən, aşağıda cari yedək parolunuzu daxil edin:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Lütfən, aşağıda cihaz şifrələmə parolunu daxil edin."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Lütfən, aşağıda cihaz şifrələmə parolunuzu daxil edin. Bu yedək arxivini şifrələmək üçün də istifadə olunacaq."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Tam yedək data şifrələmədən istifadə üçün şifrə daxil edin. Əgər boş buraxılsa, cari yedək şifrə istifadə olunacaq:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Bütün yedək datanı şifrələmək istəyirsinizsə, aşağıda parol daxil edin:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Bərpa məlumatları şifrələnibsə, şifrəni aşağıda daxil edin:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Rezerv edilir ..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Yedəkləmə sona çatdı"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Bərpa başlayır..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Bərpa sona çatdı"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"Əməliyyat vaxtı bitdi"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-az/strings.xml b/packages/BackupRestoreConfirmation/res/values-az/strings.xml
new file mode 100644
index 0000000..1f9e6aa
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-az/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="backup_confirm_title" msgid="827563724209303345">"Tam yedəkləmə"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Tam bərpa"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Bütün datanın qoşulmuş masaüstü kompüterə rezerv olunması sorğusu göndərilib. Buna icazə vermək istəyirsiniz mi?\n\nƏgər bu sorğunu göndərməmisinizsə, bu prosesin davam etməsinə icazə verməyin."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Məlumatlarımı yedəklə"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Rezerv etməyin"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Qoşulmuş stolüstü kompüterdən tam bərpa tələb olunur. Buna icazə verilsin?\n\nBərpanı siz özünüz tələb etməmisinizsə, bu əməliyyatı davam etdirməyin. Bu cihazdakı istənilən məlumatı dəyişdirəcək."</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Məlumatlarımı bərpa et"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Bərpa etməyin"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Lütfən, aşağıda cari yedək parolunuzu daxil edin:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Lütfən, aşağıda cihaz şifrələmə parolunu daxil edin."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Lütfən, aşağıda cihaz şifrələmə parolunuzu daxil edin. Bu yedək arxivini şifrələmək üçün də istifadə olunacaq."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Tam yedək data şifrələmədən istifadə üçün şifrə daxil edin. Əgər boş buraxılsa, cari yedək şifrə istifadə olunacaq:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Bütün yedək datanı şifrələmək istəyirsinizsə, aşağıda parol daxil edin:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Bərpa məlumatları şifrələnibsə, şifrəni aşağıda daxil edin:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Rezerv edilir ..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Yedəkləmə sona çatdı"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Bərpa başlayır..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Bərpa sona çatdı"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"Əməliyyat vaxtı bitdi"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-hy/strings.xml b/packages/BackupRestoreConfirmation/res/values-hy/strings.xml
new file mode 100644
index 0000000..4db9080
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-hy/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="backup_confirm_title" msgid="827563724209303345">"Ամբողջական պահուստավորում"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Ամբողջական վերականգնում"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Կապակցված աշխատասեղանով համակարգչի վրա բոլոր տվյալների լրիվ պահուստավորման հարցում է արվել: Ցանկանու՞մ եք թույլատրել հարցման կատարումը:\n\nԵթե դուք ինքներդ պահուստավորման հարցում չեք արել, թույլ մի տվեք, որպեսզի գործողությունը շարունակվի:"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Պահուստավորել իմ տվյալները"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Չպահուստավորել"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Հայցվել է բոլոր տվյալների ամբողջական վերականգնում միացված աշխատանքային համակարգչից: Ցանկանու՞մ եք թույլատրել, որ դա տեղի ունենա:\n\nԵթե վերականգնումը ինքներդ չեք հայցել, թուjլ մի տվեք, որ գործողությունը շարունակվի: Դա կփոխարինի ներկայում հեռախոսի մեջ գտնվող ցանկացած տվյալ:"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Վերականգնել իմ տվյալները"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Չվերականգնել"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Խնդրում ենք մուտքագրել ձեր ընթացիկ պահուստային գաղտնաբառը ներքևում`"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Խնդրում ենք մուտքագրել ձեր սարքի կոդավորված գաղտնաբառը ներքևում:"</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Խնդրում ենք մուտքագրել ձեր սարքի կոդավորված գաղտնաբառը ներքևում: Այն նաև կօգտագործվի պահուստային արխիվի կոդավորման համար:"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Խնդրում ենք մուտքագրել գաղտնաբառը` ամբողջական պահուստավորվող տվյալները կոդավորելու համար: Եթե ​​այն դատարկ թողնեք, ապա կօգտագործվի ձեր առկա պահուստավորման գաղտնաբառը`"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Եթե ​​ցանկանում եք կոդավորել ամբողջական պահուստավորված տվյալները, մուտքագրեք գաղտնաբառ ստորև`"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Եթե ​​վերականգնվող տվյալները կոդավորված են, խնդրում ենք մուտքագրել գաղտնաբառը ստորև`"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Պահուստավորումը սկսվում է..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Պահուստավորումն ավարտվեց"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Վերականգնումը մեկնարկեց..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Վերականգնումն ավարտվեց"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"Գործողության ժամանակը սպառվեց"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-ka/strings.xml b/packages/BackupRestoreConfirmation/res/values-ka/strings.xml
new file mode 100644
index 0000000..49b72e1b
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-ka/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="backup_confirm_title" msgid="827563724209303345">"სრული დამარქაფება"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"სრულად აღდგენა"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"მოთხოვნილ იქნა სამაგიდო კომპიუტერთან დაკავშირებული ყველა მონაცემის სრულყოფილი სარეზერვო ასლები. \n\nთუ სარეზერვო ასლები თქვენ არ მოგითხოვიათ, არ დაუშვათ ამ ოპერაციის გაგრძელება."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"ჩემი მონაცემების დამარქაფება"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"სარეზერვო ასლები არ გააკეთო"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"დაკავშირებული დესკტოპ კომპიუტერიდან მოხდა ყველა მონაცემის სრული აღდგენის მოთხოვნა. გსურთ, დაუშვათ ეს?\n\nთუ თქვენ თვითონ არ მოითხოვეთ აღდგენა, არ დაუშვათ ამ ოპერაციის გაგრძელება. ის ჩაანაცვლებს მოწყობილობაზე ამჟამად არსებულ ნებისმიერ მონაცემს!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"ჩემი მონაცემების აღდგენა"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"არ აღადგინო"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"გთხოვთ, ქვემოთ მიუთითოთ თქვენი ამჟამინდელი სათადარიგო პაროლი:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"გთხოვთ, ქვემოთ მიუთითოთ თქვენი მოწყობილობის დაშიფვრის პაროლი."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"გთხოვთ, ქვემოთ მიუთითოთ თქვენი მოწყობილობის დაშიფვრის პაროლი. ეს ასევე გამოყენებული იქნება სათადარიგო არქივის დაშიფრვისათვის."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"გთხოვთ შეიყვანოთ ყველა სამარქაფო ასლის დაშიფრვის პაროლი. თუ ამ ველს ცარიელს დატოვებთ, გამოყენებული იქნება მიმდინარე პაროლი:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"თუ გსურთ მთელი დამარქაფებული მონაცემების დაშიფრვა, შეიყვანეთ პაროლი ქვემოთ:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"თუ აღსადგენი მონაცემები დაშიფრულია, გთხოვთ, შეიყვანოთ პაროლი ქვემოთ:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"ასლების მომზადება იწყება..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"დამარქაფება დასრულდა"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"აღდგენა იწყება..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"აღდგენა დასრულდა"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"ოპერაციის დროის ლიმიტი ამოიწურა"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-km/strings.xml b/packages/BackupRestoreConfirmation/res/values-km/strings.xml
new file mode 100644
index 0000000..956fdd7
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-km/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="backup_confirm_title" msgid="827563724209303345">"ការ​បម្រុង​ទុក​ពេញលេញ"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"ស្ដារ​ឡើងវិញ​ពេញលេញ"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"ការ​បម្រុងទុក​ទិន្នន័យ​ទាំងអស់​ពេញលេញ​​ទៅ​កុំព្យូទ័រ​ដែល​បាន​ភ្ជាប់​ត្រូវ​បាន​ស្នើ។ តើ​អ្នក​ចង់ឲ្យ​វា​កើត​ឡើង​ដែរ​ឬទេ??\n\nបើ​អ្នក​មិន​បាន​ស្នើ​ការ​បម្រុងទុក​ដោយ​ខ្លួន​អ្នក​ផ្ទាល់​ទេ កុំ​អនុញ្ញាត​ប្រតិបត្តិការ​នេះ។"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"បម្រុង​ទុក​ទិន្នន័យ​របស់​ខ្ញុំ"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"កុំ​បម្រុង​ទុក"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"ការ​ស្ដារ​ទិន្នន័យ​ទាំងអស់​ពេញលេញ​ពី​កុំព្យូទ័រ​ដែល​បាន​តភ្ជាប់​ត្រូវ​បាន​ស្នើ។ តើ​អ្នក​ចង់​អនុញ្ញាត​ដែរ​ឬទេ?\n\n បើ​អ្នក​មិន​បាន​ស្នើ​ការ​ស្ដារ​ខ្លួន​ឯង​ទេ កុំ​អនុញ្ញាត។ វា​នឹង​ជំនួស​ទិន្នន័យ​ណាមួយ​ដែល​មាន​លើ​ឧបករណ៍!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"ស្ដារ​ទិន្នន័យ​របស់​ខ្ញុំ"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"កុំ​ស្ដារ​ឡើងវិញ"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"សូម​បញ្ចូល​ពាក្យ​សម្ងាត់​បម្រុង​ទុក​បច្ចុប្បន្ន​របស់​អ្នក​ខាង​ក្រោម៖"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"សូម​បញ្ចូល​ពាក្យ​សម្ងាត់​ដាក់​លេខ​កូដ​​ឧបករណ៍​របស់​​អ្នក​ខាង​ក្រោម។"</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"សូម​បញ្ចូល​ពាក្យ​សម្ងាត់​ដាក់​លេខ​កូដ​ឧបករណ៍​របស់​អ្នក​ខាង​ក្រោម។ វា​នឹង​ត្រូវ​បាន​ប្រើ ដើម្បី​ដាក់​លេខ​កូដ​ប័ណ្ណសារ​បម្រុងទុក​ផង​ដែរ។"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"សូម​បញ្ចូល​ពាក្យ​សម្ងាត់​ដើម្បី​ប្រើ​សម្រាប់​ដាក់លេខ​កូដ​ទិន្នន័យ​បម្រុងទុក​ពេញលេញ។ បើ​ទុក​វា​ទទេ ពាក្យ​សម្ងាត់​បម្រុងទុក​បច្ចុប្បន្ន​របស់​អ្នក​នឹង​ត្រូវ​បាន​ប្រើ៖"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"បើ​អ្នក​ចង់​ដាក់​លេខ​កូដ​ទិន្នន័យ​បម្រុងទុក​ពេញលេញ បញ្ចូល​ពាក្យ​សម្ងាត់​ខាង​ក្រោម៖"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"បើ​​ទិន្នន័យ​ស្ដារ​ត្រូវ​បាន​ដាក់​លេខ​កូដ សូម​បញ្ចូល​ពាក្យ​សម្ងាត់​ខាង​ក្រោម៖"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"កំពុង​ចាប់ផ្ដើម​បម្រុងទុក..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"ការ​​បម្រុង​ទុក​បាន​បញ្ចប់"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"ការ​ស្ដារ​កំពុង​ចាប់ផ្ដើម..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"ការ​ស្តា​រ​បាន​បញ្ចប់"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"ប្រតិបត្តិការ​អស់​ពេល"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-lo/strings.xml b/packages/BackupRestoreConfirmation/res/values-lo/strings.xml
new file mode 100644
index 0000000..fb28502
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-lo/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="backup_confirm_title" msgid="827563724209303345">"ສຳຮອງຂໍ້ມູນເຕັມຮູບແບບ"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"ກູ້ຂໍ້ມູນເຕັມຮູບແບບ"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"ມີການຮ້ອງຂໍໃຫ້ສຳຮອງຂໍ້ມູນທັງໝົດ ໄປໃສ່ຄອມພິວເຕີຕັ້ງໂຕະທີ່ເຊື່ອມຕໍ່ຢູ່. ທ່ານຈະອະນຸມັດໃຫ້ດຳເນີນການຫຼືບໍ່?\n\nຫາກທ່ານບໍ່ໄດ້ຮ້ອງຂໍໃຫ້ສຳຮອງຂໍ້ມູນດ້ວຍຕົນເອງ, ກະລຸນາຢ່າອະນຸຍາດໃຫ້ດຳເນີນການຕໍ່ໄປ."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"ສຳຮອງຂໍ້ມູນຂອງຂ້ອຍ"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"ບໍ່ໃຫ້ສຳຮອງຂໍ້ມູນ"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"ການກູ້ຂໍ້ມູນທັງໝົດຈາກຄອມພິວເຕີທີ່ເຊື່ອມຕໍ່ຢູ່ນັ້ນຖືກຮ້ອງຂໍແລ້ວ. ທ່ານຕ້ອງການອະນຸຍາດໃຫ້ການກະທຳນີ້ເກີດຂຶ້ນບໍ່?\n\nຫາກທ່ານບໍ່ໄດ້ເຮັດການຮ້ອງຂໍ້ການກູ້ຂໍ້ມູນດ້ວຍໂຕທ່ານເອງ, ທ່ານບໍ່ຄວນອະນຸຍາດໃຫ້ມີການດຳເນີນການໃດໆ ເນື່ອງຈາກມັນຈະໄປຂຽນທັບຂໍ້ມູນທັງໝົດທີ່ຢູ່ໃນອຸປະກອນ!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"ກູ້ຄືນຂໍ້ມູນຂອງຂ້ອຍ"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"ບໍ່ໃຫ້ກູ້ຄືນ"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"ກະລຸນາປ້ອນລະຫັດຜ່ານການສຳຮອງຂໍ້ມູນທີ່ທ່ານໃຊ້ຢູ່ໃສ່ດ້ານລຸ່ມ:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"ກະລຸນາປ້ອນລະຫັດຜ່ານການເຂົ້າລະຫັດອຸປະກອນຂອງທ່ານໃສ່ດ້ານລຸ່ມ."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"ກະລຸນາປ້ອນລະຫັດຜ່ານການເຂົ້າລະຫັດອຸປະກອນຂອງທ່ານໃສ່ດ້ານລຸ່ມ. ລະຫັດນີ້ຍັງຈະໃຊ້ເພື່ອເຂົ້າລະຫັດຂໍ້ມູນທີ່ສຳຮອງໄວ້."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"ກະລຸນາປ້ອນລະຫັດຜ່ານ ເພື່ອໃຊ້ໃນການເຂົ້າລະຫັດການສຳຮອງຂໍ້ມູນເຕັມຮູບແບບ. ຖ້າປ່ອຍໃຫ້ເປົ່າຫວ່າງໄວ້, ລະຫັດຜ່ານສຳຮອງຂໍ້ມູນທີ່ທ່ານໃຊ້ຢູ່ຈະຖືກນຳໃຊ້ແທນ:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"ຫາກທ່ານຕ້ອງການທີ່ຈະເຂົ້າລະຫັດໃຫ້ກັບການສຳຮອງຂໍ້ມູນທັງໝົດ, ກະລຸນາໃສ່ລະຫັດທາງລຸ່ມນີ້:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"ຫາກຂໍ້ມູນສຳຮອງຖືກເຂົ້າລະຫັດໄວ້, ກະລຸນາໃສ່ລະຫັດຜ່ານທາງດ້ານລຸ່ມນີ້:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"ກຳລັງເລີ່ມການສຳຮອງຂໍ້ມູນ..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"ສຳຮອງຂໍ້ມູນສຳເລັດແລ້ວ"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"ການກູ້ຂໍ້ມູນກຳລັງຈະເລີ່ມ..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"ການກູ້ຂໍ້ມູນສິ້ນສຸດແລ້ວ"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"ໝົດເວລາປະຕິບັດການ"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-mn/strings.xml b/packages/BackupRestoreConfirmation/res/values-mn/strings.xml
new file mode 100644
index 0000000..b2738c0
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-mn/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="backup_confirm_title" msgid="827563724209303345">"Бүрэн нөөшлөх"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Бүрэн сэргээх"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Холбогдсон байгаа десктоп компьютерлүү бүх датаг бүрэн нөөшлөх хүсэлт тавигдав. Та энийг зөвшөөрөх үү?\n\nХэрэв та нөөшлөлт хийх хүсэлт хийгээгүй бол энийг зөвшөөрч болохгүй."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Миний датаг нөөшлөх"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Нөөшлөхгүй"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Холбогдсон байгаа десктоп компьютерээс бүх датаг бүрэн сэргээх хүсэлт тавигдав. Та энийг зөвшөөрөх үү?\n\nХэрэв та сэргээх хүсэлт хийгээгүй бол энийг зөвшөөрч болохгүй. Энэ нь төхөөрөмж дээр одоо байгаа дурын датаг орлуулах болно!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Миний датаг сэргээх"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Сэргээхгүй"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Одоогийн нөөшлөх нууц үгийг доор оруулна уу:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Төхөөрөмж шифрлэх нууц үгийг доор оруулна уу."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Төхөөрөмж шифрлэх нууц үгийг доор оруулна уу. Энэ нууц үгийг нөөшлөх архивийг шифрлэхэд бас ашиглана."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Бүрэн дата нөөшлөлтийг шифрлэхэд ашиглах нууц үгийг оруулна уу. Хэрэв та хоосон үлдээвэл таны одоогийн нөөшлөлтийн нууц үг ашиглагдах болно:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Хэрэв та бүрэн нөөшлөх датаг шифрлэх бол доор нууц үгийг оруулна уу:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Хэрэв сэргээх дата шифрлэгдсэн бол доор нууц үгийг оруулна уу:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Нөөшлөж эхлэх..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Нөөшлөлт дуусав"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Сэргээлт эхлэж байна..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Сэргээлт дуусав"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"Ажиллагааны хугацаа хэтрэв"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-ne-rNP/strings.xml b/packages/BackupRestoreConfirmation/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..c56332f
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-ne-rNP/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="backup_confirm_title" msgid="827563724209303345">"पूर्ण ब्याकअप"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"पूर्ण पुनःप्राप्ति"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"एउटा जोडिएको डेस्कटप कम्प्युटरमा सबै डेटाको एउटा पूर्ण जगेडाको अनुरोध गरिएको छ। के तपाईँ यो हुन दिन चाहनुहुन्छ? \n\nयदि तपाईँले जगेडाको लागि आफैँ अनुरोध गर्नु भएन भने प्रक्रियालाई अगाडि बढ्न अनुमति नदिनुहोस्।"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"मेरो डेटा ब्याकअप गर्नुहोस्"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"जगेडा नगर्नुहोस्"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"एउटा जडित डेस्कटप कम्प्युटरबाट सबै डेटाको पूर्ण पुनःबहाली अनुरोध गरियो। के तपाईं यो हुन अनुमति दिनुहुन्छ?\n\nयदि तपाईं आफैं पुनःबहाली अनुरोध गर्नुहुन्न भने अपरेसनलाई अघि बढाउन अनुमति नदिनुहोस्। यसले उपकरणमा भएको कुनै पनि डेटालाई बदल्ने छ!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"मेरो डेटा पुनःबहाली गर्नुहोस्"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"पुन:स्थापना नगर्नुहोस्"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"कृपया तल तपाईंको हालको ब्याकअप पासवर्ड प्रविष्टि गर्नुहोस्:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"कृपया तल तपाईंको उपकरण एन्क्रिप्सन पासवर्ड प्रविष्टि गर्नुहोस्:"</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"कृपया तल तपाईंको उपकरण एन्क्रिप्सन पासवर्ड प्रविष्टि गर्नुहोस्: यो ब्याकप सँग्रह एन्क्रिप्ट गर्न पनि प्रयोग हुने छ।"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"ब्याकप डेटालाई encrypt गर्न पासवर्ड प्रविष्टि गर्नुहोस्, यदि यो खालि छोडिएको खण्डमा तपाईको पुरानै पासवर्ड प्रयोग हुने छ।"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"यदि तपाईं पूर्ण ब्याकअप डेटा इन्क्रिप्ट गर्न चाहनु हुन्छ भने तल पासवर्ड प्रविष्टि गर्नुहोस्।"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"यदि पुनःबहाली डेटा इन्क्रिप्ट छ भने कृपया तल पासवर्ड प्रविष्टि गर्नुहोस्:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"जगेडा राख्न सुरु हुँदै..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"ब्याकअप सकियो"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"पुनःस्थापना सुरु हुँदैछ..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"पुनःबहाली समाप्त भयो"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"संचलन कार्यको समय समाप्त भयो"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-ne/strings.xml b/packages/BackupRestoreConfirmation/res/values-ne/strings.xml
new file mode 100644
index 0000000..c56332f
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-ne/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="backup_confirm_title" msgid="827563724209303345">"पूर्ण ब्याकअप"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"पूर्ण पुनःप्राप्ति"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"एउटा जोडिएको डेस्कटप कम्प्युटरमा सबै डेटाको एउटा पूर्ण जगेडाको अनुरोध गरिएको छ। के तपाईँ यो हुन दिन चाहनुहुन्छ? \n\nयदि तपाईँले जगेडाको लागि आफैँ अनुरोध गर्नु भएन भने प्रक्रियालाई अगाडि बढ्न अनुमति नदिनुहोस्।"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"मेरो डेटा ब्याकअप गर्नुहोस्"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"जगेडा नगर्नुहोस्"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"एउटा जडित डेस्कटप कम्प्युटरबाट सबै डेटाको पूर्ण पुनःबहाली अनुरोध गरियो। के तपाईं यो हुन अनुमति दिनुहुन्छ?\n\nयदि तपाईं आफैं पुनःबहाली अनुरोध गर्नुहुन्न भने अपरेसनलाई अघि बढाउन अनुमति नदिनुहोस्। यसले उपकरणमा भएको कुनै पनि डेटालाई बदल्ने छ!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"मेरो डेटा पुनःबहाली गर्नुहोस्"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"पुन:स्थापना नगर्नुहोस्"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"कृपया तल तपाईंको हालको ब्याकअप पासवर्ड प्रविष्टि गर्नुहोस्:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"कृपया तल तपाईंको उपकरण एन्क्रिप्सन पासवर्ड प्रविष्टि गर्नुहोस्:"</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"कृपया तल तपाईंको उपकरण एन्क्रिप्सन पासवर्ड प्रविष्टि गर्नुहोस्: यो ब्याकप सँग्रह एन्क्रिप्ट गर्न पनि प्रयोग हुने छ।"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"ब्याकप डेटालाई encrypt गर्न पासवर्ड प्रविष्टि गर्नुहोस्, यदि यो खालि छोडिएको खण्डमा तपाईको पुरानै पासवर्ड प्रयोग हुने छ।"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"यदि तपाईं पूर्ण ब्याकअप डेटा इन्क्रिप्ट गर्न चाहनु हुन्छ भने तल पासवर्ड प्रविष्टि गर्नुहोस्।"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"यदि पुनःबहाली डेटा इन्क्रिप्ट छ भने कृपया तल पासवर्ड प्रविष्टि गर्नुहोस्:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"जगेडा राख्न सुरु हुँदै..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"ब्याकअप सकियो"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"पुनःस्थापना सुरु हुँदैछ..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"पुनःबहाली समाप्त भयो"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"संचलन कार्यको समय समाप्त भयो"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-si-rLK/strings.xml b/packages/BackupRestoreConfirmation/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..ed32e73
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-si-rLK/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="backup_confirm_title" msgid="827563724209303345">"සම්පූර්ණ උපස්ථය"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"සම්පූර්ණයෙන් නැවත පිහිටුවන්න"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"ඩෙස්ක්ටොප් පරිගණකයකට සම්බන්ධිත සියලුම දත්ත වල සම්පූර්ණ උපස්ථයක් ඉල්ලා තිබේ. මෙම සිදු වෙනවාට අවසර දීමට ඔබට අවශ්‍යද?\n\nඔබ විසින් උපස්ථය කිරීමට ඉල්ලා නොතිබුණි නම්, මෙම මෙහෙයුම ඉදිරියට කරගෙන යාමට අවසර දෙන්න එපා. 1"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"මගේ දත්ත උපස්ථ කරන්න"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"උපස්ථ කරන්න එපා"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"සම්බන්ධිත ඩෙස්ක්ටොප් පරිගණකයකින් සියලු දත්ත වල සම්පූර්ණ ප්‍රතිස්ථාපනයක් ඉල්ලා ඇත. ඔබ මෙය සිදු වීමට අවසර දෙනවා ද?\n\nඔබ විසින් ප්‍රතිස්ථාපනය ඉල්ලා නොමැති නම්, ක්‍රියාවලියට ඉදිරියට යාමට ඉඩ නොදෙන්න. උපාංගයේ දැනට ඇති ඕනෑම දත්තයක් මෙමඟින් ප්‍රතිස්ථාපනය වෙයි!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"මගේ දත්ත නැවත පිහිටුවන්න"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"නැවත පිහිටුවන්න එපා"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"කරුණාකර ඔබගේ වර්තමාන උපස්ථ මුරපදය පහත ඇතුලත් කරන්න:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"කරුණාකර ඔබගේ උපාංගයේ සංකේතන මුරපදය පහත ඇතුලත් කරන්න."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"කරුණාකර ඔබගේ උපාංගයේ සංකේතන මුරපදය පහත ඇතුලත් කරන්න. සංරක්ෂිත උපස්ථ සංකේතනය කිරීමට මෙය භාවිත කළ හැක."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"කරුණාකර සියලු උපස්ථ දත්ත සංකේතනය කිරීම සඳහා භාවිතයට මුරපදයක් ඇතුළත් කරන්න. මෙය හිස්ව තැබුවොත්, ඔබගේ වර්තමාන උපස්ථ මුරපදය භාවිත වෙයි:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"සියලු උපස්ථ දත්ත සංකේතනය කිරීමට ඔබ අදහස් කරන්නේ නම්, මුරපදය පහලින් ඇතුලත් කරන්න:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"යළි පිහිටුවන දත්ත සංකේතනය කරන ලද ඒවානම්, කරුණාකර මුරපදය පහලින් ඇතුල් කරන්න:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"උපස්ථ කිරීම ආරම්භ කරමින්..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"උපස්ථය අවසන්"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"යළි පිහිටුවීම අරඹයි..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"යළි පිහිටුවීම අවසන්"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"ක්‍රියාවලිය කල් ඉකුත් වී ඇත"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-si/strings.xml b/packages/BackupRestoreConfirmation/res/values-si/strings.xml
new file mode 100644
index 0000000..ed32e73
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-si/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="backup_confirm_title" msgid="827563724209303345">"සම්පූර්ණ උපස්ථය"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"සම්පූර්ණයෙන් නැවත පිහිටුවන්න"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"ඩෙස්ක්ටොප් පරිගණකයකට සම්බන්ධිත සියලුම දත්ත වල සම්පූර්ණ උපස්ථයක් ඉල්ලා තිබේ. මෙම සිදු වෙනවාට අවසර දීමට ඔබට අවශ්‍යද?\n\nඔබ විසින් උපස්ථය කිරීමට ඉල්ලා නොතිබුණි නම්, මෙම මෙහෙයුම ඉදිරියට කරගෙන යාමට අවසර දෙන්න එපා. 1"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"මගේ දත්ත උපස්ථ කරන්න"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"උපස්ථ කරන්න එපා"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"සම්බන්ධිත ඩෙස්ක්ටොප් පරිගණකයකින් සියලු දත්ත වල සම්පූර්ණ ප්‍රතිස්ථාපනයක් ඉල්ලා ඇත. ඔබ මෙය සිදු වීමට අවසර දෙනවා ද?\n\nඔබ විසින් ප්‍රතිස්ථාපනය ඉල්ලා නොමැති නම්, ක්‍රියාවලියට ඉදිරියට යාමට ඉඩ නොදෙන්න. උපාංගයේ දැනට ඇති ඕනෑම දත්තයක් මෙමඟින් ප්‍රතිස්ථාපනය වෙයි!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"මගේ දත්ත නැවත පිහිටුවන්න"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"නැවත පිහිටුවන්න එපා"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"කරුණාකර ඔබගේ වර්තමාන උපස්ථ මුරපදය පහත ඇතුලත් කරන්න:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"කරුණාකර ඔබගේ උපාංගයේ සංකේතන මුරපදය පහත ඇතුලත් කරන්න."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"කරුණාකර ඔබගේ උපාංගයේ සංකේතන මුරපදය පහත ඇතුලත් කරන්න. සංරක්ෂිත උපස්ථ සංකේතනය කිරීමට මෙය භාවිත කළ හැක."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"කරුණාකර සියලු උපස්ථ දත්ත සංකේතනය කිරීම සඳහා භාවිතයට මුරපදයක් ඇතුළත් කරන්න. මෙය හිස්ව තැබුවොත්, ඔබගේ වර්තමාන උපස්ථ මුරපදය භාවිත වෙයි:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"සියලු උපස්ථ දත්ත සංකේතනය කිරීමට ඔබ අදහස් කරන්නේ නම්, මුරපදය පහලින් ඇතුලත් කරන්න:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"යළි පිහිටුවන දත්ත සංකේතනය කරන ලද ඒවානම්, කරුණාකර මුරපදය පහලින් ඇතුල් කරන්න:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"උපස්ථ කිරීම ආරම්භ කරමින්..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"උපස්ථය අවසන්"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"යළි පිහිටුවීම අරඹයි..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"යළි පිහිටුවීම අවසන්"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"ක්‍රියාවලිය කල් ඉකුත් වී ඇත"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-az-rAZ/strings.xml b/packages/DefaultContainerService/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..cae7d02
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-az-rAZ/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Paket Giriş Yardımçısı"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-az/strings.xml b/packages/DefaultContainerService/res/values-az/strings.xml
new file mode 100644
index 0000000..cae7d02
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-az/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Paket Giriş Yardımçısı"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-hy/strings.xml b/packages/DefaultContainerService/res/values-hy/strings.xml
new file mode 100644
index 0000000..1e2f587
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-hy/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Փաթեթի մուտքի օժանդակող"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-ka/strings.xml b/packages/DefaultContainerService/res/values-ka/strings.xml
new file mode 100644
index 0000000..216d715
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-ka/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Package Access Helper"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-km/strings.xml b/packages/DefaultContainerService/res/values-km/strings.xml
new file mode 100644
index 0000000..1006d56
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-km/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"កម្មវិធី​ជំនួយ​ចូល​ដំណើរការ​កញ្ចប់"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-lo/strings.xml b/packages/DefaultContainerService/res/values-lo/strings.xml
new file mode 100644
index 0000000..216d715
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-lo/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Package Access Helper"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-mn/strings.xml b/packages/DefaultContainerService/res/values-mn/strings.xml
new file mode 100644
index 0000000..d9fe647
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-mn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Багц хандалтын тусламж"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-ne-rNP/strings.xml b/packages/DefaultContainerService/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..5b70ce1
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-ne-rNP/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"प्याकेज पहुँच सहयोगी"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-ne/strings.xml b/packages/DefaultContainerService/res/values-ne/strings.xml
new file mode 100644
index 0000000..5b70ce1
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-ne/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"प्याकेज पहुँच सहयोगी"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-si-rLK/strings.xml b/packages/DefaultContainerService/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..522ec6c
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-si-rLK/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"පැකේජ ප්‍රවේශ උදව්කරු"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-si/strings.xml b/packages/DefaultContainerService/res/values-si/strings.xml
new file mode 100644
index 0000000..522ec6c
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-si/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"පැකේජ ප්‍රවේශ උදව්කරු"</string>
+</resources>
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 6e34bbb..f68d1a9 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -39,10 +39,8 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StatFs;
-import android.os.SystemClock;
 import android.provider.Settings;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.app.IMediaContainerService;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
index 1f7386c..71fd100 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
@@ -22,7 +22,6 @@
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.provider.DocumentsContract.Document;
-import android.util.Log;
 
 import com.google.android.collect.Maps;
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
index 05766f5..82c3048 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
@@ -54,8 +54,6 @@
 
 import libcore.io.IoUtils;
 
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
index 9d70c51..ce98db2 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
@@ -23,7 +23,6 @@
 import android.os.Bundle;
 import android.text.Editable;
 import android.text.TextWatcher;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
diff --git a/packages/ExternalStorageProvider/res/values-az-rAZ/strings.xml b/packages/ExternalStorageProvider/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..a6a79ca8
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-az-rAZ/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="7123375275748530234">"Xarici Yaddaş"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Daxili yaddaş"</string>
+</resources>
diff --git a/packages/FusedLocation/src/com/android/location/fused/FusedLocationService.java b/packages/FusedLocation/src/com/android/location/fused/FusedLocationService.java
index 509c010..12966cf 100644
--- a/packages/FusedLocation/src/com/android/location/fused/FusedLocationService.java
+++ b/packages/FusedLocation/src/com/android/location/fused/FusedLocationService.java
@@ -16,9 +16,6 @@
 
 package com.android.location.fused;
 
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
 import android.app.Service;
 import android.content.Intent;
 import android.os.IBinder;
diff --git a/packages/InputDevices/res/values-it/strings.xml b/packages/InputDevices/res/values-it/strings.xml
index dbb7301..334318e 100644
--- a/packages/InputDevices/res/values-it/strings.xml
+++ b/packages/InputDevices/res/values-it/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8016145283189546017">"Dispositivi di input"</string>
+    <string name="app_label" msgid="8016145283189546017">"Dispositivi di immissione"</string>
     <string name="keyboard_layouts_label" msgid="6688773268302087545">"Tastiera Android"</string>
     <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglese (UK)"</string>
     <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglese (USA)"</string>
diff --git a/packages/InputDevices/res/values-mn-rMN/strings.xml b/packages/InputDevices/res/values-mn-rMN/strings.xml
index 0cfb085..ec6cccb 100644
--- a/packages/InputDevices/res/values-mn-rMN/strings.xml
+++ b/packages/InputDevices/res/values-mn-rMN/strings.xml
@@ -25,7 +25,7 @@
     <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Финлянд"</string>
     <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Хорват"</string>
     <string name="keyboard_layout_czech" msgid="1349256901452975343">"Чех"</string>
-    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Эстони"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Эстон"</string>
     <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Унгар"</string>
     <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Исланд"</string>
     <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Бразил"</string>
diff --git a/packages/Keyguard/res/values-az-rAZ/strings.xml b/packages/Keyguard/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..5c8f6ac
--- /dev/null
+++ b/packages/Keyguard/res/values-az-rAZ/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PİN kodu daxil edin"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK və yeni PİN kod daxil edin"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kod"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Yeni PIN kodu"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Şifrə daxil etmək üçün toxunun"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Kilidi açmaq üçün parol yazın"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Kilidi açmaq üçün PIN daxil edin"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Yanlış PIN kodu."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Kilidi açmaq üçün Menyu, sonra 0 basın."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Sifət kilidi cəhdləriniz bitdi"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Dolmuş"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Dolur, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Elektrikə qoşun."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Kilidi açmaq üçün Menyu düyməsinə baxın."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Şəbəkə kilidləndi"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SİM kart yoxdur"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Planşetdə SİM kart yoxdur.."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Telefonda SİM kart yoxdu."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM kartı daxil edin."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SİM kart yoxdur və ya oxuna bilinmir. SİM kart daxil edin."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Yararsız SIM kart."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Sizin SİM kartınız daimi olaraq deaktivləşib.\n Başqa SİM kart üçün simsiz xidmət provayderinizə müraciət edin."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM kart kilidlənib."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SİM kart PUK ilə kilidlənib."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SİM kartın kilidi açılır..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget əlavə edin."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Boş"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Kilidi açma sahəsi genişləndi."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Kilidi açma sahəsi çökdü."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> vidcet."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"İstifadəçi selektoru"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Media kontrolları"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Yenidən sıralama vidceti başladıldı."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Vidcetin təkrar sifarişi sona çatdı."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Vidcet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> silindi."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Kilidi açma sahəsini genişləndir."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Sürüşdürmə kilidi."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Kild açma modeli."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Sifət Kilidi"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin kilid açması."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Şifrə kilidi."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Model sahəsi."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Sürüşdürmə sahəsi."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Əvvəlki izləmə düyməsi"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Növbəti izləmə düyməsi"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pauza düyməsi"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Oxutma düyməsi"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Dayandırma düyməsi"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Ləğv et"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Sil"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Hazırdır"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Rejim dəyişikliyi"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Daxil olun"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Kilidi aç"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Səssiz"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Səs açıqdır"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Axtar"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün yuxarı sürüşdürün."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün aşağı sürüşdürün."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sola sürüşdür."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sağa sürüşdür."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Təcili zəng"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Şablonu unutmuşam"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Yanlış Model"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Yanlış Şifrə"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN səhvdir"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Şablonunuzu çəkin"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN kodu daxil edin"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PİN kodu daxil edin"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Parol daxil edin"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM indi deaktivdir. Davam etmək üçün PUK kodu daxil edin. Əlavə məlumat üçün operatora müraciət edin."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"İstədiyiniz PİN kodu daxil edin"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"İstədiyiniz PIN kodu təsdiqləyin"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SİM kartın kilidi açılır..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Yanlış PİN kod."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-dən 8-ə qədər rəqəmi olan PIN yazın."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kod 8 rəqəm və ya daha çox olmalıdır."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Düzgün PUK kodu yenidən daxil edin. Təkrarlanan cəhdlər SIM\'i birdəfəlik sıradan çıxaracaq."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodları uyğun deyil"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Həddindən çox cəhd edildi!"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Kilidi açmaq üçün Google hesabınız ilə daxil olun."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"İstifadəçi adı (e-poçt)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Şifrə"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Daxil ol"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Yanlış istifadəçi adı və ya parol."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"İstifadəçi adınızı və ya parolunuzu unutmusunuz?\n "<b>"google.com/accounts/recovery"</b>" linkinə daxil olun."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Hesab yoxlanılır..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Modelinizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış çəkmisiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, planşet fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Siz telefon kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, telefon fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. Planşet fabrik ayarlarına sıfırlanacaq."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Siz telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> yanlış cəhd etmisiniz. Telefon artıq defolt zavod halına sıfırlanacaq."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> daha uğursuz cəhddən sonra planşetinizin kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Siz artıq modeli <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etmisiniz.<xliff:g id="NUMBER_1">%d</xliff:g> dəfə də yanlış daxil etsəniz, telefonun kilidinin açılması üçün elektron poçt ünvanınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində yenidən cəhd edin."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" - "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Yığışdır"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Əvvəlki izləmə düyməsi"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Növbəti izləmə düyməsi"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pauza düyməsi"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Oxutma düyməsi"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Dayandırma düyməsi"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Xidmət yoxdur."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-az/strings.xml b/packages/Keyguard/res/values-az/strings.xml
new file mode 100644
index 0000000..5c8f6ac
--- /dev/null
+++ b/packages/Keyguard/res/values-az/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PİN kodu daxil edin"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK və yeni PİN kod daxil edin"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kod"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Yeni PIN kodu"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Şifrə daxil etmək üçün toxunun"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Kilidi açmaq üçün parol yazın"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Kilidi açmaq üçün PIN daxil edin"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Yanlış PIN kodu."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Kilidi açmaq üçün Menyu, sonra 0 basın."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Sifət kilidi cəhdləriniz bitdi"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Dolmuş"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Dolur, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Elektrikə qoşun."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Kilidi açmaq üçün Menyu düyməsinə baxın."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Şəbəkə kilidləndi"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SİM kart yoxdur"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Planşetdə SİM kart yoxdur.."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Telefonda SİM kart yoxdu."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM kartı daxil edin."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SİM kart yoxdur və ya oxuna bilinmir. SİM kart daxil edin."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Yararsız SIM kart."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Sizin SİM kartınız daimi olaraq deaktivləşib.\n Başqa SİM kart üçün simsiz xidmət provayderinizə müraciət edin."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM kart kilidlənib."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SİM kart PUK ilə kilidlənib."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SİM kartın kilidi açılır..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget əlavə edin."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Boş"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Kilidi açma sahəsi genişləndi."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Kilidi açma sahəsi çökdü."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> vidcet."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"İstifadəçi selektoru"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Media kontrolları"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Yenidən sıralama vidceti başladıldı."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Vidcetin təkrar sifarişi sona çatdı."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Vidcet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> silindi."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Kilidi açma sahəsini genişləndir."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Sürüşdürmə kilidi."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Kild açma modeli."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Sifət Kilidi"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin kilid açması."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Şifrə kilidi."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Model sahəsi."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Sürüşdürmə sahəsi."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Əvvəlki izləmə düyməsi"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Növbəti izləmə düyməsi"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pauza düyməsi"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Oxutma düyməsi"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Dayandırma düyməsi"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Ləğv et"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Sil"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Hazırdır"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Rejim dəyişikliyi"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Daxil olun"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Kilidi aç"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Səssiz"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Səs açıqdır"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Axtar"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün yuxarı sürüşdürün."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün aşağı sürüşdürün."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sola sürüşdür."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sağa sürüşdür."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Təcili zəng"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Şablonu unutmuşam"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Yanlış Model"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Yanlış Şifrə"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN səhvdir"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Şablonunuzu çəkin"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN kodu daxil edin"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PİN kodu daxil edin"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Parol daxil edin"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM indi deaktivdir. Davam etmək üçün PUK kodu daxil edin. Əlavə məlumat üçün operatora müraciət edin."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"İstədiyiniz PİN kodu daxil edin"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"İstədiyiniz PIN kodu təsdiqləyin"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SİM kartın kilidi açılır..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Yanlış PİN kod."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-dən 8-ə qədər rəqəmi olan PIN yazın."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kod 8 rəqəm və ya daha çox olmalıdır."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Düzgün PUK kodu yenidən daxil edin. Təkrarlanan cəhdlər SIM\'i birdəfəlik sıradan çıxaracaq."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodları uyğun deyil"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Həddindən çox cəhd edildi!"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Kilidi açmaq üçün Google hesabınız ilə daxil olun."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"İstifadəçi adı (e-poçt)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Şifrə"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Daxil ol"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Yanlış istifadəçi adı və ya parol."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"İstifadəçi adınızı və ya parolunuzu unutmusunuz?\n "<b>"google.com/accounts/recovery"</b>" linkinə daxil olun."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Hesab yoxlanılır..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Modelinizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış çəkmisiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, planşet fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Siz telefon kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, telefon fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. Planşet fabrik ayarlarına sıfırlanacaq."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Siz telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> yanlış cəhd etmisiniz. Telefon artıq defolt zavod halına sıfırlanacaq."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> daha uğursuz cəhddən sonra planşetinizin kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Siz artıq modeli <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etmisiniz.<xliff:g id="NUMBER_1">%d</xliff:g> dəfə də yanlış daxil etsəniz, telefonun kilidinin açılması üçün elektron poçt ünvanınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində yenidən cəhd edin."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" - "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Yığışdır"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Əvvəlki izləmə düyməsi"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Növbəti izləmə düyməsi"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pauza düyməsi"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Oxutma düyməsi"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Dayandırma düyməsi"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Xidmət yoxdur."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-hy/strings.xml b/packages/Keyguard/res/values-hy/strings.xml
new file mode 100644
index 0000000..19b3c79
--- /dev/null
+++ b/packages/Keyguard/res/values-hy/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Մուտքագրեք PIN կոդը"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Մուտքագրեք PUK-ը և նոր PIN կոդը"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK կոդ"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Նոր PIN ծածկագիր"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Հպեք` գաղտնաբառը մուտքագրելու համար"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Մուտքագրեք գաղտնաբառը ապակողպման համար"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Մուտքագրեք PIN-ը ապակողպման համար"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Սխալ PIN ծածկագիր:"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Ապակողպման համար սեղմեք Ցանկ, ապա 0:"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Առավելագույն Դեմքով ապակողպման փորձերը գերազանցված են"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Լիցքավորված է"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Լիցքավորում, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Միացրեք ձեր լիցքավորիչը:"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Ապակողպելու համար սեղմեք Ցանկը:"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Ցանցը կողպված է"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM քարտ չկա"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Գրասալիկում SIM քարտ չկա:"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Հեռախոսի մեջ SIM քարտ չկա:"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Զետեղեք SIM քարտը:"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM քարտը բացակայում է կամ չի կարող կարդացվել: Մտցրեք SIM քարտ:"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Անպիտան SIM քարտ:"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Ձեր SIM քարտը ընդմիշտ կասեցվել է:\nԿապվեք ձեր բջջային ծառայության մատակարարի հետ նոր SIM քարտ ձեռք բերելու համար:"</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM քարտը կողպված է:"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM քարտը PUK-ով կողպված է:"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM քարտը ապակողպվում է..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Վիջեթ %2$d of %3$d:"</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ավելացնել վիջեթ:"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Դատարկ"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Ապակողպման տարածքն ընդլայնված է:"</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Ապակողպման տարածքը ետ է ծալված:"</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> վիջեթ:"</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Օգտվողի ընտրիչ"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Կարգավիճակ"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Ֆոտոխցիկ"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Մեդիա կարգավորումներ"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Վիջեթների վերադասավորումը մեկնարկել է:"</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Վիջեթի վերադասավորումն ավարտվեց:"</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Վիջեթ <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>-ը ջնջված է:"</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Ընդլայնել ապակողպման տարածությունը:"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Էջի ապակողպում:"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Սխեմայով ապակողպում:"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Դեմքով ապակողպում:"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin-ն ապակողպված է:"</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Գաղտնաբառի ապակողպում:"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Սխեմայի տարածք:"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Սահեցման տարածք:"</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Նախորդ հետագծի կոճակը"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Հաջորդ հետագծի կոճակը"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Դադարի կոճակ"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Նվագարկման կոճակ"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Կանգի կոճակ"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Չեղարկել"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Ջնջել"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Կատարված է"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Ռեժիմի փոփոխում"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Մուտք"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Ապակողպել"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Ֆոտոխցիկ"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Լուռ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Ձայնը միացնել"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Որոնել"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Սահեցրեք վերև <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Սահեցրեք ցած <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Սահեցրեք ձախ` <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Սահեցրեք աջ` <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
+    <string name="user_switched" msgid="3768006783166984410">"Ներկայիս օգտվողը <xliff:g id="NAME">%1$s</xliff:g>:"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Արտակարգ իրավիճակի հեռախոսազանգ"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Մոռացել եմ սխեման"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Սխալ սխեմա"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Սխալ գաղտնաբառ"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Սխալ PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Փորձեք կրկին <xliff:g id="NUMBER">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Հավաքեք ձեր սխեման"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Մուտքագրեք SIM-ի PIN-ը"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Մուտքագրեք PIN-ը"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Մուտքագրեք գաղտնաբառը"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-ը այս պահին անջատված է: Մուտքագրեք PUK կոդը շարունակելու համար: Մանրամասների համար կապվեք օպերատորի հետ:"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Մուտքագրեք ցանկալի PIN ծածկագիրը"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Հաստատեք ցանկալի PIN ծածկագիրը"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ապակողպում է SIM քարտը ..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Սխալ PIN ծածկագիր:"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Մուտքագրեք PIN, որը 4-ից 8 թիվ է:"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK կոդը պետք է լինի 8 կամ ավելի թիվ:"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Վերամուտքագրեք ճիշտ PUK ծածկագիրը: Կրկնվող փորձերը ընդմիշտ կկասեցնեն SIM քարտը:"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN ծածկագրերը չեն համընկնում"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Չափից շատ սխեմայի փորձեր"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Ապակողպելու համար` մուտք գործեք ձեր Google հաշվով:"</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Օգտանուն (էլփոստ)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Գաղտնաբառը"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Մուտք գործել"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Սխալ օգտանուն կամ գաղտնաբառ:"</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Մոռացե՞լ եք ձեր օգտանունը կամ գաղտնաբառը:\nԱյցելեք "<b>"google.com /accounts/recovery"</b>":"</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Հաշիվը ստուգվում է..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք մուտքագրել ձեր PIN-ը: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Դուք սխալ եք մուտքագրել ձեր գաղտնաբառը <xliff:g id="NUMBER_0">%d</xliff:g> անգամ: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ փորձ եք արել գրասալիկն ապակողպելու համար: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո գրասալիկը կվերակարգավորվի գործարանային լռելյայնի, և օգտվողի բոլոր տվյալները կկորեն:"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ փորձ եք արել հեռախոսն ապակողպելու համար: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո հեռախոսը կվերակարգավորվի գործարանային լռելյայնի, և օգտվողի բոլոր տվյալները կկորեն:"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Դուք <xliff:g id="NUMBER">%d</xliff:g> անգամ սխալ փորձ եք արել գրասալիկն ապակողպելու համար: Գրասալիկն այժմ կվերակարգավորվի գործարանային լռելյայնի:"</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Դուք <xliff:g id="NUMBER">%d</xliff:g> անգամ սխալ փորձ եք արել հեռախոսն ապակողպելու համար: Հեռախոսն այժմ կվերակարգավորվի գործարանային լռելյայնի:"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Դուք սխալ եք հավաքել ձեր ապակողպման սխեման <xliff:g id="NUMBER_0">%d</xliff:g> անգամ: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել ձեր գրասալիկը` օգտագործելով էլփոստի հաշիվ:\n\n Փորձեք կրկին <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման նմուշը: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո ձեզ կառաջարկվի ապակողպել ձեր հեռախոսը` օգտագործելով էլփոստի հաշիվ:\n\n Փորձեք կրկին <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Հեռացնել"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Նախորդ հետագծի կոճակ"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Հաջորդ հետագծի կոճակ"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Դադարի կոճակ"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Նվագարկման կոճակ"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Դադարի կոճակ"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ծառայություն չկա:"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ka/strings.xml b/packages/Keyguard/res/values-ka/strings.xml
new file mode 100644
index 0000000..b901bf4
--- /dev/null
+++ b/packages/Keyguard/res/values-ka/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"აკრიფეთ PIN კოდი"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"დაბეჭდეთ PUK კოდი და ახალი PIN კოდი."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK კოდი"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ახალი PIN კოდი"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384">"შეეხეთ "<font size="17">"-ს პაროლის"</font>" დასაბეჭდად."</string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"განსაბლოკად აკრიფეთ პაროლი"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"განსაბლოკად აკრიფეთ PIN კოდი"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"არასწორი PIN კოდი."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"განბლოკვისათვის დააჭირეთ მენიუს და შემდეგ 0-ს."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"სახის ამოცნობით განბლოკვის მცდელობამ დაშვებულ რაოდენობას გადააჭარბა"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"დამუხტულია"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"მიმდინარეობს დამუხტვა (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"შეაერთეთ დამტენი."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"განბლოკვისთვის დააჭირეთ მენიუს."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"ქსელი ჩაკეტილია"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM ბარათი არ არის"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ტაბლეტში არ დევს SIM ბარათი."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"არ არის SIM ბარათი ტელეფონში."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"ჩადეთ SIM ბარათი."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM ბარათი არ არის ან არ იკითხება. ჩადეთ SIM ბარათი."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"არამოხმარებადი SIM ბარათი."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"თქვენი SIM ბარათი გამუდმებით გამორთული იყო.\n დაუკავშირდით თქვენი უკაბელო სერვისის პროვაიდერს სხვა SIM ბარათისთვის."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM ბარათი დაბლოკილია."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM ბარათი დაბლოკილია PUK კოდით."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"მიმდინარეობს SIM ბარათის განბლოკვა…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ვიჯეტი %2$d of %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ვიჯეტის დამატება"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ცარიელი"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"განბლოკვის სივრცე გაშლილია."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"განბლოკვის სივრცე ჩაკეცილია."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ვიჯეტი."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"მომხმარებლის ამომრჩეველი"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"სტატუსი"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"კამერა"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"მედიის მართვის ელემენტები"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"დაიწყო ვიჯეტის ხელახლა განლაგება."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"ვიჯეტების გადახარისხება დასრულებულია."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"ვიჯეტი <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> წაიშალა."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"განბლოკვის სივრცის გაშლა."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"გასრიალებით განბლოკვა"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"განბლოკვა ნიმუშით."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"განბლოკვა სახით"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"განბლოკვა Pin-ით."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"პაროლის განბლოკვა"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ნიმუშების სივრცე."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"გადასრიალების სივრცე."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"წინა ჩანაწერის ღილაკი"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"შემდეგი ჩანაწერის ღილაკი"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"პაუზის ღილაკი"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"დაკვრის ღილაკი"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Stop ღილაკი"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"გაუქმება"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"წაშლა"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"დასრულდა"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"რეჟიმის შეცვლა"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift-"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"შეყვანა"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"განბლოკვა"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"კამერა"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"უხმო"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ხმის ჩართვა"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ძიება"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"გაასრიალეთ ზემოთ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"გაასრიალეთ ქვემოთ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"გაასრიალეთ მარცხნივ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"გაასრიალეთ მარჯვნივ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
+    <string name="user_switched" msgid="3768006783166984410">"ამჟამინდელი მომხმარებელი <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"გადაუდებელი დახმარების ზარი"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"დაგავიწყდათ ნიმუში"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"არასწორი ნიმუში"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"არასწორი პაროლი"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"არასწორი PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"კიდევ სცადეთ <xliff:g id="NUMBER">%d</xliff:g> წამში."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"დახატეთ თქვენი ნიმუში."</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN-ის შეყვანა"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"შეიყვანეთ PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"პაროლის შეყვანა"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM ამჟამად დეაქტივირებულია. გასაგრძელებლად შეიყვანეთ PUK კოდი. დეტალებისთვის მიმართეთ მობილურ ოპერატორს."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"სასურველი PIN კოდის შეყვანა"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"სასურველი PIN კოდის დადასტურება"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM ბარათის განბლოკვა…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"არასწორი PIN კოდი."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"აკრიფეთ PIN, რომელიც შედგება 4-დან 8 ციფრამდე."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK კოდი უნდა იყოს რვა ან მეტი ციფრისგან შემდგარი."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"ხელახლა შეიყვანეთ სწორი PUK კოდი. რამდენიმე წარუმატებელი მცდელობა გამოიწვევს SIM ბარათის დაბლოკვას."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN კოდები არ ემთხვევა"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ნახატი ნიმუშის ძალიან ბევრი მცდელობა"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"განბლოკვისთვის გაიარეთ ავტორიზაცია თქვენი Google  ანგარიშით."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"მომხმარებლის სახელი (ელფოსტა)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"პაროლი"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"შესვლა"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"არასწორი სახელი, ან პაროლი."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"დაგავიწყდათ მომხმარებლის სახელი და პაროლი?\nეწვიეთ "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"მიმდინარეობს ანგარიშის შემოწმება…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად შეიყვანეთ PIN კოდი. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად დაბეჭდეთ თქვენი პაროლი. \n\nხელახლა სცადეთ <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ დახატეთ განბლოკვის ნიმუში. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"თქვენ არასწორად სცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ ტაბლეტზე დაყენდება საწყისი, ქარხნული პარამეტრები და მომხმარებლის ყველა მონაცემი დაიკარგება."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"თქვენ არასწორად სცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ ტელეფონზე დაყენდება საწყისი, ქარხნული პარამეტრები და მომხმარებლის ყველა მონაცემი დაიკარგება."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"თქვენ არასწორად სცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER">%d</xliff:g>-ჯერ. ტაბლეტზე დაყენდება საწყისი, ქარხნული პარამეტრები და მომხმარებლის ყველა მონაცემი დაიკარგება."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"თქვენ <xliff:g id="NUMBER">%d</xliff:g>-ჯერ არასწორად სცადეთ ტელეფონის განბლოკვა. ამიტომ ტელეფონზე დადგება საწყისი, ქარხნული პარამეტრები."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%d</xliff:g> ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ მოგთხოვთ ტაბლეტის განბლოკვას ელფოსტის ანგარიშის გამოყენებით.\n\n ხელახლა სცადეთ <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ, დაგჭირდებათ თქვენი ტელეფონის განბლოკვა ელფოსტის ანგარიშის გამოყენებით.\n\n ხელახლა სცადეთ <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"ამოშლა"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"წინა ჩანაწერზე გადასვლის ღილაკი"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"შემდეგი ჩანაწერის ღილაკი"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"პაუზის ღილაკი"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"დაკვრის ღილაკი"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"შეჩერების ღილაკი"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"არ არის სერვისი."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-km/strings.xml b/packages/Keyguard/res/values-km/strings.xml
new file mode 100644
index 0000000..586169e
--- /dev/null
+++ b/packages/Keyguard/res/values-km/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"បញ្ចូល​កូដ PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"បញ្ចូល​កូដ PUK និង​ PIN ថ្មី"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"កូដ PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"កូដ PIN ថ្មី"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"ប៉ះ ដើម្បី​បញ្ចូល​ពាក្យ​សម្ងាត់"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"បញ្ចូល​ពាក្យ​សម្ងាត់​ ​ដើម្បី​ដោះ​សោ"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"បញ្ចូល​កូដ PIN ដើម្បី​ដោះ​សោ"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"កូដ PIN មិន​ត្រឹមត្រូវ។"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"ដើម្បី​ដោះ​សោ​​ ចុច​ម៉ឺនុយ​ បន្ទាប់មក 0 ។"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"បាន​លើស​ការ​ព្យាយាម​ដោះ​សោ​តាម​ទម្រង់​មុខ"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"បាន​បញ្ចូល​​ពេញ"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"បញ្ចូល​ថ្ម <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"ភ្ជាប់​ឧបករណ៍​បញ្ចូល​ថ្ម​។"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"ចុច​ម៉ឺនុយ ដើម្បី​ដោះ​សោ។"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"បណ្ដាញ​ជាប់​សោ"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"គ្មាន​ស៊ី​ម​កាត"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"គ្មាន​ស៊ី​ម​កាត​នៅ​ក្នុង​កុំព្យូទ័រ​បន្ទះ​។"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"គ្មាន​ស៊ីមកាត​ក្នុង​ទូរស័ព្ទ។"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"បញ្ចូល​​​ស៊ី​ម​កាត​។"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"បាត់​ស៊ីមកាត ឬ​មិន​អាច​អាន។ បញ្ចូល​ស៊ីម​កាត។"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"ស៊ីម​កាត​មិន​អាច​ប្រើ​បាន។"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"បាន​បិទ​ស៊ីម​កាត​របស់​អ្នក​ជា​អចិន្ត្រៃយ៍។\n ទាក់ទង​​ក្រុមហ៊ុន​ផ្ដល់​សេវាកម្ម​ឥត​ខ្សែ​សម្រាប់​ស៊ីម​កាត​ផ្សេង។"</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"ស៊ីម​កាត​​ជាប់​សោ។"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"ស៊ីម​កាត​ជាប់​កូដ​​ PUK ។"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"កំពុង​ដោះ​សោ​ស៊ីម​កាត..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ធាតុ​ក្រាហ្វិក %2$d នៃ %3$d ។"</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"បន្ថែម​ធាតុ​ក្រាហ្វិក​។"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ទទេ"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"បាន​ពង្រីក​ផ្ទៃ​ដោះ​សោ។"</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"បាន​បង្រួម​ផ្ទៃ​ដោះ​សោ។"</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ធាតុ​ក្រាហ្វិក។"</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"ឧបករណ៍​ជ្រើស​អ្នក​ប្រើ"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"ស្ថានភាព"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"ម៉ាស៊ីន​ថត"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"ពិនិត្យ​មេឌៀ"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"បាន​ចាប់ផ្ដើម​តម្រៀប​ធាតុ​ក្រាហ្វិក​ឡើងវិញ។"</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"បាន​បញ្ចប់​ការ​បង្ហាញ​ធាតុ​ក្រាហ្វិក។"</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"បាន​លុប​ធាតុ​ក្រាហ្វិក <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ។"</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"ពង្រីក​តំបន់​ដោះ​សោ។"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"រុញ​ដោះ​សោ។"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"លំនាំ​ដោះ​សោ​។"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ដោះ​សោ​តាម​​ទម្រង់​មុខ។"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"កូដ PIN ដោះ​សោ។"</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"ពាក្យ​សម្ងាត់​ដោះ​សោ​។"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ផ្ទៃ​លំនាំ។"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"ផ្ទៃ​រុញ។"</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"ប៊ូតុង​បទ​មុន"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"ប៊ូតុង​បទ​បន្ទាប់"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"ប៊ូតុង​ផ្អាក"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"ប៊ូតុង​ចាក់"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"ប៊ូតុង​បញ្ឈប់"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះ​បង់"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"លុប"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"រួចរាល់"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ប្ដូរ​របៀប"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"ដោះ​​សោ"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"ម៉ាស៊ីន​ថត"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"ស្ងាត់"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"បើក​សំឡេង"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"រុញ​ឡើង​លើ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"រុញ​ចុះក្រោម​សម្រាប់ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"រុញ​ទៅ​ឆ្វេង​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"រុញ​​ទៅ​ស្ដាំ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
+    <string name="user_switched" msgid="3768006783166984410">"អ្នក​ប្រើ​បច្ចុប្បន្ន <xliff:g id="NAME">%1$s</xliff:g> ។"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"ការ​ហៅ​ពេល​អាសន្ន"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ភ្លេច​​លំនាំ"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"លំនាំ​មិន​ត្រឹមត្រូវ"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"កូដ PIN មិន​ត្រឹមត្រូវ"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"គូរ​លំនាំ​របស់​អ្នក"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"បញ្ចូល​កូដ PIN ស៊ីម​កាត"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"បញ្ចូល​​កូដ PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"បញ្ចូល​ពាក្យ​សម្ងាត់"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ឥឡូវ​ស៊ីមកាត​ត្រូវ​បាន​បិទ។ បញ្ចូល​កូដ PUK ដើម្បី​បន្ត។ ចំពោះ​ព័ត៌មាន​លម្អិត​ទាក់ទង​ក្រុមហ៊ុន​បញ្ជូន​របស់​អ្នក។"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"បញ្ចូល​កូដ PIN ដែល​ចង់​បាន"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"បញ្ជាក់​កូដ PIN ដែល​ចង់​បាន"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"កំពុង​ដោះ​សោ​​ស៊ីម​កាត..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"កូដ PIN មិន​ត្រឹមត្រូវ។"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"បញ្ចូល​កូដ PIN ដែល​មាន​ពី ៤ ដល់ ៨ លេខ។"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"កូដ PUK គួរ​តែ​មាន​​ ៨ លេខ ឬ​​ច្រើន​ជាង​នេះ។"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"បញ្ចូល​កូដ PUK ម្ដង​ទៀត។ ការ​ព្យាយាម​ដដែល​ច្រើន​ដឹង​នឹង​បិទ​ស៊ីម​កាត​ជា​អចិន្ត្រៃយ៍។"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"កូដ PIN មិន​ដូច​គ្នា"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាម​លំនាំ​ច្រើន​ពេក"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"ដើម្បី​ដោះ​សោ ចូល​ក្នុង​គណនី Google ។"</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"ឈ្មោះ​អ្នក​ប្រើ (អ៊ី​ម៉ែ​ល​)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"ចូល"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"ឈ្មោះ​អ្នកប្រើ ឬ​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ។"</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ភ្លេច​ឈ្មោះ​អ្នកប្រើ ឬ​ពាក្យ​សម្ងាត់​របស់​អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"កំពុង​ពិនិត្យ​មើល​គណនី..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"អ្នក​បាន​បញ្ចូល​កូដ PIN របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"អ្នក​បាន​បញ្ចូល​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"អ្នក​បាន​​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​​កុំព្យូទ័រ​បន្ទះ​​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង កុំព្យូទ័រ​បន្ទះ​​នឹង​ត្រូវ​បាន​កំណត់​ទៅ​លំនាំដើម​ដូច​ចេញ​ពី​រោងចក្រ ហើយ​ទិន្នន័យ​អ្នកប្រើ​នឹង​បាត់បង់។"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​ទូរស័ព្ទ​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង ទូរស័ព្ទ​នឹង​ត្រូវ​បាន​កំណត់​ទៅ​លំនាំដើម​ដូច​ចេញ​ពី​រោងចក្រ ហើយ​ទិន្នន័យ​អ្នកប្រើ​នឹង​បាត់បង់។"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​កុំព្យូទ័រ​បន្ទះ​មិន​ត្រឹមត្រូវ​ចំនួន​ <xliff:g id="NUMBER">%d</xliff:g> ដង។ កុំព្យូទ័រ​បន្ទះ​នឹង​ត្រូវ​បាន​កំណត់​ទៅ​លំនាំដើម​ដូច​ចេញ​ពី​រោងចក្រ"</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​ទូរស័ព្ទ​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER">%d</xliff:g> ដង។ ឥឡូវ​ទូរស័ព្ទ​នឹង​កំណត់​ទៅ​លំនាំ​ដើម​ដូច​ចេញ​ពី​រោងចក្រ។"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​សោ​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម <xliff:g id="NUMBER_1">%d</xliff:g> ដង​មិន​ជោគជ័យ អ្នក​នឹង​ត្រូវ​បាន​ស្នើ​ឲ្យ​ដោះ​សោ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក ដោយ​ប្រើ​គណនី​អ៊ីមែល។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើនជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង អ្នក​នឹង​ត្រូវ​បាន​​ស្នើ​ឲ្យ​ដោះ​សោ​ទូរស័ព្ទ​របស់​អ្នក​ដោយ​ប្រើ​គណនី​អ៊ីមែល។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"លុប​ចេញ"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"ប៊ូតុង​បទ​មុន"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"ប៊ូតុង​បទ​បន្ទាប់"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"ប៊ូតុង​ផ្អាក"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"ប៊ូតុង​ចាក់"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"ប៊ូតុង​បញ្ឈប់"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"គ្មាន​សេវា​។"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-lo/strings.xml b/packages/Keyguard/res/values-lo/strings.xml
new file mode 100644
index 0000000..0dcb7d1
--- /dev/null
+++ b/packages/Keyguard/res/values-lo/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"ພິມລະຫັດ PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"ພິມລະຫັດ PUK ແລະ​ລະ​ຫັດ PIN ອັນໃໝ່"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"ລະ​ຫັດ PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ລະຫັດ PIN ໃໝ່"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"ແຕະເພື່ອພິມລະຫັດຜ່ານ"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"ພິມລະຫັດເພື່ອປົດລັອກ"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ພິມລະຫັດ PIN ເພື່ອປົດລັອກ"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"ເພື່ອປົດລັອກ, ໃຫ້ກົດເມນູ ແລ້ວກົດ 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"ຄວາມພະຍາຍາມປົດລັອກດ້ວຍໜ້ານັ້ນ ເກີນຈຳນວນທີ່ກຳນົດແລ້ວ"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"ສາກເຕັມແລ້ວ"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"ກຳລັງສາກ, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"ເຊື່ອມຕໍ່ອຸປະກອນສາກຂອງທ່ານ."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"ກົດເມນູເພື່ອປົດລັອກ."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"ເຄືອຂ່າຍຖືກລັອກ"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"ບໍ່ມີຊິມກາດ"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ບໍ່ມີຊິມກາດໃນແທັບເລັດ."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ບໍ່ມີຊິມກາດຢູ່ໃນໂທລະສັບ."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"ໃສ່ SIM card."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"ບໍ່ພົບເຫັນຊິມກາດ ຫຼືບໍ່ສາມາດອ່ານຊິມກາດໄດ້. ກະລຸນາໃສ່ຊິມກາດໃໝ່."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM card ບໍ່ສາມາດໃຊ້ໄດ້."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM card ຂອງທ່ານຖືກປິດການນຳໃຊ້ຢ່າງຖາວອນແລ້ວ.\n ຕິດຕໍ່ຜູ່ໃຫ້ບໍລິການລະບົບຂອງທ່ານເພື່ອຂໍ SIM card ໃໝ່."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"ຊິມກາດຖືກລັອກ."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"ຊິມກາດຖືກລັອກດ້ວຍລະຫັດ PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"ກຳລັງປົດລັອກຊິມກາດ..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ວິດເຈັດ %2$d ຈາກທັງໝົດ %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ເພີ່ມວິດເຈັດ"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ຫວ່າງເປົ່າ"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"ຂະຫຍາຍພື້ນທີ່ປົດລັອກແລ້ວ."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"ຫຍໍ້ພື້ນທີ່ປົດລັອກແລ້ວ."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ວິດເຈັດ."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"ໂຕເລືອກຂອງຜູ່ໃຊ້"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"ສະຖານະ"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"ກ້ອງ"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"ການຄວບຄຸມສື່"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"ການຈັດຮຽງວິເຈັດໃໝ່ເລີ່ມຕົ້ນແລ້ວ."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"ການຈັດຮຽງວິດເຈັດຄືນໃໝ່ສຳເລັດແລ້ວ."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"ລຶບວິດເຈັດ <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ແລ້ວ."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"ຂະຫຍາຍຂອບເຂດປົດລັອກ."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"ການປົດລັອກດ້ວຍການເລື່ອນ."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ປົດລັອກດ້ວຍຮູບແບບ."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ປົດລັອກດ້ວຍໜ້າ."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"ປົດລັອກດ້ວຍ PIN."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"ການປົດລັອກດ້ວຍລະຫັດຜ່ານ."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ພື້ນທີ່ຮູບແບບ."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"ເລື່ອນພື້ນທີ່."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"ປຸ່ມເພງກ່ອນໜ້າ"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"ປຸ່ມເພງຕໍ່ໄປ"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"ປຸ່ມຢຸດຊົ່ວຄາວ"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"ປຸ່ມຫຼິ້ນ"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"ປຸ່ມຢຸດ"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ຍົກເລີກ"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"ລຶບ"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"ແລ້ວໆ"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ປ່ຽນຮູບແບບ"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"ປົດລັອກ"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"ກ້ອງ"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"ປິດສຽງ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ເປີດສຽງ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ຊອກຫາ"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"ເລື່ອນຂຶ້ນເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"ເລື່ອນລົງເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"ເລື່ອນໄປທາງຊ້າຍເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"ເລື່ອນໄປທາງຂວາເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"ຜູ່ໃຊ້ປັດຈຸບັນ <xliff:g id="NAME">%1$s</xliff:g> ."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"ການໂທສຸກເສີນ"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ລືມຮູບແບບປົດລັອກ?"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"ຮູບແບບຜິດ"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"ລະຫັດຜ່ານບໍ່ຖືກຕ້ອງ"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"ລະຫັດ PIN ຜິດ"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"ລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"ແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານ"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"ໃສ່ລະຫັດ PIN ຂອງຊິມ"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"ໃສ່ລະຫັດ PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"ໃສ່ລະຫັດຜ່ານ"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ຊິມຖືກປິດການນຳໃຊ້ແລ້ວ. ປ້ອນລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ຕິດຕໍ່ຜູ່ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ໃສ່ລະຫັດ PIN ທີ່ຕ້ອງການ."</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ຢືນຢັນລະຫັດ PIN ທີ່ຕ້ອງການ"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"ປົດລັອກ SIM card..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ພິມລະຫັດ PIN ຄວາມຍາວ 4 ເຖິງ 8 ໂຕເລກ."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"ລະຫັດ PUK ຄວນມີຢ່າງໜ້ອຍ 8 ໂຕເລກ."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"ປ້ອນລະຫັດ PUK ທີ່ຖືກຕ້ອງຄືນໃໝ່. ການພະຍາຍາມໃສ່ຫຼາຍເທື່ອຈະເຮັດໃຫ້ຊິມກາດໃຊ້ບໍ່ໄດ້ຖາວອນ."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ລະຫັດ PIN ບໍ່ກົງກັນ"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ແຕ້ມຮູບແບບປົດລັອກຫຼາຍເກີນໄປ"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"ເພື່ອປົດລັອກ, ເຂົ້າສູ່ລະບົບດ້ວຍບັນຊີ Google ຂອງທ່ານ."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"ຊື່ຜູ່ໃຊ້ (ອີເມວ)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"ລະຫັດຜ່ານ"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"ເຂົ້າສູ່ລະບົບ"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"ຊື່ຜູ່ໃຊ້ ຫຼືລະຫັດຜ່ານບໍ່ຖືກຕ້ອງ."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ລືມຊື່ຜູ່ໃຊ້ ຫຼືລະຫັດຜ່ານຂອງທ່ານບໍ່?\nໄປທີ່ "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"ກຳລັງກວດສອບບັນຊີ..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ທ່ານພິມລະຫັດ PIN​ ຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ທ່ານພິມລະຫັດຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ສຳເລັດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ແທັບເລັດຂອງທ່ານຈະຖືກຕັ້ງ ໃຫ້ກັບໄປໃຊ້ຄ່າເລີ່ມຕົ້ນຈາກໂຮງງານຄືນໃໝ່ ແລະຂໍ້ມູນຜູ່ໃຊ້ທັງໝົດຈະສູນຫາຍໄປ."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ສຳເລັດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ໂທລະສັບຂອງທ່ານຈະຖືກຕັ້ງ ໃຫ້ກັບໄປໃຊ້ຄ່າເລີ່ມຕົ້ນຈາກໂຮງງານຄືນໃໝ່ ແລະຂໍ້ມູນຜູ່ໃຊ້ທັງໝົດຈະສູນຫາຍໄປ."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ສຳເລັດ <xliff:g id="NUMBER">%d</xliff:g> ເທື່ອແລ້ວ. ຕອນນີ້ແທັບເລັດຈະຖືກຕັ້ງໃຫ້ກັບໄປໃຊ້ຄ່າເລີ່ມຕົ້ນຈາກໂຮງງານ."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ຖືກ <xliff:g id="NUMBER">%d</xliff:g> ເທື່ອແລ້ວ. ຕອນນີ້ໂທລະສັບຈະຖືກຣີເຊັດເປັນຄ່າຈາກໂຮງງານ."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກແທັບເລັດຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບໂດຍໃຊ້ອີເມວຂອງທ່ານ.\n\n ກະລຸນາລອງໃໝ່ອີກຄັ້ງໃນອີກ <xliff:g id="NUMBER_2">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍບັນຊີອີເມວ.\n\n ລອງໃໝ່ອີກຄັ້ງໃນ <xliff:g id="NUMBER_2">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"ລຶບອອກ"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"ປຸ່ມເພງກ່ອນໜ້າ"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"ປຸ່ມເພງຕໍ່ໄປ"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"ປຸ່ມຢຸດຊົ່ວຄາວ"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"ປຸ່ມຫຼິ້ນ"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"ປຸ່ມຢຸດ"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"ບໍ່ມີບໍລິການ"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-mn/strings.xml b/packages/Keyguard/res/values-mn/strings.xml
new file mode 100644
index 0000000..4ae7220
--- /dev/null
+++ b/packages/Keyguard/res/values-mn/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN кодыг бичнэ үү"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK-г бичээд шинэ PIN код оруулна уу"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK код"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Шинэ PIN код"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Нууц үг бичих бол хүрнэ үү"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Тайлах нууц үгийг бичнэ үү"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Тайлах PIN-г оруулна уу"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Буруу PIN код."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Тайлах бол Цэсийг дараад 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Нүүрээр түгжээ тайлах оролдлогын тоо дээд хэмжээнээс хэтэрсэн"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Цэнэглэгдэв"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Цэнэглэж байна, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Цэнэглэгчээ холбоно уу."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Тайлх бол цэсийг дарна уу."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Сүлжээ түгжигдсэн"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM карт байхгүй"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Таблет SIM картгүй."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Утсанд SIM карт байхгүй."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM картыг оруулна уу."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM карт байхгүй эсвэл унших боломжгүй. SIM карт оруулна уу."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Ашиглаж болохгүй SIM карт."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Таны SIM карт бүрмөсөн идэвхгүй болов.\n Өөр SIM карт авах бол өөрийн утасгүй үйлчилгээний нийлүүлэгчтэй холбогдоно уу."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM карт түгжигдсэн."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM картны PUK-түгжигдсэн."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM картны түгжээг гаргаж байна…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d. -н %2$d виджет"</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Виджет нэмэх."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Хоосон"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Тайлах хэсэг нээгдсэн."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Тайлах хэсэг хаагдсан."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> виджет."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Хэрэглэгч сонгоч"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Статус"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Камер"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Медиа контрол"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Виджет дахин эрэмбэлж эхлэв."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Виджетийг дахин эрэмбэлж дуусав."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> виджет устсан."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Түгжээгүй хэсгийг өргөсгөх."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Тайлах гулсуулалт."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Тайлах хээ."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Нүүрээр тайлах"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Тайлах пин."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Тайлах нууц үг."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Хээний хэсэг."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Гулсуулах хэсэг."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Өмнөх бичлэг товч"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Дараагийн бичлэг товч"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Түр зогсоох товч"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Тоглуулах товч"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Зогсоох товч"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Цуцлах"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Устгах"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Дуусгах"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Горим өөрчлөх"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Шифт"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Оруулах"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Тайлах"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Камер"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Чимээгүй"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Дуунууд идэвхтэй"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Хайх"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-г гулсуулах."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх бол доош гулсуулах."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх зүүнлүү гулсуулах."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх бол баруунлуу гулсуулах."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Одоогийн хэрэглэгч <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Яаралтай дуудлага"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Хээг мартсан"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Буруу хээ"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Нууц үг буруу"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN буруу"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Хээг зурах"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN оруулна уу"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN оруулна уу"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Нууц үгээ оруулна уу"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM идэвхгүй байна. Үргэлжлүүлэх бол PUK кодыг оруулна уу. Дэлгэрэнгүй мэдээллийг оператороос асууна ууу"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Хүссэн PIN кодоо оруулна уу"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Хүссэн PIN кодоо дахин оруулна уу"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM картны түгжээг гаргаж байна…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Буруу PIN код."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-8 тооноос бүтэх PIN-г бичнэ үү."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK код 8-с цөөнгүй тооноос бүтнэ."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Зөв PUK кодыг дахин оруулна уу. Давтан оролдвол SIM нь бүрмөсөн идэвхгүй болгоно."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN кодууд таарахгүй байна"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Хээ оруулах оролдлого хэт олон"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Түгжээг тайлах бол Google акаунтаараа нэвтэрнэ үү."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Хэрэглэгчийн нэр (имэйл)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Нууц үг"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Нэвтрэх"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Хэрэглэгчийн нэр эсвэл нууц үг буруу."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Хэрэглэгчийн нэр нууц үгээ мартсан уу?\n"<b>"google.com/accounts/recovery"</b>"-д зочилно уу."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Акаунт шалгаж байна…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Та PIN кодоо <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Та PIN кодоо <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Та таблетыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол таблет үйлдвэрийн үндсэн утгаараа тохируулагдах ба хэрэглэгчийн дата бүхэлдээ устана."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Та утсыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол утас үйлдвэрийн үндсэн утгаараа тохируулагдах ба хэрэглэгчийн дата бүхэлдээ устана."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Та таблетыг тайлах гэж <xliff:g id="NUMBER">%d</xliff:g> удаа буруу оролдлоо. Таблет одоо үйлдвэрийн үндсэн утгаараа тохируулагдах болно."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Та утсыг тайлах гэж <xliff:g id="NUMBER">%d</xliff:g> удаа буруу оролдлоо. Утас одоо үйлдвэрийн үндсэн утгаараа тохируулагдах болно."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та таблетаа тайлахын тулд имэйл акаунт шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та утсаа тайлахын тулд имэйл акаунтаа ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Устгах"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Өмнөх дуу товч"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Дараагийн дуу товч"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Түр зогсох товч"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Тоглуулах товч"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Зогсоох товч"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Үйлчилгээ байхгүй."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-nb/strings.xml b/packages/Keyguard/res/values-nb/strings.xml
index c25a772..71138a5 100644
--- a/packages/Keyguard/res/values-nb/strings.xml
+++ b/packages/Keyguard/res/values-nb/strings.xml
@@ -117,7 +117,7 @@
     <string name="kg_invalid_puk" msgid="3638289409676051243">"Skriv inn den korrekte PUK-koden på nytt. Gjentatte forsøk kommer til å deaktivere SIM-kortet."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-kodene stemmer ikke overens"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"For mange forsøk på tegning av mønster"</string>
-    <string name="kg_login_instructions" msgid="1100551261265506448">"Logg deg på med Google-kontoen din for å låse opp."</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Logg på med Google-kontoen din for å låse opp."</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"Brukernavn (e-postadresse)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Passord"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Logg på"</string>
diff --git a/packages/Keyguard/res/values-ne-rNP/strings.xml b/packages/Keyguard/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..0fa1182
--- /dev/null
+++ b/packages/Keyguard/res/values-ne-rNP/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN कोड टाइप गर्नुहोस्"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK र नयाँ PIN कोड टाइप गर्नुहोस्"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK कोड"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"नयाँ PIN कोड"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"पासवर्ड टाइप गर्न छुनुहोस्"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"अनलक गर्न पासवर्ड टाइप गर्नुहोस्।"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"अनलक गर्न PIN कोड टाइप गर्नुहोस्"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"गलत PIN कोड।"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"अनलक गर्न मेनु थिच्नुहोस् र त्यसपछि ० थिच्नुहोस्।"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"अत्याधिक मोहडा खोल्ने प्रयासहरू बढी भए।"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"चार्ज भयो"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"चार्ज गर्दै, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"तपाईँको चार्जर जोड्नुहोस्।"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"अनलक गर्न मेनु थिच्नुहोस्।"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"नेटवर्क लक गरिएको छ"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM कार्ड छैन"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ट्याब्लेटमा SIM कार्ड छैन।"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"फोनमा कुनै SIM कार्ड छैन।"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM कार्ड भित्र राख्नुहोस्।"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM कार्ड हराइरहेको छ वा पढ्न योग्य छैन। SIM कार्ड हाल्नुहोस्।"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"प्रयोग अयोग्य SIM कार्ड।"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"तपाईँको SIM कार्ड स्थायी रूपमा असक्षम पारिएको छ।\n अर्को SIM कार्डको लागि तपाईँको ताररहित सेवा प्रदायकसँग सम्पर्क गर्नुहोस्।"</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM कार्ड लक गरियो।"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM कार्ड PUK-लक छ।"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM कार्ड अनलक हुँदै…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. विजेट %2$d of %3$d।"</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"विजेट थप गर्नुहोस्।"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"खाली"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"अनलक क्षेत्र विस्तार भयो।"</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"अनलक क्षेत्र भत्कियो।"</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> विजेट।"</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"प्रयोगकर्ता छनौटकर्ता"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"स्थिति"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"क्यामेरा"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"मिडिया नियन्त्रणहरू"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"विजेट पुनःक्रम गर्ने सुरु भयो।"</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"विजेट पुनःक्रम समाप्त भएको छ।"</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"विजेट <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> मेटाइयो।"</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"अनलक क्षेत्र बढाउनुहोस्।"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"स्लाइड अनलक।"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ढाँचा अनलक।"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"फेस अनलक"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin अनलक"</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"पासवर्ड अनलक।"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ढाँचा क्षेत्र।"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"स्लाइड क्षेत्र।"</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"अघिल्लो पथ बटन"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"अर्को पथ बटन"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"रोक्ने बटन"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"बजाउने बटन"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"बटन रोक्नुहोस्"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?१२३"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"रद्द गर्नुहोस्"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"मेट्नुहोस्"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"भयो"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"मोड परिवर्तन गर्नुहोस्"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"प्रविष्टि गर्नुहोस्"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"अनलक गर्नुहोस्"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"क्यामेरा"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"मौन"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"आवाज चालू"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"खोज्नुहोस्"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि माथि धिसार्नुहोस्"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> को लागि तल स्लाइड गर्नुहोस्।"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"स्लाइड <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि बायाँ।"</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"स्लाइड <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि दायाँ।"</string>
+    <string name="user_switched" msgid="3768006783166984410">"अहिलेको प्रयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>।"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"आपतकालीन कल"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ढाँचा बिर्सनु भयो"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"गलत ढाँचा"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"गलत पासवर्ड"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"गलत PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g>सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"आफ्नो ढाँचा कोर्नुहोस्"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN प्रविष्टि गर्नुहोस्"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN प्रविष्टि गर्नुहोस्"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"पासवर्ड प्रविष्टि गर्नुहोस्"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM कार्ड अहिले असक्षम छ। सुचारु गर्नको लागि PUK कोड प्रविष्टि गर्नुहोस्।  विवरणको लागि वाहकलाई सम्पर्क गर्नुहोस्।"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"इच्छित PIN कोड प्रविष्टि गर्नुहोस्"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"मनपर्दो PIN कोड निश्चित गर्नुहोस्"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM कार्ड अनलक गर्दै…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"गलत PIN कोड।"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"४ देखि ८ वाट नम्बर भएको एउटा PIN टाइप गर्नुहोस्।"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK कोड ८ वटा नम्बर वा सो भन्दा बढी हुनुपर्छ।"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"PUK कोड पुन:प्रदान गर्नुहोस्। धेरै पुन:प्रयासहरूले SIMलाई स्थायी रूपमा निष्क्रिय गरिदिने छ।"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN कोडहरू मेल खाएन"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"निकै धेरै ढाँचा कोसिसहरू"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"अनलक गर्नको लागि, तपाईँको Google खाताको साथ साइन इन गर्नुहोस्।"</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"प्रयोगकर्ता नाम (इमेल)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"पासवर्ड"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"साइन इन गर्नुहोस्"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"अमान्य प्रयोगकर्तानाम वा पासवर्ड।"</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"के तपाईँले उपयोगकर्ता नाम वा पासवर्ड बिर्सनुभयो?\n"<b>"google.com/accounts/recovery"</b>" मा जानुहोस्।"</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"खाता जाँच हुँदै…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"तपाईँले तपाईँक पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> पटक गलत टाइप गर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"तपाईँले तपाईँको अनलक ढाँचा गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"तपाईँले ट्याब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक कोसिस गर्नु भएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> पछि थप असफल प्रयासहरू, ट्याब्लेट पूर्वनिर्धारित कार्यशालामा पुनःसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"तपाईँले गलतसँग फोनलाई अनलक गर्न <xliff:g id="NUMBER_0">%d</xliff:g> पटक कोसिस गर्नु भयो। <xliff:g id="NUMBER_1">%d</xliff:g> पछि थप असफल कोसिसहरू, फोनलाई पूर्वनिर्धारित कार्यशालामा पुनःसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"तपाईँले ट्यब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER">%d</xliff:g> पटक प्रयास गर्नु भएको छ। अब ट्याब्लेटलाई पूर्वनिर्धारित कार्यशालामा पुनःसेट गरिने छ।"</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"तपाईंले गलत तरिकाले फोन <xliff:g id="NUMBER">%d</xliff:g> पटक अनलक गर्ने प्रयत्न गर्नुभयो। अब फोन फ्याक्ट्रि पूर्वनिर्धारितमा पुनःसेट हुने छ।"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"तपाईंले गलत तरिकाले आफ्नो अनलक ढाँचा <xliff:g id="NUMBER_0">%d</xliff:g> पटक कोर्नुभयो। <xliff:g id="NUMBER_1">%d</xliff:g> विफल प्रयत्नहरू पछि, तपाईंलाई आफ्नो ट्याब्लेट इमेल खाता प्रयोग गरेर अनलक गर्न सोधिने छ।\n\n फेरि प्रयास गर्नुहोस् <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डहरूमा।"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"तपाईँले आफ्नो अनलक ढाँचा गलत रूपमा <xliff:g id="NUMBER_0">%d</xliff:g> पटक तान्नु भएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> धेरै असफल प्रयासहरूपछि, तपाईँलाई एउटा इमेल खाताको प्रयोग गरेर तपाईँको फोन अनलक गर्न सोधिने छ।\n\n फेरि <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डमा प्रयास गर्नुहोस्।"</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"हटाउनुहोस्"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"अघिल्लो ट्रयाक बटन"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"अर्को ट्रयाक बटन"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"रोक्ने बटन"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"बटन बजाउनुहोस्"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"बटन रोक्नुहोस्"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"कुनै सेवा छैन।"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ne/strings.xml b/packages/Keyguard/res/values-ne/strings.xml
new file mode 100644
index 0000000..0fa1182
--- /dev/null
+++ b/packages/Keyguard/res/values-ne/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN कोड टाइप गर्नुहोस्"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK र नयाँ PIN कोड टाइप गर्नुहोस्"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK कोड"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"नयाँ PIN कोड"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"पासवर्ड टाइप गर्न छुनुहोस्"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"अनलक गर्न पासवर्ड टाइप गर्नुहोस्।"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"अनलक गर्न PIN कोड टाइप गर्नुहोस्"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"गलत PIN कोड।"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"अनलक गर्न मेनु थिच्नुहोस् र त्यसपछि ० थिच्नुहोस्।"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"अत्याधिक मोहडा खोल्ने प्रयासहरू बढी भए।"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"चार्ज भयो"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"चार्ज गर्दै, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"तपाईँको चार्जर जोड्नुहोस्।"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"अनलक गर्न मेनु थिच्नुहोस्।"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"नेटवर्क लक गरिएको छ"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM कार्ड छैन"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ट्याब्लेटमा SIM कार्ड छैन।"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"फोनमा कुनै SIM कार्ड छैन।"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM कार्ड भित्र राख्नुहोस्।"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM कार्ड हराइरहेको छ वा पढ्न योग्य छैन। SIM कार्ड हाल्नुहोस्।"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"प्रयोग अयोग्य SIM कार्ड।"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"तपाईँको SIM कार्ड स्थायी रूपमा असक्षम पारिएको छ।\n अर्को SIM कार्डको लागि तपाईँको ताररहित सेवा प्रदायकसँग सम्पर्क गर्नुहोस्।"</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM कार्ड लक गरियो।"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM कार्ड PUK-लक छ।"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM कार्ड अनलक हुँदै…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. विजेट %2$d of %3$d।"</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"विजेट थप गर्नुहोस्।"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"खाली"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"अनलक क्षेत्र विस्तार भयो।"</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"अनलक क्षेत्र भत्कियो।"</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> विजेट।"</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"प्रयोगकर्ता छनौटकर्ता"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"स्थिति"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"क्यामेरा"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"मिडिया नियन्त्रणहरू"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"विजेट पुनःक्रम गर्ने सुरु भयो।"</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"विजेट पुनःक्रम समाप्त भएको छ।"</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"विजेट <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> मेटाइयो।"</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"अनलक क्षेत्र बढाउनुहोस्।"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"स्लाइड अनलक।"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ढाँचा अनलक।"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"फेस अनलक"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin अनलक"</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"पासवर्ड अनलक।"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ढाँचा क्षेत्र।"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"स्लाइड क्षेत्र।"</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"अघिल्लो पथ बटन"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"अर्को पथ बटन"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"रोक्ने बटन"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"बजाउने बटन"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"बटन रोक्नुहोस्"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?१२३"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"रद्द गर्नुहोस्"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"मेट्नुहोस्"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"भयो"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"मोड परिवर्तन गर्नुहोस्"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"प्रविष्टि गर्नुहोस्"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"अनलक गर्नुहोस्"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"क्यामेरा"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"मौन"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"आवाज चालू"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"खोज्नुहोस्"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि माथि धिसार्नुहोस्"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> को लागि तल स्लाइड गर्नुहोस्।"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"स्लाइड <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि बायाँ।"</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"स्लाइड <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि दायाँ।"</string>
+    <string name="user_switched" msgid="3768006783166984410">"अहिलेको प्रयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>।"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"आपतकालीन कल"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ढाँचा बिर्सनु भयो"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"गलत ढाँचा"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"गलत पासवर्ड"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"गलत PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g>सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"आफ्नो ढाँचा कोर्नुहोस्"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN प्रविष्टि गर्नुहोस्"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN प्रविष्टि गर्नुहोस्"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"पासवर्ड प्रविष्टि गर्नुहोस्"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM कार्ड अहिले असक्षम छ। सुचारु गर्नको लागि PUK कोड प्रविष्टि गर्नुहोस्।  विवरणको लागि वाहकलाई सम्पर्क गर्नुहोस्।"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"इच्छित PIN कोड प्रविष्टि गर्नुहोस्"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"मनपर्दो PIN कोड निश्चित गर्नुहोस्"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM कार्ड अनलक गर्दै…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"गलत PIN कोड।"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"४ देखि ८ वाट नम्बर भएको एउटा PIN टाइप गर्नुहोस्।"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK कोड ८ वटा नम्बर वा सो भन्दा बढी हुनुपर्छ।"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"PUK कोड पुन:प्रदान गर्नुहोस्। धेरै पुन:प्रयासहरूले SIMलाई स्थायी रूपमा निष्क्रिय गरिदिने छ।"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN कोडहरू मेल खाएन"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"निकै धेरै ढाँचा कोसिसहरू"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"अनलक गर्नको लागि, तपाईँको Google खाताको साथ साइन इन गर्नुहोस्।"</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"प्रयोगकर्ता नाम (इमेल)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"पासवर्ड"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"साइन इन गर्नुहोस्"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"अमान्य प्रयोगकर्तानाम वा पासवर्ड।"</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"के तपाईँले उपयोगकर्ता नाम वा पासवर्ड बिर्सनुभयो?\n"<b>"google.com/accounts/recovery"</b>" मा जानुहोस्।"</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"खाता जाँच हुँदै…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"तपाईँले तपाईँक पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> पटक गलत टाइप गर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"तपाईँले तपाईँको अनलक ढाँचा गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"तपाईँले ट्याब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक कोसिस गर्नु भएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> पछि थप असफल प्रयासहरू, ट्याब्लेट पूर्वनिर्धारित कार्यशालामा पुनःसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"तपाईँले गलतसँग फोनलाई अनलक गर्न <xliff:g id="NUMBER_0">%d</xliff:g> पटक कोसिस गर्नु भयो। <xliff:g id="NUMBER_1">%d</xliff:g> पछि थप असफल कोसिसहरू, फोनलाई पूर्वनिर्धारित कार्यशालामा पुनःसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"तपाईँले ट्यब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER">%d</xliff:g> पटक प्रयास गर्नु भएको छ। अब ट्याब्लेटलाई पूर्वनिर्धारित कार्यशालामा पुनःसेट गरिने छ।"</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"तपाईंले गलत तरिकाले फोन <xliff:g id="NUMBER">%d</xliff:g> पटक अनलक गर्ने प्रयत्न गर्नुभयो। अब फोन फ्याक्ट्रि पूर्वनिर्धारितमा पुनःसेट हुने छ।"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"तपाईंले गलत तरिकाले आफ्नो अनलक ढाँचा <xliff:g id="NUMBER_0">%d</xliff:g> पटक कोर्नुभयो। <xliff:g id="NUMBER_1">%d</xliff:g> विफल प्रयत्नहरू पछि, तपाईंलाई आफ्नो ट्याब्लेट इमेल खाता प्रयोग गरेर अनलक गर्न सोधिने छ।\n\n फेरि प्रयास गर्नुहोस् <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डहरूमा।"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"तपाईँले आफ्नो अनलक ढाँचा गलत रूपमा <xliff:g id="NUMBER_0">%d</xliff:g> पटक तान्नु भएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> धेरै असफल प्रयासहरूपछि, तपाईँलाई एउटा इमेल खाताको प्रयोग गरेर तपाईँको फोन अनलक गर्न सोधिने छ।\n\n फेरि <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डमा प्रयास गर्नुहोस्।"</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"हटाउनुहोस्"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"अघिल्लो ट्रयाक बटन"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"अर्को ट्रयाक बटन"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"रोक्ने बटन"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"बटन बजाउनुहोस्"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"बटन रोक्नुहोस्"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"कुनै सेवा छैन।"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-si-rLK/strings.xml b/packages/Keyguard/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..8904c7e
--- /dev/null
+++ b/packages/Keyguard/res/values-si-rLK/strings.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN කේතය ටයිප් කරන්න"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK සහ නව PIN කේතය ටයිප් කරන්න"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK කේතය"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"නව PIN කේතය"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"මුරපදය ටයිප් කිරීමට ස්පර්ශ කරන්න"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"අගුළු ඇරීමට මුරපදය ටයිප් කරන්න"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"අගුළු හැරීමට PIN එක ටයිප් කරන්න"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"වැරදි PIN කේතයකි."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"අගුළු ඇරීමට, මෙනුව ඔබා පසුව 0 ද ඔබන්න."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"මුහුණ භාවිතයෙන් අඟුළු හැරීමේ උපරිම ප්‍රයන්තයන් ගණන ඉක්මවා ඇත"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"අරෝපිතයි"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"ආරෝපණය වෙමින්, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"ඔබගේ ආරෝපකයට සම්බන්ධ කරන්න."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"අගුළු ඇරීමට මෙනුව ඔබන්න."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"ජාල අගුළු දමා ඇත"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM පත නොමැත"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ටැබ්ලටයේ SIM පත නොමැත."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"දුරකථනය තුල SIM පතක් නැත."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM පත ඇතුල් කරන්න."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM පත නොමැත හෝ කියවිය නොහැක. SIM පතක් ඇතුල් කරන්න."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"භාවිතා කළ නොහැකි SIM පත."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"ඔබගේ SIM පත ස්ථිරව අබල කර ඇත.\n වෙනත් SIM පතක් සඳහා ඔබගේ නොරැහැන් සේවා සැපයුම්කරු සම්බන්ධ කරගන්න."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM පත අගුළු දමා ඇත."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM පත PUK අගුළු ලා ඇත."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM පත අගුළු හරිමින්..."</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for keyguard_accessibility_widget_changed (5678624624681400191) -->
+    <skip />
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"විජටය එකතු කරන්න."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"හිස්"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"අගුළු අරින ප්‍රදේශය විදහා ඇත."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"අගුළු අරින ප්‍රදේශය හැකිලී ඇත."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> විජට්."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"පරිශීලක තෝරන්නා"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"තත්වය"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"කැමරාව"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"මාධ්‍ය පාලක"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"විජටය නැවත අනුපිළිවෙළට සැකසිම ඇරඹුණි."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"විජට් නැවත අනුපිළිවෙලට සැකසීම අවසානය."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> විජටය මැකී ඇත."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"අගුළු නොදැමූ ප්‍රදේශය පුළුල් කරන්න."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"සර්පණ අගුළු ඇරීම."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"රටා අගුළු ඇරීම."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"මුහුණ භාවිතයෙන් අඟුළු හැරීම."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN අගුළු ඇරීම."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"මුරපද අගුළු ඇරීම."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"රටා ප්‍රදේශය."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"සර්පණ ප්‍රදේශය."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"පෙර ගීත බොත්තම"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"ඉදිරි ගීත බොත්තම"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"විරාම බොත්තම"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"ධාවක බොත්තම"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"නැවතීමේ බොත්තම"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"අවලංගු කරන්න"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"මකන්න"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"හරි"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ආකාරය වෙනස් කරන්න"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"ඇතුල් කරන්න"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"අඟුල අරින්න"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"කැමරාව"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"නිහඬ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ශබ්ද සක්‍රීය කරන්න"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"සෙවීම"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා උඩට සර්පණය කරන්න."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා පහලට සර්පණය කරන්න."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා වමට සර්පණය කරන්න."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා දකුණට සර්පණය කරන්න."</string>
+    <string name="user_switched" msgid="3768006783166984410">"දැනට සිටින පරිශීලකයා <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"හදිසි ඇමතුම"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"රටාව අමතකයි"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"වැරදි රටාවකි"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"වැරදි මුරපදය"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN එක වැරදියි"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"තත්පර <xliff:g id="NUMBER">%d</xliff:g> ට පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"ඔබගේ රටාව අඳින්න"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN ඇතුලු කරන්න"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN එක ඇතුළු කරන්න"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"මුරපදය ඇතුළු කරන්න"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"දැන් SIM එක අබල කර ඇත. ඉදිරියට යාමට PUK කේතය යොදන්න. විස්තර සඳහා වාහකයා අමතන්න."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"අපේක්ෂිත PIN කේතය ඇතුළත් කරන්න"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"අපේක්ෂිත PIN කේතය ස්ථිර කරන්න"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM පත අගුළු අරිමින්..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"වැරදි PIN කේතයකි."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"අංක 4 සිට 8 අතර වන PIN එකක් ටයිප් කරන්න."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK කේතය සංඛ්‍යා 8 ක් හෝ වැඩි විය යුතුය."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"නිවැරදි PUK කේතය නැවත ඇතුලත් කරන්න. නැවත නැවත උත්සාහ කිරීමෙන් SIM එක ස්ථිරවම අබල කරයි."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN කේත ගැලපී නැත"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"රටා උත්සාහ කිරීම් වැඩිය"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"අගුළු ඇරීමට, ඔබගේ Google ගිණුම සමග පුරනය වන්න."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"පරිශීලක නාමය (ඊ-තැපෑල)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"මුරපදය"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"පුරනය වන්න"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"වලංගු නොවන පරිශීලක නාමයක් හෝ මුරපදයක්."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ඔබගේ පරිශීලක නාමය හෝ මුරපදය අමතකද?\n "<b>"google.com/accounts/recovery"</b>" වෙත යන්න."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"ගිණුම පරීක්ෂා කරමින්…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ඔබ PIN අංකය <xliff:g id="NUMBER_0">%d</xliff:g> වාරයක් වැරදියට ටයිප් කොට ඇත.\n\n තත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ මුරපදය ඔබ වැරදියට ටයිප් කර ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ට පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ඔබ <xliff:g id="NUMBER_0">%d</xliff:g> වාරයක් අගුළු ඇරීමේ රටාව වැරදියට ඇඳ ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ඔබ ටැබ්ලටය අගුළු හැරීමට වැරදියට අවස්ථා <xliff:g id="NUMBER_0">%d</xliff:g> ක් උත්සාහ කර ඇත. අවස්ථා <xliff:g id="NUMBER_1">%d</xliff:g> ක් අසාර්ථකව උත්සහ කිරීමකින් පසුව, කර්මාන්ත ශාලා මුල් තත්වයට නැවත පත් වන අතර සියලු පරිශීලක දත්ත නැති වෙයි."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ඔබ දුරකථනය අගුළු ඇරීමට වාර <xliff:g id="NUMBER_0">%d</xliff:g> කදී වැරදී ප්‍රයත්නයන් ගෙන තිබේ. තවත් අසාර්ථක ප්‍රයත්න <xliff:g id="NUMBER_1">%d</xliff:g> කින් පසුව, දුරකථනය කර්මාන්ත ශාලාවේ සුපුරුද්දට යළි පිහිටුවන අතර සියලුම පරිශීලක දත්ත නැති වී යයි."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"ටැබ්ලටයේ අගුළු ඇරීමට ඔබ වැරදි ප්‍රයත්න <xliff:g id="NUMBER">%d</xliff:g> වාරයක් ගෙන ඇත. දැන් ටැබ්ලටය කර්මාන්ත ශාලා සුපුරුද්ද වෙත යළි පිහිටුවීම කෙරේ."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"ඔබ දුරකථනය අගුළු ඇරීමට වාර <xliff:g id="NUMBER">%d</xliff:g> කදී වැරදී ප්‍රයන්තයන් ගෙන තිබේ. දැන් දුරකථනය කර්මාන්තශාලා සුපුරුද්දට පිහිටුවනු ලබයි."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"ඔබ අගුළු ඇරිමේ රටාව <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් වැරදියට ඇඳ ඇත. තවත් අසාර්ථක උත්සාහ <xliff:g id="NUMBER_1">%d</xliff:g> කින් පසුව, ඊ-තැපැල් ගිණුම භාවිතා කරමින් ඔබගේ ටැබ්ලටයේ අගුළු ඇරීමට ඔබට පවසනු ඇත.\n\n නැවත තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> කින් උත්සාහ කරන්න."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%d</xliff:g> න් පසුව, ඔබගේ ඊ-තැපැල් ලිපිනය භාවිතයෙන් ඔබගේ දුරකථනය අගුළු හැරීමට ඔබගෙන් අසයි.\n\n තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> න් පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"ඉවත් කරන්න"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"පෙර ගීත බොත්තම"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"ඉදිරි ගීත යතුර"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"විරාම බොත්තම"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"ධාවන බොත්තම"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"නැවතුම් බොත්තම"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"සේවාව නැත."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-si/strings.xml b/packages/Keyguard/res/values-si/strings.xml
new file mode 100644
index 0000000..8904c7e
--- /dev/null
+++ b/packages/Keyguard/res/values-si/strings.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN කේතය ටයිප් කරන්න"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK සහ නව PIN කේතය ටයිප් කරන්න"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK කේතය"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"නව PIN කේතය"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"මුරපදය ටයිප් කිරීමට ස්පර්ශ කරන්න"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"අගුළු ඇරීමට මුරපදය ටයිප් කරන්න"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"අගුළු හැරීමට PIN එක ටයිප් කරන්න"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"වැරදි PIN කේතයකි."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"අගුළු ඇරීමට, මෙනුව ඔබා පසුව 0 ද ඔබන්න."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"මුහුණ භාවිතයෙන් අඟුළු හැරීමේ උපරිම ප්‍රයන්තයන් ගණන ඉක්මවා ඇත"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"අරෝපිතයි"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"ආරෝපණය වෙමින්, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"ඔබගේ ආරෝපකයට සම්බන්ධ කරන්න."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"අගුළු ඇරීමට මෙනුව ඔබන්න."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"ජාල අගුළු දමා ඇත"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM පත නොමැත"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ටැබ්ලටයේ SIM පත නොමැත."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"දුරකථනය තුල SIM පතක් නැත."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM පත ඇතුල් කරන්න."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM පත නොමැත හෝ කියවිය නොහැක. SIM පතක් ඇතුල් කරන්න."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"භාවිතා කළ නොහැකි SIM පත."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"ඔබගේ SIM පත ස්ථිරව අබල කර ඇත.\n වෙනත් SIM පතක් සඳහා ඔබගේ නොරැහැන් සේවා සැපයුම්කරු සම්බන්ධ කරගන්න."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM පත අගුළු දමා ඇත."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM පත PUK අගුළු ලා ඇත."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM පත අගුළු හරිමින්..."</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for keyguard_accessibility_widget_changed (5678624624681400191) -->
+    <skip />
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"විජටය එකතු කරන්න."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"හිස්"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"අගුළු අරින ප්‍රදේශය විදහා ඇත."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"අගුළු අරින ප්‍රදේශය හැකිලී ඇත."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> විජට්."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"පරිශීලක තෝරන්නා"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"තත්වය"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"කැමරාව"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"මාධ්‍ය පාලක"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"විජටය නැවත අනුපිළිවෙළට සැකසිම ඇරඹුණි."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"විජට් නැවත අනුපිළිවෙලට සැකසීම අවසානය."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> විජටය මැකී ඇත."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"අගුළු නොදැමූ ප්‍රදේශය පුළුල් කරන්න."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"සර්පණ අගුළු ඇරීම."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"රටා අගුළු ඇරීම."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"මුහුණ භාවිතයෙන් අඟුළු හැරීම."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN අගුළු ඇරීම."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"මුරපද අගුළු ඇරීම."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"රටා ප්‍රදේශය."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"සර්පණ ප්‍රදේශය."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"පෙර ගීත බොත්තම"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"ඉදිරි ගීත බොත්තම"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"විරාම බොත්තම"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"ධාවක බොත්තම"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"නැවතීමේ බොත්තම"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"අවලංගු කරන්න"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"මකන්න"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"හරි"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ආකාරය වෙනස් කරන්න"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"ඇතුල් කරන්න"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"අඟුල අරින්න"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"කැමරාව"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"නිහඬ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ශබ්ද සක්‍රීය කරන්න"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"සෙවීම"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා උඩට සර්පණය කරන්න."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා පහලට සර්පණය කරන්න."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා වමට සර්පණය කරන්න."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා දකුණට සර්පණය කරන්න."</string>
+    <string name="user_switched" msgid="3768006783166984410">"දැනට සිටින පරිශීලකයා <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"හදිසි ඇමතුම"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"රටාව අමතකයි"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"වැරදි රටාවකි"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"වැරදි මුරපදය"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN එක වැරදියි"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"තත්පර <xliff:g id="NUMBER">%d</xliff:g> ට පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"ඔබගේ රටාව අඳින්න"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN ඇතුලු කරන්න"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN එක ඇතුළු කරන්න"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"මුරපදය ඇතුළු කරන්න"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"දැන් SIM එක අබල කර ඇත. ඉදිරියට යාමට PUK කේතය යොදන්න. විස්තර සඳහා වාහකයා අමතන්න."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"අපේක්ෂිත PIN කේතය ඇතුළත් කරන්න"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"අපේක්ෂිත PIN කේතය ස්ථිර කරන්න"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM පත අගුළු අරිමින්..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"වැරදි PIN කේතයකි."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"අංක 4 සිට 8 අතර වන PIN එකක් ටයිප් කරන්න."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK කේතය සංඛ්‍යා 8 ක් හෝ වැඩි විය යුතුය."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"නිවැරදි PUK කේතය නැවත ඇතුලත් කරන්න. නැවත නැවත උත්සාහ කිරීමෙන් SIM එක ස්ථිරවම අබල කරයි."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN කේත ගැලපී නැත"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"රටා උත්සාහ කිරීම් වැඩිය"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"අගුළු ඇරීමට, ඔබගේ Google ගිණුම සමග පුරනය වන්න."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"පරිශීලක නාමය (ඊ-තැපෑල)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"මුරපදය"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"පුරනය වන්න"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"වලංගු නොවන පරිශීලක නාමයක් හෝ මුරපදයක්."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ඔබගේ පරිශීලක නාමය හෝ මුරපදය අමතකද?\n "<b>"google.com/accounts/recovery"</b>" වෙත යන්න."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"ගිණුම පරීක්ෂා කරමින්…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ඔබ PIN අංකය <xliff:g id="NUMBER_0">%d</xliff:g> වාරයක් වැරදියට ටයිප් කොට ඇත.\n\n තත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ මුරපදය ඔබ වැරදියට ටයිප් කර ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ට පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ඔබ <xliff:g id="NUMBER_0">%d</xliff:g> වාරයක් අගුළු ඇරීමේ රටාව වැරදියට ඇඳ ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ඔබ ටැබ්ලටය අගුළු හැරීමට වැරදියට අවස්ථා <xliff:g id="NUMBER_0">%d</xliff:g> ක් උත්සාහ කර ඇත. අවස්ථා <xliff:g id="NUMBER_1">%d</xliff:g> ක් අසාර්ථකව උත්සහ කිරීමකින් පසුව, කර්මාන්ත ශාලා මුල් තත්වයට නැවත පත් වන අතර සියලු පරිශීලක දත්ත නැති වෙයි."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ඔබ දුරකථනය අගුළු ඇරීමට වාර <xliff:g id="NUMBER_0">%d</xliff:g> කදී වැරදී ප්‍රයත්නයන් ගෙන තිබේ. තවත් අසාර්ථක ප්‍රයත්න <xliff:g id="NUMBER_1">%d</xliff:g> කින් පසුව, දුරකථනය කර්මාන්ත ශාලාවේ සුපුරුද්දට යළි පිහිටුවන අතර සියලුම පරිශීලක දත්ත නැති වී යයි."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"ටැබ්ලටයේ අගුළු ඇරීමට ඔබ වැරදි ප්‍රයත්න <xliff:g id="NUMBER">%d</xliff:g> වාරයක් ගෙන ඇත. දැන් ටැබ්ලටය කර්මාන්ත ශාලා සුපුරුද්ද වෙත යළි පිහිටුවීම කෙරේ."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"ඔබ දුරකථනය අගුළු ඇරීමට වාර <xliff:g id="NUMBER">%d</xliff:g> කදී වැරදී ප්‍රයන්තයන් ගෙන තිබේ. දැන් දුරකථනය කර්මාන්තශාලා සුපුරුද්දට පිහිටුවනු ලබයි."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"ඔබ අගුළු ඇරිමේ රටාව <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් වැරදියට ඇඳ ඇත. තවත් අසාර්ථක උත්සාහ <xliff:g id="NUMBER_1">%d</xliff:g> කින් පසුව, ඊ-තැපැල් ගිණුම භාවිතා කරමින් ඔබගේ ටැබ්ලටයේ අගුළු ඇරීමට ඔබට පවසනු ඇත.\n\n නැවත තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> කින් උත්සාහ කරන්න."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%d</xliff:g> න් පසුව, ඔබගේ ඊ-තැපැල් ලිපිනය භාවිතයෙන් ඔබගේ දුරකථනය අගුළු හැරීමට ඔබගෙන් අසයි.\n\n තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> න් පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"ඉවත් කරන්න"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"පෙර ගීත බොත්තම"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"ඉදිරි ගීත යතුර"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"විරාම බොත්තම"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"ධාවන බොත්තම"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"නැවතුම් බොත්තම"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"සේවාව නැත."</string>
+</resources>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java b/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java
index 63b61ad..0e08cf4 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java
@@ -29,8 +29,6 @@
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 
-import android.util.Log;
-
 class KeyguardCircleFramedDrawable extends Drawable {
 
     private final Bitmap mBitmap;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
index 751572c..2e4dbdf 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
@@ -23,16 +23,10 @@
 import android.content.Context;
 import android.os.BatteryManager;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Looper;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.AttributeSet;
-import android.util.Slog;
 import android.view.View;
 import android.widget.TextView;
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
index 3d1c3f3..ca2d615 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
@@ -17,7 +17,6 @@
 package com.android.keyguard;
 
 import android.content.Context;
-import android.text.Editable;
 import android.text.InputType;
 import android.text.TextWatcher;
 import android.text.method.DigitsKeyListener;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
index 4e3568b..e733afc 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
@@ -16,13 +16,10 @@
 
 package com.android.keyguard;
 
-import android.app.admin.DevicePolicyManager;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.text.Editable;
 import android.text.InputType;
 import android.text.TextWatcher;
-import android.text.method.DigitsKeyListener;
 import android.text.method.TextKeyListener;
 import android.util.AttributeSet;
 import android.view.View;
@@ -31,9 +28,6 @@
 import android.view.inputmethod.InputMethodSubtype;
 import android.widget.TextView.OnEditorActionListener;
 
-import com.android.internal.widget.PasswordEntryKeyboardHelper;
-import com.android.internal.widget.PasswordEntryKeyboardView;
-
 import java.util.List;
 /**
  * Displays an alphanumeric (latin-1) key entry for the user to enter
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
index 63be102..718b06e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
@@ -16,19 +16,14 @@
 package com.android.keyguard;
 
 import android.animation.ObjectAnimator;
-import android.app.ActivityManager;
-import android.app.PendingIntent;
 import android.app.SearchManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.PowerManager;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Slog;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
index 9accbb4..ae7ac97 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
@@ -20,16 +20,12 @@
 import com.android.internal.telephony.PhoneConstants;
 
 import android.content.Context;
-import android.content.DialogInterface;
-import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.AlertDialog.Builder;
 import android.app.Dialog;
 import android.app.ProgressDialog;
-import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.text.Editable;
 import android.text.InputType;
 import android.text.TextWatcher;
 import android.text.method.DigitsKeyListener;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
index 6e9e83e..82b5467 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
@@ -17,14 +17,12 @@
 package com.android.keyguard;
 
 import android.content.Context;
-import android.animation.AnimatorSet.Builder;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.ProgressDialog;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.text.Editable;
 import android.text.InputType;
 import android.text.TextWatcher;
 import android.text.method.DigitsKeyListener;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
index 349078f..a7cd909 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
@@ -32,7 +32,6 @@
 import android.media.RemoteController;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.SystemClock;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.transition.ChangeBounds;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index 6aa0a4b..f2853c8 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -16,13 +16,11 @@
 
 package com.android.keyguard;
 
-import android.app.PendingIntent;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
 import com.android.internal.policy.IKeyguardShowCallback;
 import com.android.internal.widget.LockPatternUtils;
 
-import android.app.Activity;
 import android.app.ActivityManager;
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
index 4086f84..e2219d4 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
@@ -16,7 +16,6 @@
 
 package com.android.keyguard;
 
-import android.graphics.Bitmap;
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardShowCallback;
 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
@@ -49,7 +48,6 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
-import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.WindowManager;
 import android.view.WindowManagerPolicy;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
index 169899f..a7b72e2 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
@@ -20,7 +20,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.os.Handler;
 import android.os.Looper;
-import android.util.Log;
 import android.view.View;
 
 public class KeyguardViewStateManager implements
diff --git a/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java b/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java
index 4cfc9dc..340a4d5 100644
--- a/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java
+++ b/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java
@@ -28,7 +28,6 @@
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.View.MeasureSpec;
 import android.widget.LinearLayout;
 
 public class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayout {
diff --git a/packages/PrintSpooler/res/values-be/arrays.xml b/packages/PrintSpooler/res/values-be/arrays.xml
deleted file mode 100644
index d40278c..0000000
--- a/packages/PrintSpooler/res/values-be/arrays.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-
-    <string-array name="pdf_printer_media_sizes" translatable="false">
-        <item>NA_LETTER</item>
-        <item>NA_GOVT_LETTER</item>
-        <item>NA_LEGAL</item>
-        <item>NA_JUNIOR_LEGAL</item>
-        <item>NA_LEDGER</item>
-        <item>NA_TABLOID</item>
-        <item>NA_INDEX_3X5</item>
-        <item>NA_INDEX_4X6</item>
-        <item>NA_INDEX_5X8</item>
-        <item>NA_MONARCH</item>
-        <item>NA_QUARTO</item>
-        <item>NA_FOOLSCAP</item>
-    </string-array>
-
-</resources>
diff --git a/packages/PrintSpooler/res/values-ca/arrays.xml b/packages/PrintSpooler/res/values-ca/arrays.xml
deleted file mode 100644
index d40278c..0000000
--- a/packages/PrintSpooler/res/values-ca/arrays.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-
-    <string-array name="pdf_printer_media_sizes" translatable="false">
-        <item>NA_LETTER</item>
-        <item>NA_GOVT_LETTER</item>
-        <item>NA_LEGAL</item>
-        <item>NA_JUNIOR_LEGAL</item>
-        <item>NA_LEDGER</item>
-        <item>NA_TABLOID</item>
-        <item>NA_INDEX_3X5</item>
-        <item>NA_INDEX_4X6</item>
-        <item>NA_INDEX_5X8</item>
-        <item>NA_MONARCH</item>
-        <item>NA_QUARTO</item>
-        <item>NA_FOOLSCAP</item>
-    </string-array>
-
-</resources>
diff --git a/packages/PrintSpooler/res/values-es-rUS/arrays.xml b/packages/PrintSpooler/res/values-es-rUS/arrays.xml
deleted file mode 100644
index d40278c..0000000
--- a/packages/PrintSpooler/res/values-es-rUS/arrays.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-
-    <string-array name="pdf_printer_media_sizes" translatable="false">
-        <item>NA_LETTER</item>
-        <item>NA_GOVT_LETTER</item>
-        <item>NA_LEGAL</item>
-        <item>NA_JUNIOR_LEGAL</item>
-        <item>NA_LEDGER</item>
-        <item>NA_TABLOID</item>
-        <item>NA_INDEX_3X5</item>
-        <item>NA_INDEX_4X6</item>
-        <item>NA_INDEX_5X8</item>
-        <item>NA_MONARCH</item>
-        <item>NA_QUARTO</item>
-        <item>NA_FOOLSCAP</item>
-    </string-array>
-
-</resources>
diff --git a/packages/PrintSpooler/res/values-ja/arrays.xml b/packages/PrintSpooler/res/values-ja/arrays.xml
index 460bdb2..3187cbe 100644
--- a/packages/PrintSpooler/res/values-ja/arrays.xml
+++ b/packages/PrintSpooler/res/values-ja/arrays.xml
@@ -36,7 +36,6 @@
         <item>JPN_KAHU</item>
         <item>JPN_KAKU2</item>
         <item>JPN_YOU4</item>
-
     </string-array>
 
 </resources>
diff --git a/packages/PrintSpooler/res/values-zh-rCN/arrays.xml b/packages/PrintSpooler/res/values-zh-rCN/arrays.xml
deleted file mode 100644
index 4fc75db..0000000
--- a/packages/PrintSpooler/res/values-zh-rCN/arrays.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-
-    <string-array name="pdf_printer_media_sizes" translatable="false">
-        <item>ROC_8K</item>
-        <item>ROC_16K</item>
-        <item>PRC_1</item>
-        <item>PRC_2</item>
-        <item>PRC_3</item>
-        <item>PRC_4</item>
-        <item>PRC_5</item>
-        <item>PRC_6</item>
-        <item>PRC_7</item>
-        <item>PRC_8</item>
-        <item>PRC_9</item>
-        <item>PRC_10</item>
-        <item>PRC_16K</item>
-        <item>OM_PA_KAI</item>
-        <item>OM_DAI_PA_KAI</item>
-        <item>OM_JUURO_KU_KAI</item>
-    </string-array>
-
-</resources>
diff --git a/packages/SettingsProvider/res/values-az-rAZ/strings.xml b/packages/SettingsProvider/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..a4d0d43
--- /dev/null
+++ b/packages/SettingsProvider/res/values-az-rAZ/strings.xml
@@ -0,0 +1,23 @@
+<?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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Parametrlər Deposu"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-az/strings.xml b/packages/SettingsProvider/res/values-az/strings.xml
new file mode 100644
index 0000000..a4d0d43
--- /dev/null
+++ b/packages/SettingsProvider/res/values-az/strings.xml
@@ -0,0 +1,23 @@
+<?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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Parametrlər Deposu"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-hy/strings.xml b/packages/SettingsProvider/res/values-hy/strings.xml
new file mode 100644
index 0000000..b1f1afb
--- /dev/null
+++ b/packages/SettingsProvider/res/values-hy/strings.xml
@@ -0,0 +1,23 @@
+<?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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Կարգավորումների պահուստ"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-ka/strings.xml b/packages/SettingsProvider/res/values-ka/strings.xml
new file mode 100644
index 0000000..691a2e9
--- /dev/null
+++ b/packages/SettingsProvider/res/values-ka/strings.xml
@@ -0,0 +1,23 @@
+<?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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"პარამეტრების საცავი"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-km/strings.xml b/packages/SettingsProvider/res/values-km/strings.xml
new file mode 100644
index 0000000..7be6242
--- /dev/null
+++ b/packages/SettingsProvider/res/values-km/strings.xml
@@ -0,0 +1,23 @@
+<?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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"កំណត់​ការ​ផ្ទុក"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-lo/strings.xml b/packages/SettingsProvider/res/values-lo/strings.xml
new file mode 100644
index 0000000..4e57936
--- /dev/null
+++ b/packages/SettingsProvider/res/values-lo/strings.xml
@@ -0,0 +1,23 @@
+<?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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"ບ່ອນເກັບຂໍ້ມູນການຕັ້ງຄ່າ"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-mn/strings.xml b/packages/SettingsProvider/res/values-mn/strings.xml
new file mode 100644
index 0000000..9452145
--- /dev/null
+++ b/packages/SettingsProvider/res/values-mn/strings.xml
@@ -0,0 +1,23 @@
+<?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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Тохиргооны Сан"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-ne-rNP/strings.xml b/packages/SettingsProvider/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..af6ef62
--- /dev/null
+++ b/packages/SettingsProvider/res/values-ne-rNP/strings.xml
@@ -0,0 +1,23 @@
+<?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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"सेटिङहरू भण्डारण"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-ne/strings.xml b/packages/SettingsProvider/res/values-ne/strings.xml
new file mode 100644
index 0000000..af6ef62
--- /dev/null
+++ b/packages/SettingsProvider/res/values-ne/strings.xml
@@ -0,0 +1,23 @@
+<?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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"सेटिङहरू भण्डारण"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-si-rLK/strings.xml b/packages/SettingsProvider/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..24ef798
--- /dev/null
+++ b/packages/SettingsProvider/res/values-si-rLK/strings.xml
@@ -0,0 +1,23 @@
+<?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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"සැකසීම් ගබඩාව"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-si/strings.xml b/packages/SettingsProvider/res/values-si/strings.xml
new file mode 100644
index 0000000..24ef798
--- /dev/null
+++ b/packages/SettingsProvider/res/values-si/strings.xml
@@ -0,0 +1,23 @@
+<?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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"සැකසීම් ගබඩාව"</string>
+</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 09c21f3..b71796e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -39,13 +39,10 @@
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.provider.Settings.Secure;
-import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.content.PackageHelper;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.util.XmlUtils;
diff --git a/packages/Shell/res/values-az-rAZ/strings.xml b/packages/Shell/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..da08e38
--- /dev/null
+++ b/packages/Shell/res/values-az-rAZ/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="3701846017049540910">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Baq raport alındı"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Xətanı şikayətini paylaşmaq üçün toxunun"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Baq raportları sistemin müxtəlif jurnal fayllarından data içərir ki, buna şəxsi və konfidensial məlumatlar da aiddir. Yalnız inandığınız adamlarla baq raportlarını paylaşın."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bu mesajı növbəti dəfə göstər"</string>
+</resources>
diff --git a/packages/Shell/res/values-az/strings.xml b/packages/Shell/res/values-az/strings.xml
new file mode 100644
index 0000000..da08e38
--- /dev/null
+++ b/packages/Shell/res/values-az/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="3701846017049540910">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Baq raport alındı"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Xətanı şikayətini paylaşmaq üçün toxunun"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Baq raportları sistemin müxtəlif jurnal fayllarından data içərir ki, buna şəxsi və konfidensial məlumatlar da aiddir. Yalnız inandığınız adamlarla baq raportlarını paylaşın."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bu mesajı növbəti dəfə göstər"</string>
+</resources>
diff --git a/packages/Shell/res/values-hy/strings.xml b/packages/Shell/res/values-hy/strings.xml
new file mode 100644
index 0000000..ea7fa9f
--- /dev/null
+++ b/packages/Shell/res/values-hy/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="3701846017049540910">"Խեցի"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Վրիպակի զեկույց ստացվեց"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Հպեք` ձեր վրիպակի մասին զեկույցը տարածելու համար"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Վրիպակի զեկույցները պարունակում են տվյալներ համակարգի տարբեր մուտքի ֆայլերից, այդ թվում նաև անհատական ​​և գաղտնի տեղեկություններ: Վրիպակի զեկույցները կիսեք միայն այն հավելվածների և մարդկանց հետ, որոնց վստահում եք:"</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Այս հաղորդագրությունը ցույց տալ հաջորդ անգամ"</string>
+</resources>
diff --git a/packages/Shell/res/values-ka/strings.xml b/packages/Shell/res/values-ka/strings.xml
new file mode 100644
index 0000000..7d9c72a
--- /dev/null
+++ b/packages/Shell/res/values-ka/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="3701846017049540910">"გარეკანი"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"ანგარიში ხარვეზების შესახებ შექმნილია"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"შეეხეთ თქვენი ხარვეზების ანგარიშის გასაზიარებლად"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"ხარვეზის ანგარიშები მოიცავს მონაცემებს სხვადასხვა სისტემური ჟურნალის ფაილებიდან, მათ შორის პირად და კონფიდენციალურ ინფორმაციას."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"შემდგომში აჩვენე ეს შეტყობინება"</string>
+</resources>
diff --git a/packages/Shell/res/values-km/strings.xml b/packages/Shell/res/values-km/strings.xml
new file mode 100644
index 0000000..efb345c
--- /dev/null
+++ b/packages/Shell/res/values-km/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="3701846017049540910">"សែល"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"បាន​ចាប់​យក​របាយការណ៍​កំហុស"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"ប៉ះ​ ដើម្បី​ចែក​រំលែក​របាយការណ៍​កំហុស​របស់​អ្នក"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"របាយការណ៍​កំហុស​រួមមាន​ឯកសារ​កំណត់​ហេតុ​ផ្សេងៗ​របស់​ប្រព័ន្ធ រួមមាន​ព័ត៌មាន​ផ្ទាល់ខ្លួន និង​ឯកជន។ ចែករំលែក​របាយការណ៍​កំហុស​ជា​មួយ​កម្មវិធី និង​មនុស្ស​ដែល​អ្នក​ទុក​ចិត្ត។"</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"បង្ហាញ​សារ​នេះ​ពេល​ក្រោយ"</string>
+</resources>
diff --git a/packages/Shell/res/values-lo/strings.xml b/packages/Shell/res/values-lo/strings.xml
new file mode 100644
index 0000000..a237d48
--- /dev/null
+++ b/packages/Shell/res/values-lo/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="3701846017049540910">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"ລາຍງານຈຸດບົກພ່ອງຖືກເກັບກຳແລ້ວ"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"ແຕະເພື່ອສົ່ງການລາຍງານປັນຫາຂອງທ່ານ"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"ການລາຍງານຂໍ້ຜິດພາດປະກອບມີ ຂໍ້ມູນຈາກໄຟລ໌ບັນທຶກຂອງລະບົບຫຼາຍໄຟລ໌, ຮວມທັງຂໍ້ມູນສ່ວນໂຕນຳ. ທ່ານຕ້ອງແບ່ງປັນລາຍງານຂໍ້ຜິດພາດໃຫ້ແອັບຯ ແລະຄົນທີ່ທ່ານເຊື່ອຖືໄດ້ເທົ່ານັ້ນ."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ສະແດງຂໍ້ຄວາມນີ້ອີກໃນເທື່ອຕໍ່ໄປ"</string>
+</resources>
diff --git a/packages/Shell/res/values-mn/strings.xml b/packages/Shell/res/values-mn/strings.xml
new file mode 100644
index 0000000..f74298d
--- /dev/null
+++ b/packages/Shell/res/values-mn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="3701846017049540910">"Шел"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Алдааны мэдээлэл хүлээн авав"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Та алдааны мэдэгдлийг хуваалцах бол хүрнэ үү"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Алдааны репорт нь хувийн болон нууц мэдээлэл зэргийг агуулсан системийн төрөл бүрийн лог файлын датаг агуулна. Алдааны репортыг зөвхөн итгэлтэй апп болон хүмүүст хуваалцана уу."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Энэ мессежийг дараагийн удаа харуулах"</string>
+</resources>
diff --git a/packages/Shell/res/values-ne-rNP/strings.xml b/packages/Shell/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..cf09433
--- /dev/null
+++ b/packages/Shell/res/values-ne-rNP/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="3701846017049540910">"सेल"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"बग प्रतिवेदन समातियो"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"तपाईंको बग रिपोर्ट साझेदारी गर्न छुनुहोस्"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"बग रिपोर्टहरूमा प्रणालीका विभिन्न लग फाइलहरूबाट व्यक्तिगत तथा नीजि सूचनासहितको डेटा रहन्छ।  बग रिपोर्टहरू अनुप्रयोगहरू र तपाईँले विश्वास गरेका व्यक्तिहरूसँग मात्र साझेदारी गर्नुहोस्।"</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"यो सन्देश अर्को पटक देखाउनुहोस्"</string>
+</resources>
diff --git a/packages/Shell/res/values-ne/strings.xml b/packages/Shell/res/values-ne/strings.xml
new file mode 100644
index 0000000..cf09433
--- /dev/null
+++ b/packages/Shell/res/values-ne/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="3701846017049540910">"सेल"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"बग प्रतिवेदन समातियो"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"तपाईंको बग रिपोर्ट साझेदारी गर्न छुनुहोस्"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"बग रिपोर्टहरूमा प्रणालीका विभिन्न लग फाइलहरूबाट व्यक्तिगत तथा नीजि सूचनासहितको डेटा रहन्छ।  बग रिपोर्टहरू अनुप्रयोगहरू र तपाईँले विश्वास गरेका व्यक्तिहरूसँग मात्र साझेदारी गर्नुहोस्।"</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"यो सन्देश अर्को पटक देखाउनुहोस्"</string>
+</resources>
diff --git a/packages/Shell/res/values-si-rLK/strings.xml b/packages/Shell/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..0780789
--- /dev/null
+++ b/packages/Shell/res/values-si-rLK/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="3701846017049540910">"ෂෙල්"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"දෝෂ වාර්තාව ලබාගන්නා ලදි"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"ඔබගේ දෝෂ වාර්තාව බෙදා ගැනීමට ස්පර්ශ කරන්න"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"පුද්ගලික සහ පෞද්ගලික තොරතුරු ඇතුළත්ව පද්ධතියේ විවිධ ලොග් ගොනු වල දත්ත දෝෂ වාර්තාවේ අඩංගු වේ. ඔබට විශ්වාසවන්ත යෙදුම් සහ පුද්ගලයින් සමඟ පමණක් දෝෂ වාර්තා බෙදා ගන්න."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ඊළඟ වෙලාවේ මෙම පණිවිඩය පෙන්වන්න"</string>
+</resources>
diff --git a/packages/Shell/res/values-si/strings.xml b/packages/Shell/res/values-si/strings.xml
new file mode 100644
index 0000000..0780789
--- /dev/null
+++ b/packages/Shell/res/values-si/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="3701846017049540910">"ෂෙල්"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"දෝෂ වාර්තාව ලබාගන්නා ලදි"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"ඔබගේ දෝෂ වාර්තාව බෙදා ගැනීමට ස්පර්ශ කරන්න"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"පුද්ගලික සහ පෞද්ගලික තොරතුරු ඇතුළත්ව පද්ධතියේ විවිධ ලොග් ගොනු වල දත්ත දෝෂ වාර්තාවේ අඩංගු වේ. ඔබට විශ්වාසවන්ත යෙදුම් සහ පුද්ගලයින් සමඟ පමණක් දෝෂ වාර්තා බෙදා ගන්න."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ඊළඟ වෙලාවේ මෙම පණිවිඩය පෙන්වන්න"</string>
+</resources>
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index ab45d99..1ff93d2 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -7,4 +7,5 @@
   public void setGlowScale(float);
 }
 
+-keep class com.android.systemui.statusbar.phone.PhoneStatusBar
 -keep class com.android.systemui.statusbar.tv.TvStatusBar
diff --git a/core/res/res/drawable-hdpi/ic_action_assist_generic_activated.png b/packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_activated.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_action_assist_generic_activated.png
rename to packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_action_assist_generic_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_normal.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_action_assist_generic_normal.png
rename to packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_glowdot.png b/packages/SystemUI/res/drawable-hdpi/ic_lockscreen_glowdot.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_glowdot.png
rename to packages/SystemUI/res/drawable-hdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_action_assist_generic_activated.png b/packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_activated.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_action_assist_generic_activated.png
rename to packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_action_assist_generic_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_normal.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_action_assist_generic_normal.png
rename to packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_glowdot.png b/packages/SystemUI/res/drawable-mdpi/ic_lockscreen_glowdot.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_glowdot.png
rename to packages/SystemUI/res/drawable-mdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_action_assist_generic_activated.png b/packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_activated.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_action_assist_generic_activated.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_action_assist_generic_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_normal.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_action_assist_generic_normal.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_glowdot.png b/packages/SystemUI/res/drawable-xhdpi/ic_lockscreen_glowdot.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_glowdot.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_action_assist_generic_activated.png b/packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_activated.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_action_assist_generic_activated.png
rename to packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_action_assist_generic_normal.png b/packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_normal.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_action_assist_generic_normal.png
rename to packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_glowdot.png b/packages/SystemUI/res/drawable-xxhdpi/ic_lockscreen_glowdot.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_lockscreen_glowdot.png
rename to packages/SystemUI/res/drawable-xxhdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/core/res/res/drawable/ic_action_assist_generic.xml b/packages/SystemUI/res/drawable/ic_action_assist_generic.xml
similarity index 100%
rename from core/res/res/drawable/ic_action_assist_generic.xml
rename to packages/SystemUI/res/drawable/ic_action_assist_generic.xml
diff --git a/packages/SystemUI/res/drawable/notification_row_legacy_bg.xml b/packages/SystemUI/res/drawable/notification_row_legacy_bg.xml
index 0e1bdd3..ce3372e 100644
--- a/packages/SystemUI/res/drawable/notification_row_legacy_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_row_legacy_bg.xml
@@ -17,6 +17,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
         android:exitFadeDuration="@android:integer/config_mediumAnimTime">
 
-    <item android:state_pressed="true"  android:drawable="@*android:drawable/notification_item_background_color_pressed" />
+    <item android:state_pressed="true"  android:drawable="@drawable/notification_item_background_color_pressed" />
     <item android:state_pressed="false" android:drawable="@drawable/notification_item_background_legacy_color" />
 </selector>
diff --git a/packages/SystemUI/res/drawable/status_bar_item_background.xml b/packages/SystemUI/res/drawable/status_bar_item_background.xml
index b82fed9..3a50aa9 100644
--- a/packages/SystemUI/res/drawable/status_bar_item_background.xml
+++ b/packages/SystemUI/res/drawable/status_bar_item_background.xml
@@ -19,7 +19,7 @@
     android:opacity="translucent"
     >
     <item
-        android:drawable="@*android:drawable/notification_item_background_color"
+        android:drawable="@drawable/notification_item_background_color"
         />
 </layer-list>
 
diff --git a/packages/SystemUI/res/drawable/status_bar_ticker_background.xml b/packages/SystemUI/res/drawable/status_bar_ticker_background.xml
deleted file mode 100644
index 7cb64c0..0000000
--- a/packages/SystemUI/res/drawable/status_bar_ticker_background.xml
+++ /dev/null
@@ -1,21 +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.
--->
-
-<bitmap
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tileMode="repeat"
-    android:src="@*android:drawable/notify_panel_notification_icon_bg"
-    />
diff --git a/packages/SystemUI/res/drawable/system_bar_ticker_background.xml b/packages/SystemUI/res/drawable/system_bar_ticker_background.xml
deleted file mode 100644
index 7cb64c0..0000000
--- a/packages/SystemUI/res/drawable/system_bar_ticker_background.xml
+++ /dev/null
@@ -1,21 +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.
--->
-
-<bitmap
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tileMode="repeat"
-    android:src="@*android:drawable/notify_panel_notification_icon_bg"
-    />
diff --git a/packages/SystemUI/res/drawable/ticker_background.xml b/packages/SystemUI/res/drawable/ticker_background.xml
index 07b44ca..7320fa0 100644
--- a/packages/SystemUI/res/drawable/ticker_background.xml
+++ b/packages/SystemUI/res/drawable/ticker_background.xml
@@ -20,7 +20,7 @@
     >
     <!-- the large icon extends 12dp beyond the edge of the status bar -->
     <item
-        android:drawable="@*android:drawable/notification_item_background_color"
+        android:drawable="@drawable/notification_item_background_color"
         android:top="12dp"
         />
 </layer-list>
diff --git a/packages/SystemUI/res/layout-land/status_bar_search_panel.xml b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
index a109191..ddffd6e 100644
--- a/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
@@ -51,13 +51,13 @@
                 prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
                 prvandroid:outerRingDrawable="@drawable/navbar_search_outerring"
                 prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
-                prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
+                prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
                 prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
                 prvandroid:feedbackCount="0"
                 prvandroid:vibrationDuration="@integer/config_vibration_duration"
                 prvandroid:alwaysTrackFinger="true"
-                prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
-                prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"
+                prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
+                prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"
                 />
 
         </RelativeLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
index 1fa67bd..08f61bb 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
@@ -37,12 +37,12 @@
         prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
         prvandroid:outerRingDrawable="@drawable/navbar_search_outerring"
         prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
-        prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
+        prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
         prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
         prvandroid:feedbackCount="0"
         prvandroid:vibrationDuration="@integer/config_vibration_duration"
         prvandroid:alwaysTrackFinger="true"
-        prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
-        prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"/>
+        prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
+        prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"/>
 
 </com.android.systemui.SearchPanelView>
diff --git a/packages/SystemUI/res/layout/status_bar_search_panel.xml b/packages/SystemUI/res/layout/status_bar_search_panel.xml
index b871bef..c01db7c 100644
--- a/packages/SystemUI/res/layout/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout/status_bar_search_panel.xml
@@ -51,13 +51,13 @@
                 prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
                 prvandroid:outerRingDrawable="@drawable/navbar_search_outerring"
                 prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
-                prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
+                prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
                 prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
                 prvandroid:feedbackCount="0"
                 prvandroid:vibrationDuration="@integer/config_vibration_duration"
                 prvandroid:alwaysTrackFinger="true"
-                prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
-                prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"
+                prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
+                prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"
                />
 
         </RelativeLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 988d594..3d33d69 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Saai na skerm uit"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helderheid"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Kleur-omkeringmodus"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Verbeterde kontrasmodus"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Kleurregstellingmodus"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netwerk word\ndalk gemonitor"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Soek"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Gly op vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Gly links vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index ae0c650..8cb5c4c 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"ማያ ገጽ ውሰድ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ብሩህነት"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ራስ-ሰር"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"የተቃራኒ ቀለም ሁነታ"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"የተሻሻለ ንፅፅር ሁነታ"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"የቀለም እርማት ሁነታ"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"አውታረ መረብ\nክትትል ሊደረግበት ይችላል"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ፍለጋ"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ላይ አንሸራትት።"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ግራ አንሸራትት።"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 88b6762..821e21f 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"بث الشاشة"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"السطوع"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"تلقائي"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"وضع انعكاس اللون"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"وضع التباين المحسن"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"وضع تصحيح الألوان"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"قد تكون الشبكة\nخاضعة للرقابة"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"بحث"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"تمرير لأعلى لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"تمرير لليسار لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az-land/strings.xml b/packages/SystemUI/res/values-az-land/strings.xml
new file mode 100644
index 0000000..8eb6978
--- /dev/null
+++ b/packages/SystemUI/res/values-az-land/strings.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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"Hazırda ekran landşaft orientasiyasında kilidlənib."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 8f46657..a674ab1 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -209,6 +209,15 @@
     <skip />
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркасць"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АЎТА"</string>
+    <!-- no translation found for quick_settings_inversion_label (1666358784283020762) -->
+    <skip />
+    <!-- no translation found for quick_settings_contrast_label (3319507551689108692) -->
+    <skip />
+    <!-- no translation found for quick_settings_color_space_label (853443689745584770) -->
+    <skip />
     <!-- no translation found for ssl_ca_cert_warning (9005954106902053641) -->
     <skip />
+    <string name="description_target_search" msgid="3091587249776033139">"Пошук"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Правядзіце пальцам уверх, каб атрымаць <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Правядзіце пальцам улева, каб атрымаць <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 1814c23..0159704 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Екран за предаване"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркост"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТ."</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Режим на инвертиране на цветовете"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Режим на подобрен контраст"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим на коригиране на цветовете"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Мрежата може\nда се наблюдава"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Търсене"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Плъзнете нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Плъзнете наляво за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index ad7eb5d..6884546 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Pantalla d\'emissió"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillantor"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÀTICA"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversió de color"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode de contrast millorat"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correcció de color"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"És possible que la xarxa\nestigui controlada"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Cerca"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Fes lliscar el dit cap amunt per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Fes lliscar el dit cap a l\'esquerra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index c74f15c..b52fe60 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Vzdálená obrazovka"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Jas"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATICKY"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Režim převrácení barev"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Režim zvýšeného kontrastu"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Režim korekce barev"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Síť může být\nmonitorována"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Vyhledávání"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Přejeďte prstem nahoru: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Přejeďte prstem doleva: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 3da7c6a..41f617e 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Cast-skærm"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Lysstyrke"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Farveinverteringstilstand"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Tilstand for forbedret kontrast"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Farvekorrigeringstilstand"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netværket kan\nvære overvåget"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Søgning"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Glid op for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Glid til venstre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 0e1017b..96668e5 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Bildschirm übertragen"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helligkeit"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Farbinversionsmodus"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrastverbesserungsmodus"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Farbkorrekturmodus"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netzwerk wird\neventuell überwacht."</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Suche"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben schieben"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links schieben"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 1b6929c..9e26a40 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Μετάδοση οθόνης"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Φωτεινότητα"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ΑΥΤΟΜΑΤΗ"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Λειτουργία αναστροφής χρώματος"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Λειτουργία βελτίωσης αντίθεσης"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Λειτουργία διόρθωσης χρώματος"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Το δίκτυο μπορεί\nνα παρακολουθείται"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Αναζήτηση"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Κύλιση προς τα επάνω για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Κύλιση προς τα αριστερά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 825692d..bb6447f 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Cast Screen"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Colour inversion mode"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Enhanced contrast mode"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Colour correction mode"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Network may\nbe monitored"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 825692d..bb6447f 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Cast Screen"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Colour inversion mode"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Enhanced contrast mode"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Colour correction mode"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Network may\nbe monitored"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 6202baf..6122985 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Pantalla de Cast"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillo"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversión de color"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste mejorado"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de corrección de color"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Es posible que la red\nesté supervisada."</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 154c0ee..f233887 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Pantalla de Cast"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillo"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversión de color"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste mejorado"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de corrección de color"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"La red se\npuede supervisar"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index fad777c..43fffae 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Cast-ekraan"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Heledus"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAATNE"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Värvide ümberpööramise režiim"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Täiustatud kontrasti režiim"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Värviparandusrežiim"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Võrku võidakse\njälgida"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Otsing"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Lohistage üles: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Lohistage vasakule: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 5782975..f0e6130 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"فرستادن صفحه"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"روشنایی"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"خودکار"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"حالت وارونگی رنگ"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"حالت کنتراست بهبودیافته"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"حالت تصحیح رنگ"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ممکن است شبکه\nتحت نظارت باشد"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"جستجو"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"لغزاندن به بالا برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"لغزاندن به چپ برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 9a715e8..8d4b14d 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Lähetysnäyttö"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kirkkaus"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Käänteinen väritila"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrastinparannustila"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Värinkorjaustila"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Verkkoa saatetaan\nvalvoa"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Haku"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Liu\'uta ylös ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Liu\'uta vasemmalle ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index bb1dbf1..d5cf322 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Écran distant"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosité"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIQUE"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversion des couleurs"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode d\'accentuation du contraste"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correction des couleurs"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Le réseau peut\nêtre surveillé."</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Recherche"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Faire glisser le doigt vers le haut : <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Faites glisser votre doigt vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index a0eee35..8a140e9 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Écran sur lequel l\'affichage est diffusé"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosité"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIQUE"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversion des couleurs"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode d\'accentuation du contraste"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correction des couleurs"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Le réseau peut\nêtre surveillé."</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Rechercher"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Faites glisser vers le haut pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Faites glisser vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 4b1c3bc..f47b98c 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"स्क्रीन कास्ट करें"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"स्क्रीन की रोशनी"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"स्वत:"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"रंग व्युत्क्रम मोड"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"उन्नत कंट्रास्ट मोड"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"रंग सुधार मोड"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"नेटवर्क को\nमॉनीटर किया जा सकता है"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"खोजें"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर स्‍लाइड करें."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं स्‍लाइड करें."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index afed35c..2dee973 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Emitiranje zaslona"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Svjetlina"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATSKI"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Način inverzije boje"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Način pojačanog kontrasta"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Način korekcije boje"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mreža se\nmožda prati"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Pretraživanje"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Kliznite prema gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Kliznite lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index aba5a88..dfda55e 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Képernyő tartalmának átküldése"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Fényerő"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"automatikus"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Színinvertálás mód"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrasztjavítás mód"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Színjavítás mód"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Lehet, hogy a\nhálózat felügyelt"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Keresés"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa felfelé."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa balra."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy-land/strings.xml b/packages/SystemUI/res/values-hy-land/strings.xml
new file mode 100644
index 0000000..7c0535c
--- /dev/null
+++ b/packages/SystemUI/res/values-hy-land/strings.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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"Էկրանն այժմ կողպված է հորիզոնական դիրքավորման մեջ:"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index f5793c0..44a8bbc 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Հեռակա էկրան"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Պայծառություն"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"Ինքնաշխատ"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Գունաշրջման ռեժիմ"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Ընդլայնված ցայտունության ռեժիմ"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Գույների կարգավորման ռեժիմ"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Ցանցը կարող է\nվերահսկվել"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Որոնել"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Սահեցրեք վերև <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Սահեցրեք ձախ` <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 0893599..912d858 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Layar Transmisi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kecerahan"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OTOMATIS"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode inversi warna"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode kontras yang disempurnakan"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode koreksi warna"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Jaringan bisa\ndiawasi"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Telusuri"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Geser ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Geser ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 67ae18d..34da6a7 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Trasmetti schermo"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosità"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modalità inversione colori"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modalità di contrasto avanzata"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modalità di correzione del colore"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"La rete potrebbe\nessere monitorata"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Ricerca"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Su per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"A sinistra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index fe9c458..b323fb7 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"העבר מסך"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"בהירות"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"אוטומטי"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"מצב היפוך צבעים"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"מצב ניגודיות מוגברת"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"מצב תיקון צבע"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ייתכן שהרשת\nמנוטרת"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"חיפוש"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"הסט למעלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"הסט שמאלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 13bea42..e8e62a1 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"画面のキャスト"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"画面の明るさ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"色反転モード"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"拡張コントラストモード"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"色補正モード"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ネットワークが監視される\n場合があります"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"検索します"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"上にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"左にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka-land/strings.xml b/packages/SystemUI/res/values-ka-land/strings.xml
new file mode 100644
index 0000000..3f20938
--- /dev/null
+++ b/packages/SystemUI/res/values-ka-land/strings.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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"ეკრანი ამჟამად დაბლოკილია თარაზულ ორიენტაციაში"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 67b29d6..b3097e4 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Cast Screen"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"განათება"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ავტომატურად"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"ფერთა ინვერსიის რეჟიმი"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"გაუმჯობესებული კონტრასტის რეჟიმი"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"ფერთა კორექციის რეჟიმი"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"შესაძლოა ქსელზე\nმონიტორინგი ხორციელდებოდეს"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ძიება"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"გაასრიალეთ ზემოთ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"გაასრიალეთ მარცხნივ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km-land/strings.xml b/packages/SystemUI/res/values-km-land/strings.xml
new file mode 100644
index 0000000..f148cc3
--- /dev/null
+++ b/packages/SystemUI/res/values-km-land/strings.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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"ឥឡូវ​អេក្រង់​​ជាប់​សោ​ក្នុង​ទិស​ផ្ដេក។"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 4afc08b..2623cde 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"ចាត់​ថ្នាក់​អេក្រង់"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ពន្លឺ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ស្វ័យប្រវត្តិ"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"របៀប​​បញ្ច្រាស​ពណ៌"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"របៀប​កម្រិត​ពណ៌​ប្រ​សើ​រ​ឡើង"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"របៀប​កែ​ពណ៌"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"បណ្ដាញ​អាច​\nត្រូវ​បាន​ត្រួតពិនិត្យ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"រុញ​ឡើង​លើ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"រុញ​ទៅ​ឆ្វេង​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index ec8bdc1..672c25b 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"화면 전송"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"밝기"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"자동"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"색상 반전 모드"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"향상된 대비 모드"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"색상 보정 모드"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"네트워크가\n모니터링될 수 있음"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"검색"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 위로 슬라이드"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 왼쪽으로 슬라이드"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-land/arrays.xml b/packages/SystemUI/res/values-land/arrays.xml
index 74a6c81..c32ce12 100644
--- a/packages/SystemUI/res/values-land/arrays.xml
+++ b/packages/SystemUI/res/values-land/arrays.xml
@@ -22,21 +22,21 @@
     <array name="navbar_search_targets">
         <item>@null</item>
         <item>@null</item>
-        <item>@*android:drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_action_assist_generic</item>
         <item>@null</item>
     </array>
 
     <array name="navbar_search_target_descriptions">
         <item>@null</item>
         <item>@null</item>
-        <item>@*android:string/description_target_search</item>
+        <item>@string/description_target_search</item>
         <item>@null</item>
     </array>
 
     <array name="navbar_search_direction_descriptions">
         <item>@null</item>
         <item>@null</item>
-        <item>@*android:string/description_direction_left</item>
+        <item>@string/description_direction_left</item>
         <item>@null</item>
     </array>
 
diff --git a/packages/SystemUI/res/values-lo-land/strings.xml b/packages/SystemUI/res/values-lo-land/strings.xml
new file mode 100644
index 0000000..a838a15
--- /dev/null
+++ b/packages/SystemUI/res/values-lo-land/strings.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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"ໜ້າຈໍຕອນນີ້ຖືກລັອກໄວ້ໃນແບບລວງນອນ."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 766477f..f6e778d 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"ດຶງໜ້າຈໍ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ຄວາມແຈ້ງ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ອັດຕະໂນມັດ"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"ໂໝດສະລັບສີ"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"ໂໝດຄວາມຕ່າງແສງ"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"ໂໝດການແກ້ໄຂສີ"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ເຄືອຄ່າຍອາດ\nຖືກຕິດຕາມ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ຊອກຫາ"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"ເລື່ອນຂຶ້ນເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"ເລື່ອນໄປທາງຊ້າຍເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 4feeae2..9fad9e5 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Perduoti ekraną"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Skaistis"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATINIS"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Spalvų inversijos režimas"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Patobulinto kontrasto režimas"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Spalvų taisymo režimas"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Tinklas gali\nbūti stebimas"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Paieška"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Slyskite aukštyn link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Slyskite į kairę link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 01d1108..884c655 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Apraides ekrāns"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Spilgtums"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMĀTISKI"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Krāsu inversijas režīms"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Uzlabota kontrasta režīms"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Krāsu korekcijas režīms"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Tīkls var\ntikt uzraudzīts"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Meklēt"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Velciet uz augšu, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Velciet pa kreisi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn-land/strings.xml b/packages/SystemUI/res/values-mn-land/strings.xml
new file mode 100644
index 0000000..ec4616f
--- /dev/null
+++ b/packages/SystemUI/res/values-mn-land/strings.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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"Дэлгэц хэвтээ чиглэлд түгжигдсэн."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index d92407c..22bf297 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Дамжуулах дэлгэц"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Тодрол"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОМАТ"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Өнгө урвуулах горим"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Сайжруулсан ялгаралтай горим"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Өнгө залруулах горим"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Сүлжээ хянагдаж\nбайж болзошгүй"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Хайх"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-г гулсуулах."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх зүүнлүү гулсуулах."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 58613fd..da74d8c 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Skrin Cast"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kecerahan"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mod penyongsangan warna"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mod kontras dipertingkat"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mod pembetulan warna"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Rangkaian mungkin\nboleh dipantau"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Carian"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Luncurkan ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Luncurkan ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index f75730e..48971ea 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Send skjermen"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Lysstyrke"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modus for fargeinvertering"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Forbedret kontrastmodus"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modus for fargekorrigering"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Nettverket kan\nvære overvåket"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Søk"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Dra opp for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Dra til venstre for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne-land/strings.xml b/packages/SystemUI/res/values-ne-land/strings.xml
new file mode 100644
index 0000000..8d5286e
--- /dev/null
+++ b/packages/SystemUI/res/values-ne-land/strings.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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"स्क्रिन अहिले ल्यान्डस्केप अवस्थामा बन्द छ।"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 9e6605e..19e2744 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -38,7 +38,7 @@
     <string name="invalid_charger" msgid="4549105996740522523">"USB चार्ज गर्न समर्थित छैन।\n आपूर्ति गरिएको चार्जर मात्र प्रयोग गर्नुहोस्।"</string>
     <string name="battery_low_why" msgid="7279169609518386372">"ब्याट्रि प्रयोग"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"सेटिङहरू"</string>
-    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"वाइफाइ"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"वाइ-फाइ"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"हवाइजहाज मोड"</string>
     <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"स्वत:घुम्ने स्क्रिन"</string>
     <string name="status_bar_settings_mute_label" msgid="554682549917429396">"म्युट गर्नुहोस्"</string>
@@ -127,9 +127,9 @@
     <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
     <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"रोमिङ"</string>
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
-    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"वाइफाइ"</string>
+    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"वाइ-फाइ"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM छैन।"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ब्लुटुथ टेदर गर्दै।"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ब्लुटुथ टिथर गर्दै।"</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"हवाइजहाज मोड।"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ब्याट्रि <xliff:g id="NUMBER">%d</xliff:g> प्रतिशत"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"प्रणाली सेटिङहरू"</string>
@@ -159,7 +159,7 @@
     <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"तपाईँ निर्दिष्ट डेटा उपयोग सीमामा पुग्नु भएको छ।\n\nयदि तपाईँले डेटालाई पुनःसक्षम पार्नु भयो भने तपाईँलाई अर्को संचालकबाट शुल्क लगाउन सक्छ।"</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"डेटा पुनः सक्षम गर्नुहोस्"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"इन्टरनेट जडान छैन"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"वाइफाइ जडित"</string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"वाइ-फाइ जडित"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPSको लागि खोजी गर्दै"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारा स्थान सेट गरिएको"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"स्थान अनुरोधहरू सक्रिय"</string>
@@ -189,11 +189,11 @@
     <string name="quick_settings_settings_label" msgid="5326556592578065401">"सेटिङहरू"</string>
     <string name="quick_settings_time_label" msgid="4635969182239736408">"समय"</string>
     <string name="quick_settings_user_label" msgid="5238995632130897840">"मलाई"</string>
-    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"वाइफाइ"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"वाइ-फाइ"</string>
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"जोडिएको छैन"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"नेटवर्क छैन"</string>
-    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"वाइफाइ बन्द"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"वाइफाइ प्रदर्शन"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"वाइ-फाइ बन्द"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"वाइ-फाइ प्रदर्शन"</string>
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"ताररहित प्रदर्शन"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"उज्यालपन"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"स्वतः"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index a05f9c5..3b498bb 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Scherm sturen"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helderheid"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATISCH"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modus voor kleurinversie"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modus voor verbeterd contrast"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modus voor kleurcorrectie"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netwerk kan\nworden gecontroleerd"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Zoeken"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Veeg omhoog voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Veeg naar links voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 83e3c43..ddefab8 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Ekran Cast"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Jasność"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATYCZNA"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Tryb odwrócenia kolorów"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Tryb zwiększonego kontrastu"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Tryb korekcji kolorów"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Sieć może być\nmonitorowana"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Szukaj"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Przesuń w górę: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Przesuń w lewo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 4e318d7..0bf793a 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Transmitir ecrã"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brilho"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversão de cor"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste melhorado"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de correção de cor"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"A rede pode ser\nmonitorizada"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Deslize para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Deslize para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index f97da2f..e4a841a 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Transmitir tela"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brilho"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversão de cores"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste aprimorado"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de correção de cor"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"A rede pode estar\nsob monitoração"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para cima."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a esquerda."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index 5bc11e9..ef14717 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -368,6 +368,18 @@
     <skip />
     <!-- no translation found for quick_settings_brightness_dialog_auto_brightness_label (5064982743784071218) -->
     <skip />
+    <!-- no translation found for quick_settings_inversion_label (1666358784283020762) -->
+    <skip />
+    <!-- no translation found for quick_settings_contrast_label (3319507551689108692) -->
+    <skip />
+    <!-- no translation found for quick_settings_color_space_label (853443689745584770) -->
+    <skip />
     <!-- no translation found for ssl_ca_cert_warning (9005954106902053641) -->
     <skip />
+    <!-- no translation found for description_target_search (3091587249776033139) -->
+    <skip />
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 168369d..4a4fcf2 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Ecran de afișare a transmisiunii"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminozitate"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAT"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mod de inversare a culorilor"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mod contrast îmbunătățit"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mod de corectare a culorilor"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Rețeaua poate\nfi monitorizată"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Căutaţi"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Glisaţi în sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Glisaţi spre stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 96e6e13..00cd571 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -203,5 +203,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Wi-Fi-монитор"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркость"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОНАСТРОЙКА"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Инверсия цвета"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Контрастность"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Коррекция цвета"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Действия в сети\nмогут отслеживаться"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Поиск"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Проведите вверх, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Проведите влево, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si-land/strings.xml b/packages/SystemUI/res/values-si-land/strings.xml
new file mode 100644
index 0000000..b5aba2a
--- /dev/null
+++ b/packages/SystemUI/res/values-si-land/strings.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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"තිරය දැන් තිරස් දිශානතිය අගුළු දමා ඇත."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 60e4dc2..6b2a5fd 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Vzdialená obrazovka"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Jas"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATICKY"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Režim prevrátenia farieb"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Režim zvýšeného kontrastu"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Režim korekcie farieb"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Sieť môže byť\nmonitorovaná"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Vyhľadávanie"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Prejdite prstom nahor: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Prejdite prstom doľava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 2f90aeb..a042044 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Zaslon za predvajanje"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Svetlost"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"SAMODEJNO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Način inverzije barv"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Način izboljšanega kontrasta"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Način popravljanja barv"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Omrežje je\nlahko spremljano"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Iskanje"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Povlecite navzgor za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Povlecite v levo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 33607f2..7531ac9 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Пребаци екран"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Осветљеност"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АУТОМАТСКА"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Режим инверзије боје"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Режим унапређеног контраста"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим корекције боје"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Мрежа се можда\nнадгледа"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Претрага"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Превуците нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Превуците улево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index b49b5c9..f4bd4a7 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Överför skärmen"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ljusstyrka"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Färginverteringsläge"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrastförbättringsläge"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Färgkorrigeringsläge"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Nätverket kan\nvara övervakat"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Sök"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Dra uppåt för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Dra åt vänster för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index ac025fd..020587a 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -197,5 +197,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Utumaji wa Skrini"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ung\'avu"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"KIOTOMATIKI"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Hali ya ugeuzaji kinyume wa rangi"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Hali ya utofautishaji ulioboreshwa"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Hali ya kusahihisha rangi"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Huenda mtandao\nunafuatiliwa"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Tafuta"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Sogeza juu kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Sogeza kushoto kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/arrays.xml b/packages/SystemUI/res/values-sw600dp/arrays.xml
index f3a1771..21c4bd3 100644
--- a/packages/SystemUI/res/values-sw600dp/arrays.xml
+++ b/packages/SystemUI/res/values-sw600dp/arrays.xml
@@ -21,21 +21,21 @@
 
     <array name="navbar_search_targets">
         <item>@null</item>
-        <item>@*android:drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_action_assist_generic</item>
         <item>@null</item>
         <item>@null</item>
     </array>
 
     <array name="navbar_search_target_descriptions">
         <item>@null</item>
-        <item>@*android:string/description_target_search</item>
+        <item>@string/description_target_search</item>
         <item>@null</item>
         <item>@null</item>
     </array>
 
     <array name="navbar_search_direction_descriptions">
         <item>@null</item>
-        <item>@*android:string/description_direction_left</item>
+        <item>@string/description_direction_left</item>
         <item>@null</item>
         <item>@null</item>
     </array>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 65b075a..7546b12 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"ส่งหน้าจอ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ความสว่าง"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"อัตโนมัติ"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"โหมดการกลับสี"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"โหมดคอนทราสต์ที่ปรับปรุงแล้ว"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"โหมดการแก้ไขสี"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"เครือข่ายอาจ\nถูกตรวจสอบ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ค้นหา"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"เลื่อนขึ้นเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"เลื่อนไปทางซ้ายเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 4ac1b53..f66bd1d 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"I-cast ang Screen"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode ng pag-invert ng kulay"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode na dinagdagan ang contrast"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode ng pagtatama ng kulay"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Maaaring\nsinusubaybayan ang network"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Maghanap"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Mag-slide pataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Mag-slide pakaliwa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index a15e375..c30c8fd1 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Yayınlama Ekranı"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Parlaklık"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OTOMATİK"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Renk ters çevirme modu"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Geliştirilmiş kontrast modu"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Renk düzeltme modu"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Ağ izleniyor\nolabilir"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Ara"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için yukarı kaydırın."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sola kaydırın."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 439c3d7..f22edd3 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Транслювати екран"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яскравість"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТО"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Режим інверсії кольорів"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Режим посиленого контрасту"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим коригування кольору"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Мережа може\nвідстежуватися"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Пошук"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Проведіть пальцем угору, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Проведіть пальцем ліворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 34d1414..ab170e0 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Truyền màn hình"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Độ sáng"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"TỰ ĐỘNG"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Chế độ đảo ngược màu sắc"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Chế độ tương phản tăng cường"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Chế độ hiệu chỉnh màu sắc"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mạng có thể\nđược giám sát"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Tìm kiếm"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Trượt lên để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Trượt sang trái để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index f759662..6ea8b42 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"投射屏幕"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自动"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"颜色反转模式"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"增强对比度模式"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"颜色校正模式"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"网络可能会\n受到监控"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"搜索"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"向上滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"向左滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index bf5ae35..c8620f1 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"放送螢幕"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"色彩反轉模式"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"增強對比模式"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"色彩校準模式"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"網絡可能會\n受到監控"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index b1f99f5..b10ec82 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -201,5 +201,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"投放螢幕"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"彩色反轉模式"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"增強對比模式"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"色彩校正模式"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"網路可能\n受到監控"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index f284b7c..f22be67 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -199,5 +199,11 @@
     <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Isikrini sabalingisi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ukugqama"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OKUZENZAKALELAYO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Imodi yokuguqulwa kombala"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Imodi ethuthukisiwe yokugqama"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Imodi yokulungisa umbala"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Kungenzeka inethiwekhi\niqashiwe"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Sesha"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Shelelisela ngenhla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Shelelisela ngakwesokunxele ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
index bfb600d..1ce4983 100644
--- a/packages/SystemUI/res/values/arrays.xml
+++ b/packages/SystemUI/res/values/arrays.xml
@@ -21,21 +21,21 @@
     
     <array name="navbar_search_targets">
         <item>@null</item>
-        <item>@*android:drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_action_assist_generic</item>
         <item>@null</item>
         <item>@null</item>
     </array>
 
     <array name="navbar_search_target_descriptions">
         <item>@null</item>
-        <item>@*android:string/description_target_search</item>
+        <item>@string/description_target_search</item>
         <item>@null</item>
         <item>@null</item>
     </array>
 
     <array name="navbar_search_direction_descriptions">
         <item>@null</item>
-        <item>@*android:string/description_direction_up</item>
+        <item>@string/description_direction_up</item>
         <item>@null</item>
         <item>@null</item>
     </array>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 0bbdead..3a35de5 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -36,4 +36,6 @@
     <color name="batterymeter_charge_color">#FFFFFFFF</color>
     <color name="batterymeter_bolt_color">#B2000000</color><!-- 70% black -->
     <color name="status_bar_clock_color">#FFFFFFFF</color>
+    <drawable name="notification_item_background_color">#ff111111</drawable>
+    <drawable name="notification_item_background_color_pressed">#ff454545</drawable>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index cc78cb4..e6b2b8b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -220,4 +220,10 @@
 
     <!-- used by DessertCase -->
     <dimen name="dessert_case_cell_size">192dp</dimen>
+
+    <!-- Default glow radius for GlowPadView -->
+    <dimen name="glowpadview_glow_radius">75dip</dimen>
+
+    <!-- Default distance from each snap target that GlowPadView considers a "hit" -->
+    <dimen name="glowpadview_inner_radius">15dip</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e36ca8e..5afd55b 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -496,6 +496,12 @@
     <string name="quick_settings_brightness_dialog_title">Brightness</string>
     <!-- QuickSettings: Brightness dialog auto brightness button [CHAR LIMIT=NONE] -->
     <string name="quick_settings_brightness_dialog_auto_brightness_label">AUTO</string>
+    <!-- QuickSettings: Label for the toggle that controls whether display inversion is enabled. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_inversion_label">Color inversion mode</string>
+    <!-- QuickSettings: Label for the toggle that controls whether display contrast enhancement is enabled. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_contrast_label">Enhanced contrast mode</string>
+    <!-- QuickSettings: Label for the toggle that controls whether display color correction is enabled. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_color_space_label">Color correction mode</string>
 
 
     <!-- Glyph to be overlaid atop the battery when the level is extremely low. Do not translate. -->
@@ -507,4 +513,10 @@
          linebreak to position it correctly.  [CHAR LIMIT=45] -->
     <string name="ssl_ca_cert_warning">Network may\nbe monitored</string>
 
+    <!-- Description of the unlock target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_target_search">Search</string>
+    <!-- Description of the up direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_direction_up">Slide up for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
+    <!-- Description of the left direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_direction_left">"Slide left for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 13aafb2..1c64fb4 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -27,7 +27,6 @@
 import android.graphics.Path;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Typeface;
 import android.os.BatteryManager;
diff --git a/packages/SystemUI/src/com/android/systemui/DessertCase.java b/packages/SystemUI/src/com/android/systemui/DessertCase.java
index d797e38..a96f024 100644
--- a/packages/SystemUI/src/com/android/systemui/DessertCase.java
+++ b/packages/SystemUI/src/com/android/systemui/DessertCase.java
@@ -16,13 +16,10 @@
 
 package com.android.systemui;
 
-import android.animation.ObjectAnimator;
 import android.app.Activity;
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
-import android.os.Handler;
 import android.util.Slog;
-import android.view.animation.DecelerateInterpolator;
 
 public class DessertCase extends Activity {
     DessertCaseView mView;
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 4b0c2cb..c7f4828 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -471,7 +471,7 @@
 
             checkGlError();
 
-            if (w < 0 || h < 0) {
+            if (w > 0 || h > 0) {
                 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
                 glClear(GL_COLOR_BUFFER_BIT);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index c7f0e17..b096ead 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -135,7 +135,7 @@
         public void onTrigger(View v, final int target) {
             final int resId = mGlowPadView.getResourceIdForTarget(target);
             switch (resId) {
-                case com.android.internal.R.drawable.ic_action_assist_generic:
+                case R.drawable.ic_action_assist_generic:
                     mWaitingForLaunch = true;
                     startAssistActivity();
                     vibrate();
@@ -175,7 +175,7 @@
             ComponentName component = intent.getComponent();
             if (component == null || !mGlowPadView.replaceTargetDrawablesIfPresent(component,
                     ASSIST_ICON_METADATA_NAME,
-                    com.android.internal.R.drawable.ic_action_assist_generic)) {
+                    R.drawable.ic_action_assist_generic)) {
                 if (DEBUG) Log.v(TAG, "Couldn't grab icon for component " + component);
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java b/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java
index 2bc2821..2e0ee36 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java
@@ -18,7 +18,6 @@
 
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
-import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 
 public final class TaskDescription {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 2063563..74d982a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -60,6 +60,7 @@
 
 import java.io.File;
 import java.io.OutputStream;
+import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
@@ -214,8 +215,7 @@
             values.put(MediaStore.Images.ImageColumns.HEIGHT, mImageHeight);
             Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
 
-            String subjectDate = new SimpleDateFormat("hh:mma, MMM dd, yyyy")
-                .format(new Date(mImageTime));
+            String subjectDate = DateFormat.getDateTimeInstance().format(new Date(mImageTime));
             String subject = String.format(SCREENSHOT_SHARE_SUBJECT_TEMPLATE, subjectDate);
             Intent sharingIntent = new Intent(Intent.ACTION_SEND);
             sharingIntent.setType("image/png");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
index 7d3e870..9839fe9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
@@ -38,7 +38,7 @@
     }
 
     private void updateAnim() {
-        Drawable drawable = mAttached ? getDrawable() : null;
+        Drawable drawable = getDrawable();
         if (mAttached && mAnim != null) {
             mAnim.stop();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 5264998..44b3843 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -21,8 +21,6 @@
 import android.view.View;
 import android.widget.ImageView;
 
-import com.android.systemui.R;
-
 import java.util.ArrayList;
 import java.util.Comparator;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardTouchDelegate.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardTouchDelegate.java
index c1646ba..2a43cf6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardTouchDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardTouchDelegate.java
@@ -26,8 +26,6 @@
 import android.util.Slog;
 import android.view.MotionEvent;
 
-import com.android.internal.policy.IKeyguardExitCallback;
-import com.android.internal.policy.IKeyguardShowCallback;
 import com.android.internal.policy.IKeyguardService;
 
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index e7b8fa1..e6fd7d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -25,6 +25,7 @@
 import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
@@ -84,6 +85,7 @@
     static final boolean DEBUG_GONE_TILES = false;
     private static final String TAG = "QuickSettings";
     public static final boolean SHOW_IME_TILE = false;
+    public static final boolean SHOW_ACCESSIBILITY_TILES = true;
 
     public static final boolean LONG_PRESS_TOGGLES = true;
 
@@ -374,6 +376,35 @@
                 new QuickSettingsModel.BasicRefreshCallback(settingsTile));
         parent.addView(settingsTile);
         mDynamicSpannedTiles.add(settingsTile);
+
+        if (SHOW_ACCESSIBILITY_TILES) {
+            // Color inversion tile
+            final SystemSettingTile inversionTile = new SystemSettingTile(mContext);
+            inversionTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
+                    SystemSettingTile.TYPE_SECURE);
+            inversionTile.setFragment("Settings$AccessibilityInversionSettingsActivity");
+            mModel.addInversionTile(inversionTile, inversionTile.getRefreshCallback());
+            parent.addView(inversionTile);
+            mDynamicSpannedTiles.add(inversionTile);
+
+            // Contrast enhancement tile
+            final SystemSettingTile contrastTile = new SystemSettingTile(mContext);
+            contrastTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED,
+                    SystemSettingTile.TYPE_SECURE);
+            contrastTile.setFragment("Settings$AccessibilityContrastSettingsActivity");
+            mModel.addContrastTile(contrastTile, contrastTile.getRefreshCallback());
+            parent.addView(contrastTile);
+            mDynamicSpannedTiles.add(contrastTile);
+
+            // Color space adjustment tile
+            final SystemSettingTile colorSpaceTile = new SystemSettingTile(mContext);
+            colorSpaceTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
+                    SystemSettingTile.TYPE_SECURE);
+            colorSpaceTile.setFragment("Settings$AccessibilityDaltonizerSettingsActivity");
+            mModel.addColorSpaceTile(colorSpaceTile, colorSpaceTile.getRefreshCallback());
+            parent.addView(colorSpaceTile);
+            mDynamicSpannedTiles.add(colorSpaceTile);
+        }
     }
 
     private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
@@ -918,4 +949,108 @@
             }
         }
     }
+
+    /**
+     * Quick Setting tile that represents a secure setting. This type of tile
+     * can toggle a URI within Settings.Secure on click and launch a Settings
+     * fragment on long-click.
+     */
+    public class SystemSettingTile extends QuickSettingsBasicTile {
+        private static final int TYPE_GLOBAL = 0;
+        private static final int TYPE_SECURE = 1;
+        private static final int TYPE_SYSTEM = 2;
+
+        private final QuickSettingsModel.BasicRefreshCallback mRefreshCallback;
+
+        private String mFragment;
+        private String mName;
+        private int mType;
+
+        public SystemSettingTile(Context context) {
+            super(context);
+
+            mRefreshCallback = new QuickSettingsModel.BasicRefreshCallback(this);
+            mRefreshCallback.setShowWhenEnabled(true);
+        }
+
+        @Override
+        public boolean performLongClick() {
+            if (mFragment != null) {
+                collapsePanels();
+
+                final Intent intent = new Intent();
+                intent.setComponent(new ComponentName(
+                        "com.android.settings", "com.android.settings." + mFragment));
+                startSettingsActivity(intent);
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public boolean performClick() {
+            if (mName != null) {
+                collapsePanels();
+
+                final ContentResolver cr = mContext.getContentResolver();
+                switch (mType) {
+                    case TYPE_GLOBAL: {
+                        final boolean enable = Settings.Global.getInt(cr, mName, 0) == 0;
+                        Settings.Global.putInt(cr, mName, enable ? 1 : 0);
+                    } break;
+                    case TYPE_SECURE: {
+                        final boolean enable = Settings.Secure.getIntForUser(
+                                cr, mName, 0, UserHandle.USER_CURRENT) == 0;
+                        Settings.Secure.putIntForUser(
+                                cr, mName, enable ? 1 : 0, UserHandle.USER_CURRENT);
+                    } break;
+                    case TYPE_SYSTEM: {
+                        final boolean enable = Settings.System.getIntForUser(
+                                cr, mName, 0, UserHandle.USER_CURRENT) == 0;
+                        Settings.System.putIntForUser(
+                                cr, mName, enable ? 1 : 0, UserHandle.USER_CURRENT);
+                    } break;
+                }
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Specifies the fragment within the com.android.settings package to
+         * launch when this tile is long-clicked.
+         *
+         * @param fragment a fragment name within the com.android.settings
+         *            package
+         */
+        public void setFragment(String fragment) {
+            mFragment = fragment;
+            setLongClickable(fragment != null);
+        }
+
+        /**
+         * Specifies the setting name and type to toggle when this tile is
+         * clicked.
+         *
+         * @param name a setting name
+         * @param type the type of setting, one of:
+         *            <ul>
+         *            <li>{@link #TYPE_GLOBAL}
+         *            <li>{@link #TYPE_SECURE}
+         *            <li>{@link #TYPE_SYSTEM}
+         *            </ul>
+         */
+        public void setUri(String name, int type) {
+            mName = name;
+            mType = type;
+            setClickable(mName != null);
+        }
+
+        /**
+         * @return the refresh callback for this tile
+         */
+        public QuickSettingsModel.BasicRefreshCallback getRefreshCallback() {
+            return mRefreshCallback;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index 42201c5..12e08d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -91,6 +91,19 @@
     static class BrightnessState extends State {
         boolean autoBrightness;
     }
+    static class InversionState extends State {
+        boolean toggled;
+        int type;
+    }
+    static class ContrastState extends State {
+        boolean toggled;
+        float contrast;
+        float brightness;
+    }
+    static class ColorSpaceState extends State {
+        boolean toggled;
+        int type;
+    }
     public static class BluetoothState extends State {
         boolean connected = false;
         String stateContentDescription;
@@ -199,6 +212,87 @@
         }
     }
 
+    /** ContentObserver to watch display inversion */
+    private class DisplayInversionObserver extends ContentObserver {
+        public DisplayInversionObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            onInversionChanged();
+        }
+
+        public void startObserving() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.unregisterContentObserver(this);
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_QUICK_SETTING_ENABLED),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION),
+                    false, this, mUserTracker.getCurrentUserId());
+        }
+    }
+
+    /** ContentObserver to watch display contrast */
+    private class DisplayContrastObserver extends ContentObserver {
+        public DisplayContrastObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            onContrastChanged();
+        }
+
+        public void startObserving() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.unregisterContentObserver(this);
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_QUICK_SETTING_ENABLED),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS),
+                    false, this, mUserTracker.getCurrentUserId());
+        }
+    }
+
+    /** ContentObserver to watch display color space adjustment */
+    private class DisplayColorSpaceObserver extends ContentObserver {
+        public DisplayColorSpaceObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            onColorSpaceChanged();
+        }
+
+        public void startObserving() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.unregisterContentObserver(this);
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_QUICK_SETTING_ENABLED),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER),
+                    false, this, mUserTracker.getCurrentUserId());
+        }
+    }
+
     /** Callback for changes to remote display routes. */
     private class RemoteDisplayRouteCallback extends MediaRouter.SimpleCallback {
         @Override
@@ -229,6 +323,9 @@
     private final NextAlarmObserver mNextAlarmObserver;
     private final BugreportObserver mBugreportObserver;
     private final BrightnessObserver mBrightnessObserver;
+    private final DisplayInversionObserver mInversionObserver;
+    private final DisplayContrastObserver mContrastObserver;
+    private final DisplayColorSpaceObserver mColorSpaceObserver;
 
     private final MediaRouter mMediaRouter;
     private final RemoteDisplayRouteCallback mRemoteDisplayRouteCallback;
@@ -287,6 +384,18 @@
     private RefreshCallback mBrightnessCallback;
     private BrightnessState mBrightnessState = new BrightnessState();
 
+    private QuickSettingsTileView mInversionTile;
+    private RefreshCallback mInversionCallback;
+    private InversionState mInversionState = new InversionState();
+
+    private QuickSettingsTileView mContrastTile;
+    private RefreshCallback mContrastCallback;
+    private ContrastState mContrastState = new ContrastState();
+
+    private QuickSettingsTileView mColorSpaceTile;
+    private RefreshCallback mColorSpaceCallback;
+    private ColorSpaceState mColorSpaceState = new ColorSpaceState();
+
     private QuickSettingsTileView mBugreportTile;
     private RefreshCallback mBugreportCallback;
     private State mBugreportState = new State();
@@ -308,8 +417,14 @@
             @Override
             public void onUserSwitched(int newUserId) {
                 mBrightnessObserver.startObserving();
+                mInversionObserver.startObserving();
+                mContrastObserver.startObserving();
+                mColorSpaceObserver.startObserving();
                 refreshRotationLockTile();
                 onBrightnessLevelChanged();
+                onInversionChanged();
+                onContrastChanged();
+                onColorSpaceChanged();
                 onNextAlarmChanged();
                 onBugreportChanged();
                 rebindMediaRouterAsCurrentUser();
@@ -322,6 +437,12 @@
         mBugreportObserver.startObserving();
         mBrightnessObserver = new BrightnessObserver(mHandler);
         mBrightnessObserver.startObserving();
+        mInversionObserver = new DisplayInversionObserver(mHandler);
+        mInversionObserver.startObserving();
+        mContrastObserver = new DisplayContrastObserver(mHandler);
+        mContrastObserver.startObserving();
+        mColorSpaceObserver = new DisplayColorSpaceObserver(mHandler);
+        mColorSpaceObserver.startObserving();
 
         mMediaRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
         rebindMediaRouterAsCurrentUser();
@@ -847,6 +968,90 @@
         onBrightnessLevelChanged();
     }
 
+    // Color inversion
+    void addInversionTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mInversionTile = view;
+        mInversionCallback = cb;
+        onInversionChanged();
+    }
+    public void onInversionChanged() {
+        final Resources res = mContext.getResources();
+        final ContentResolver cr = mContext.getContentResolver();
+        final int currentUserId = mUserTracker.getCurrentUserId();
+        final boolean quickSettingEnabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_QUICK_SETTING_ENABLED, 0,
+                currentUserId) == 1;
+        final boolean enabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, currentUserId) == 1;
+        final int type = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION, 0, currentUserId);
+        mInversionState.enabled = quickSettingEnabled;
+        mInversionState.toggled = enabled;
+        mInversionState.type = type;
+        // TODO: Add real icon assets.
+        mInversionState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
+                : R.drawable.ic_qs_bluetooth_off;
+        mInversionState.label = res.getString(R.string.quick_settings_inversion_label);
+        mInversionCallback.refreshView(mInversionTile, mInversionState);
+    }
+
+    // Contrast enhancement
+    void addContrastTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mContrastTile = view;
+        mContrastCallback = cb;
+        onContrastChanged();
+    }
+    public void onContrastChanged() {
+        final Resources res = mContext.getResources();
+        final ContentResolver cr = mContext.getContentResolver();
+        final int currentUserId = mUserTracker.getCurrentUserId();
+        final boolean quickSettingEnabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_QUICK_SETTING_ENABLED, 0,
+                currentUserId) == 1;
+        final boolean enabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED, 0, currentUserId) == 1;
+        final float contrast = Settings.Secure.getFloatForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST, 1, currentUserId);
+        final float brightness = Settings.Secure.getFloatForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS, 0, currentUserId);
+        mContrastState.enabled = quickSettingEnabled;
+        mContrastState.toggled = enabled;
+        mContrastState.contrast = contrast;
+        mContrastState.brightness = brightness;
+        // TODO: Add real icon assets.
+        mContrastState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
+                : R.drawable.ic_qs_bluetooth_off;
+        mContrastState.label = res.getString(R.string.quick_settings_contrast_label);
+        mContrastCallback.refreshView(mContrastTile, mContrastState);
+    }
+
+    // Color space adjustment
+    void addColorSpaceTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mColorSpaceTile = view;
+        mColorSpaceCallback = cb;
+        onColorSpaceChanged();
+    }
+    public void onColorSpaceChanged() {
+        final Resources res = mContext.getResources();
+        final ContentResolver cr = mContext.getContentResolver();
+        final int currentUserId = mUserTracker.getCurrentUserId();
+        final boolean quickSettingEnabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_QUICK_SETTING_ENABLED, 0,
+                currentUserId) == 1;
+        final boolean enabled = Settings.Secure.getIntForUser(cr,
+                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, currentUserId) == 1;
+        final int type = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, 0, currentUserId);
+        mColorSpaceState.enabled = quickSettingEnabled;
+        mColorSpaceState.toggled = enabled;
+        mColorSpaceState.type = type;
+        // TODO: Add real icon assets.
+        mColorSpaceState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
+                : R.drawable.ic_qs_bluetooth_off;
+        mColorSpaceState.label = res.getString(R.string.quick_settings_color_space_label);
+        mColorSpaceCallback.refreshView(mColorSpaceTile, mColorSpaceState);
+    }
+
     // SSL CA Cert warning.
     public void addSslCaCertWarningTile(QuickSettingsTileView view, RefreshCallback cb) {
         mSslCaCertWarningTile = view;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
index b7f3cfe..72497c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
@@ -21,9 +21,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewParent;
 import android.widget.TextView;
 
 import com.android.systemui.R;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index f1fda78..075a951 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.policy;
 
-import android.app.Notification;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -27,7 +26,6 @@
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
-import android.widget.LinearLayout;
 
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index 312bba3..f5ee95b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -24,7 +24,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.database.ContentObserver;
 import android.location.LocationManager;
 import android.os.Handler;
 import android.os.UserHandle;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index 259422d..a5596f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -33,7 +33,6 @@
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
-import com.android.systemui.statusbar.NotificationData;
 
 import java.util.HashMap;
 
diff --git a/packages/VpnDialogs/res/values-az-rAZ/strings.xml b/packages/VpnDialogs/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..fdeb06f
--- /dev/null
+++ b/packages/VpnDialogs/res/values-az-rAZ/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"VPN bağlantısı yaratmaq üçün <xliff:g id="APP">%s</xliff:g> cəhdləri."</string>
+    <string name="warning" msgid="5470743576660160079">"Bunu həyata keçirməklə, siz tətbiqə bütün şəbəkə hərəkətinə qarışmağa icazə verirsiniz. "<b>" Tətbiqə güvənmirsizsə qəbul etməyin. "</b>" Əks halda, datanızın təhlükəli proqramlar tərəfindən ələ keçirilmə riskini alırsınız."</string>
+    <string name="accept" msgid="2889226408765810173">"Bu tətbiqə güvənirəm."</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN qoşuludur"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfiqurasiya edin"</string>
+    <string name="disconnect" msgid="971412338304200056">"Əlaqəni kəs"</string>
+    <string name="session" msgid="6470628549473641030">"Sessiya:"</string>
+    <string name="duration" msgid="3584782459928719435">"Müddət:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"Göndərilən:"</string>
+    <string name="data_received" msgid="4062776929376067820">"Qəbul edilən:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bayt / <xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-az/strings.xml b/packages/VpnDialogs/res/values-az/strings.xml
new file mode 100644
index 0000000..fdeb06f
--- /dev/null
+++ b/packages/VpnDialogs/res/values-az/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"VPN bağlantısı yaratmaq üçün <xliff:g id="APP">%s</xliff:g> cəhdləri."</string>
+    <string name="warning" msgid="5470743576660160079">"Bunu həyata keçirməklə, siz tətbiqə bütün şəbəkə hərəkətinə qarışmağa icazə verirsiniz. "<b>" Tətbiqə güvənmirsizsə qəbul etməyin. "</b>" Əks halda, datanızın təhlükəli proqramlar tərəfindən ələ keçirilmə riskini alırsınız."</string>
+    <string name="accept" msgid="2889226408765810173">"Bu tətbiqə güvənirəm."</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN qoşuludur"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfiqurasiya edin"</string>
+    <string name="disconnect" msgid="971412338304200056">"Əlaqəni kəs"</string>
+    <string name="session" msgid="6470628549473641030">"Sessiya:"</string>
+    <string name="duration" msgid="3584782459928719435">"Müddət:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"Göndərilən:"</string>
+    <string name="data_received" msgid="4062776929376067820">"Qəbul edilən:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bayt / <xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-hy/strings.xml b/packages/VpnDialogs/res/values-hy/strings.xml
new file mode 100644
index 0000000..85db579
--- /dev/null
+++ b/packages/VpnDialogs/res/values-hy/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g>-ը փորձում է ստեղծել VPN կապ:"</string>
+    <string name="warning" msgid="5470743576660160079">"Շարունակելով` դուք հավելվածին թույլատրում եք կանգնեցնել ամբողջ ցանցային շարժը: "<b>"Մի ընդունեք, եթե չեք վստահում հավելվածին:"</b>" Այլապես ռիսկ կա ձեր տվյալները վտանգելու վնասարար հավելվածների կողմից:"</string>
+    <string name="accept" msgid="2889226408765810173">"Ես վստահում եմ այս ծրագրին:"</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN-ը կապակցված է"</string>
+    <string name="configure" msgid="4905518375574791375">"Կարգավորել"</string>
+    <string name="disconnect" msgid="971412338304200056">"Անջատել"</string>
+    <string name="session" msgid="6470628549473641030">"Աշխատաշրջան`"</string>
+    <string name="duration" msgid="3584782459928719435">"Տևողությունը՝"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"Ուղարկվել է՝"</string>
+    <string name="data_received" msgid="4062776929376067820">"Ստացվել է՝"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> բայթ / <xliff:g id="NUMBER_1">%2$s</xliff:g> փաթեթ"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-ka/strings.xml b/packages/VpnDialogs/res/values-ka/strings.xml
new file mode 100644
index 0000000..960d3f6
--- /dev/null
+++ b/packages/VpnDialogs/res/values-ka/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> ცდილობს VPN კავშირის შექმნას."</string>
+    <string name="warning" msgid="5470743576660160079">"გაგრძელების შემთხვევაში, აპლიკაციას ექნება ქსელში გადაცემული მონაცემების მოპოვების საშუალება. "<b>"არ განაგრძოთ, თუ არ ენდობით აპლიკაციას."</b>" წინააღმდეგ შემთვევაში შესაძლოა მავნე პროგრამას თქვენ მონაცემებთან წვდომის საშუალება მიეცეს."</string>
+    <string name="accept" msgid="2889226408765810173">"ვენდობი ამ აპლიკაციას."</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN დაკავშირებულია"</string>
+    <string name="configure" msgid="4905518375574791375">"კონფიგურაცია"</string>
+    <string name="disconnect" msgid="971412338304200056">"კავშირის გაწყვეტა"</string>
+    <string name="session" msgid="6470628549473641030">"სესია:"</string>
+    <string name="duration" msgid="3584782459928719435">"ხანგრძლივობა:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"გაგზავნილი:"</string>
+    <string name="data_received" msgid="4062776929376067820">"მიღებული:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ბაიტი / <xliff:g id="NUMBER_1">%2$s</xliff:g> პაკეტი"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-km/strings.xml b/packages/VpnDialogs/res/values-km/strings.xml
new file mode 100644
index 0000000..2c79e26
--- /dev/null
+++ b/packages/VpnDialogs/res/values-km/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> ព្យាយាម​បង្កើត​ការ​តភ្ជាប់ VPN ។"</string>
+    <string name="warning" msgid="5470743576660160079">"ដោយ​បន្ត អ្នក​កំពុង​ផ្ដល់​សិទ្ធិ​ឲ្យ​កម្មវិធី​ទប់ស្កាត់​ចរាចរណ៍​បណ្ដាញ។ "<b>"កុំ​ទទួល​ លុះ​ត្រា​តែ​អ្នក​ទុក​ចិត្ត​កម្មវិធី។"</b>" បើ​មិន​ដូច្នេះ​ទេ អ្នក​ដំណើរការ​ប្រឈម​នឹង​គ្រោះថ្នាក់ ដោយ​ទិន្នន័យ​របស់​អ្នក​បាន​សម្របសម្រួល​ដោយ​កម្មវិធី​ព្យាបាទ។"</string>
+    <string name="accept" msgid="2889226408765810173">"ខ្ញុំ​ទុកចិត្ត​​​កម្មវិធី​នេះ​។"</string>
+    <string name="legacy_title" msgid="192936250066580964">"បា​ន​ភ្ជាប់ VPN"</string>
+    <string name="configure" msgid="4905518375574791375">"កំណត់​រចនាសម្ព័ន្ធ"</string>
+    <string name="disconnect" msgid="971412338304200056">"ផ្ដាច់"</string>
+    <string name="session" msgid="6470628549473641030">"សម័យ៖"</string>
+    <string name="duration" msgid="3584782459928719435">"ថិរវេលា៖"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"បាន​ផ្ញើ៖"</string>
+    <string name="data_received" msgid="4062776929376067820">"បាន​ទទួល៖"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> បៃ / <xliff:g id="NUMBER_1">%2$s</xliff:g> កញ្ចប់​ព័ត៌មាន"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-lo/strings.xml b/packages/VpnDialogs/res/values-lo/strings.xml
new file mode 100644
index 0000000..9f5216b
--- /dev/null
+++ b/packages/VpnDialogs/res/values-lo/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> ພະຍາຍາມສ້າງການເຊື່ອມຕໍ່ VPN."</string>
+    <string name="warning" msgid="5470743576660160079">"ຖ້າດຳເນີນຕໍ່, ແມ່ນທ່ານກຳລັງຈະໃຫ້ສິດແກ່ແອັບພລິເຄຊັນ ໃນການດັກຂໍ້ມູນຈະລາຈອນໃນເຄືອຂ່າຍທັງໝົດ. "<b>"ຢ່າຍອມຮັບ ນອກຈາກວ່າທ່ານຈະເຊື່ອໃຈແອັບພລິເຄຊັນດັ່ງກ່າວ."</b>" ຖ້າບໍ່ດັ່ງນັ້ນ, ທ່ານຈະຕົກຢູ່ໃນຄວາມສ່ຽງ ທີ່ຂໍ້ມູນຂອງທ່ານຈະຖືກຄຸກຄາມໂດຍຊອບແວທີ່ເປັນອັນຕະລາຍ."</string>
+    <string name="accept" msgid="2889226408765810173">"ຂ້ອຍເຊື່ອແອັບພລິເຄຊັນນີ້."</string>
+    <string name="legacy_title" msgid="192936250066580964">"ເຊື່ອມຕໍ່ VPN ແລ້ວ"</string>
+    <string name="configure" msgid="4905518375574791375">"ປັບຄ່າ"</string>
+    <string name="disconnect" msgid="971412338304200056">"ຕັດການເຊື່ອມຕໍ່"</string>
+    <string name="session" msgid="6470628549473641030">"ເຊສຊັນ:"</string>
+    <string name="duration" msgid="3584782459928719435">"ໄລຍະເວລາ:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"ສົ່ງ:"</string>
+    <string name="data_received" msgid="4062776929376067820">"ຮັບ:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ໄບ / <xliff:g id="NUMBER_1">%2$s</xliff:g> ແພັກເກັດ"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-mn/strings.xml b/packages/VpnDialogs/res/values-mn/strings.xml
new file mode 100644
index 0000000..887bb73
--- /dev/null
+++ b/packages/VpnDialogs/res/values-mn/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> VPN холболтыг үүсгэх гэж байна."</string>
+    <string name="warning" msgid="5470743576660160079">"Үргэлжлүүлсэнээр та аппликешнд бүх сүлжээний урсгалыг таслах зөвшөөрлийг өгөх болно. "<b>"Аппикешн баталгаагүй гэж үзсэн тохиолдолд л зөвшөөрч болорхгүй."</b>" Бусад тохиолдолд та өөрийн датаг хортой софтверийн аюулд өртөх эрсдэлийг үүсгэж байна."</string>
+    <string name="accept" msgid="2889226408765810173">"Би энэ аппликешнд итгэж байна."</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN холбогдов"</string>
+    <string name="configure" msgid="4905518375574791375">"Тохируулах"</string>
+    <string name="disconnect" msgid="971412338304200056">"Салгах"</string>
+    <string name="session" msgid="6470628549473641030">"Сешн:"</string>
+    <string name="duration" msgid="3584782459928719435">"Үргэлжлэх хугацаа:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"Илгээсэн:"</string>
+    <string name="data_received" msgid="4062776929376067820">"Хүлээн авсан:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> байт/ <xliff:g id="NUMBER_1">%2$s</xliff:g> пакет"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-ne-rNP/strings.xml b/packages/VpnDialogs/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..03211cb
--- /dev/null
+++ b/packages/VpnDialogs/res/values-ne-rNP/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> एउटा VPN जडान सिर्जना गर्ने प्रयासहरू।"</string>
+    <string name="warning" msgid="5470743576660160079">"अगाडी बढेर, तपाईँले यस अनुप्रयोगलाई सबै नेटवर्कको ट्राफिक अवरोध गर्न अनुमति दिनु हुँदैछ। "<b>"तपाईँलाई अनुप्रयोगको विश्वास नलागेसम्म यसलाई स्वीकार नगर्नुहोस्।"</b>" अन्यथा, तपाईँ आफ्नो डेटा खराब सफ्टवेरद्वारा जोखिममा पर्नु हुनेछ।"</string>
+    <string name="accept" msgid="2889226408765810173">"म यस अनुप्रयोगलाई विश्वास गर्छु।"</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN जोडिएको छ"</string>
+    <string name="configure" msgid="4905518375574791375">"कन्फिगर गर्नुहोस्"</string>
+    <string name="disconnect" msgid="971412338304200056">"विच्छेदन गर्नुहोस्"</string>
+    <string name="session" msgid="6470628549473641030">"सत्र:"</string>
+    <string name="duration" msgid="3584782459928719435">"अवधि:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"पठाइयो:"</string>
+    <string name="data_received" msgid="4062776929376067820">"प्राप्त भयो:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> बाइटहरू / <xliff:g id="NUMBER_1">%2$s</xliff:g> प्याकेटहरू"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-ne/strings.xml b/packages/VpnDialogs/res/values-ne/strings.xml
new file mode 100644
index 0000000..03211cb
--- /dev/null
+++ b/packages/VpnDialogs/res/values-ne/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> एउटा VPN जडान सिर्जना गर्ने प्रयासहरू।"</string>
+    <string name="warning" msgid="5470743576660160079">"अगाडी बढेर, तपाईँले यस अनुप्रयोगलाई सबै नेटवर्कको ट्राफिक अवरोध गर्न अनुमति दिनु हुँदैछ। "<b>"तपाईँलाई अनुप्रयोगको विश्वास नलागेसम्म यसलाई स्वीकार नगर्नुहोस्।"</b>" अन्यथा, तपाईँ आफ्नो डेटा खराब सफ्टवेरद्वारा जोखिममा पर्नु हुनेछ।"</string>
+    <string name="accept" msgid="2889226408765810173">"म यस अनुप्रयोगलाई विश्वास गर्छु।"</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN जोडिएको छ"</string>
+    <string name="configure" msgid="4905518375574791375">"कन्फिगर गर्नुहोस्"</string>
+    <string name="disconnect" msgid="971412338304200056">"विच्छेदन गर्नुहोस्"</string>
+    <string name="session" msgid="6470628549473641030">"सत्र:"</string>
+    <string name="duration" msgid="3584782459928719435">"अवधि:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"पठाइयो:"</string>
+    <string name="data_received" msgid="4062776929376067820">"प्राप्त भयो:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> बाइटहरू / <xliff:g id="NUMBER_1">%2$s</xliff:g> प्याकेटहरू"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-si-rLK/strings.xml b/packages/VpnDialogs/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..67e0ed6
--- /dev/null
+++ b/packages/VpnDialogs/res/values-si-rLK/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"VPN සම්බන්ධතාවයක් සැදීමට <xliff:g id="APP">%s</xliff:g> උත්සාහ කරයි."</string>
+    <string name="warning" msgid="5470743576660160079">"ඉදිරියට යාමෙන්, සියලු ජාල තදබදය මගදී අල්ලා ගැනීමට ඔබ යෙදුමට අවසර දෙයි. "<b>"ඔබ යෙදුම විශ්වාස නොකරයි නම් පිළිගන්න එපා"</b>" නැතහොත්, අනිෂ්ට මෘදුකාංගයක් මඟින් ඔබගේ දත්ත නිරාවරණය වීමේ අවදානමක් ඔබට ඇත."</string>
+    <string name="accept" msgid="2889226408765810173">"මෙම යෙදුම මට විශ්වාසයි."</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN සම්බන්ධිතයි"</string>
+    <string name="configure" msgid="4905518375574791375">"වින්‍යාස කිරීම"</string>
+    <string name="disconnect" msgid="971412338304200056">"විසන්ධි කරන්න"</string>
+    <string name="session" msgid="6470628549473641030">"සැසිය:"</string>
+    <string name="duration" msgid="3584782459928719435">"කාල සීමාව:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"යවන ලද:"</string>
+    <string name="data_received" msgid="4062776929376067820">"ලැබිණි:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"බයිට <xliff:g id="NUMBER_0">%1$s</xliff:g> / පැකැට්ටු <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-si/strings.xml b/packages/VpnDialogs/res/values-si/strings.xml
new file mode 100644
index 0000000..67e0ed6
--- /dev/null
+++ b/packages/VpnDialogs/res/values-si/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"VPN සම්බන්ධතාවයක් සැදීමට <xliff:g id="APP">%s</xliff:g> උත්සාහ කරයි."</string>
+    <string name="warning" msgid="5470743576660160079">"ඉදිරියට යාමෙන්, සියලු ජාල තදබදය මගදී අල්ලා ගැනීමට ඔබ යෙදුමට අවසර දෙයි. "<b>"ඔබ යෙදුම විශ්වාස නොකරයි නම් පිළිගන්න එපා"</b>" නැතහොත්, අනිෂ්ට මෘදුකාංගයක් මඟින් ඔබගේ දත්ත නිරාවරණය වීමේ අවදානමක් ඔබට ඇත."</string>
+    <string name="accept" msgid="2889226408765810173">"මෙම යෙදුම මට විශ්වාසයි."</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN සම්බන්ධිතයි"</string>
+    <string name="configure" msgid="4905518375574791375">"වින්‍යාස කිරීම"</string>
+    <string name="disconnect" msgid="971412338304200056">"විසන්ධි කරන්න"</string>
+    <string name="session" msgid="6470628549473641030">"සැසිය:"</string>
+    <string name="duration" msgid="3584782459928719435">"කාල සීමාව:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"යවන ලද:"</string>
+    <string name="data_received" msgid="4062776929376067820">"ලැබිණි:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"බයිට <xliff:g id="NUMBER_0">%1$s</xliff:g> / පැකැට්ටු <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+</resources>
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
index 6faf4e0..ddafc66 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.net.IConnectivityManager;
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index 3d5654a..eb20995 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.net.IConnectivityManager;
@@ -28,9 +27,6 @@
 import android.os.SystemClock;
 import android.util.Log;
 import android.view.View;
-import android.widget.Button;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.android.internal.app.AlertActivity;
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifModifier.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifModifier.java
index f00362b..0531cba 100644
--- a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifModifier.java
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifModifier.java
@@ -18,7 +18,6 @@
 
 import android.util.Log;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLCanvas.java b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLCanvas.java
index 305e905..5b07477 100644
--- a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLCanvas.java
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLCanvas.java
@@ -20,8 +20,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 
-import javax.microedition.khronos.opengles.GL11;
-
 //
 // GLCanvas gives a convenient interface to draw using OpenGL.
 //
diff --git a/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java b/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
index 8511de2..cdc5cdc 100644
--- a/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
+++ b/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
@@ -24,9 +24,7 @@
 import android.graphics.BitmapFactory;
 import android.graphics.BitmapRegionDecoder;
 import android.graphics.Canvas;
-import android.graphics.Matrix;
 import android.graphics.Paint;
-import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Build;
diff --git a/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java b/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java
index 10bcdad..edb1630 100644
--- a/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java
+++ b/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java
@@ -15,7 +15,6 @@
  */
 package com.android.proxyhandler;
 
-import android.net.ProxyProperties;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -25,7 +24,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Proxy;
 import java.net.ProxySelector;
diff --git a/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java b/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java
index 109435c..cbea188 100644
--- a/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java
+++ b/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java
@@ -17,12 +17,8 @@
 
 import android.app.Service;
 import android.content.Intent;
-import android.net.Proxy;
-import android.net.ProxyProperties;
-import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.text.TextUtils;
 
 import com.android.net.IProxyCallback;
 import com.android.net.IProxyPortListener;
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 884f57e..7c0735b 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -887,6 +887,7 @@
             case MESSAGE_DISMISS:
                 if (mDialog != null) {
                     mDialog.dismiss();
+                    mDialog = null;
                 }
                 break;
             case MESSAGE_REFRESH:
diff --git a/policy/src/com/android/internal/policy/impl/IconUtilities.java b/policy/src/com/android/internal/policy/impl/IconUtilities.java
index a47c904..82f26ad 100644
--- a/policy/src/com/android/internal/policy/impl/IconUtilities.java
+++ b/policy/src/com/android/internal/policy/impl/IconUtilities.java
@@ -24,22 +24,13 @@
 import android.graphics.BlurMaskFilter;
 import android.graphics.Canvas;
 import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
 import android.graphics.PaintFlagsDrawFilter;
-import android.graphics.PixelFormat;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
-import android.graphics.RectF;
 import android.graphics.TableMaskFilter;
-import android.graphics.Typeface;
-import android.text.Layout.Alignment;
-import android.text.StaticLayout;
-import android.text.TextPaint;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.util.TypedValue;
-import android.view.ContextThemeWrapper;
 import android.content.res.Resources;
 import android.content.Context;
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java b/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java
index 6bf4beb..5d8d0d1 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.policy.impl;
 
-import java.util.Map;
-
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.View;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 44fc1f8..d0abe9c 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -22,6 +22,11 @@
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 import static android.view.WindowManager.LayoutParams.*;
 
+import android.app.ActivityOptions;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionInflater;
+import android.transition.TransitionManager;
 import android.view.ViewConfiguration;
 
 import com.android.internal.R;
@@ -52,7 +57,6 @@
 import android.media.AudioManager;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.Debug;
 import android.os.Handler;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -62,7 +66,6 @@
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
-import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TypedValue;
 import android.view.ActionMode;
@@ -146,6 +149,10 @@
     private ActionMenuPresenterCallback mActionMenuPresenterCallback;
     private PanelMenuPresenterCallback mPanelMenuPresenterCallback;
 
+    private TransitionManager mTransitionManager;
+    private Scene mContentScene;
+    private Bundle mTransitionOptions;
+
     // The icon resource has been explicitly set elsewhere
     // and should not be overwritten with a default.
     static final int FLAG_RESOURCE_SET_ICON = 1 << 0;
@@ -281,13 +288,43 @@
     }
 
     @Override
+    public TransitionManager getTransitionManager() {
+        return mTransitionManager;
+    }
+
+    @Override
+    public void setTransitionManager(TransitionManager tm) {
+        mTransitionManager = tm;
+    }
+
+    @Override
+    public Scene getContentScene() {
+        return mContentScene;
+    }
+
+    @Override
+    public void setTransitionOptions(Bundle options) {
+        mTransitionOptions = options;
+    }
+
+    @Override
     public void setContentView(int layoutResID) {
+        // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
+        // decor, when theme attributes and the like are crystalized. Do not check the feature
+        // before this happens.
         if (mContentParent == null) {
             installDecor();
-        } else {
+        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
             mContentParent.removeAllViews();
         }
-        mLayoutInflater.inflate(layoutResID, mContentParent);
+
+        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
+            final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
+                    getContext());
+            transitionTo(newScene);
+        } else {
+            mLayoutInflater.inflate(layoutResID, mContentParent);
+        }
         final Callback cb = getCallback();
         if (cb != null && !isDestroyed()) {
             cb.onContentChanged();
@@ -301,12 +338,22 @@
 
     @Override
     public void setContentView(View view, ViewGroup.LayoutParams params) {
+        // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
+        // decor, when theme attributes and the like are crystalized. Do not check the feature
+        // before this happens.
         if (mContentParent == null) {
             installDecor();
-        } else {
+        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
             mContentParent.removeAllViews();
         }
-        mContentParent.addView(view, params);
+
+        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
+            view.setLayoutParams(params);
+            final Scene newScene = new Scene(mContentParent, view);
+            transitionTo(newScene);
+        } else {
+            mContentParent.addView(view, params);
+        }
         final Callback cb = getCallback();
         if (cb != null && !isDestroyed()) {
             cb.onContentChanged();
@@ -318,6 +365,11 @@
         if (mContentParent == null) {
             installDecor();
         }
+        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
+            // TODO Augment the scenes/transitions API to support this.
+            throw new UnsupportedOperationException(
+                    "addContentView does not support content transitions");
+        }
         mContentParent.addView(view, params);
         final Callback cb = getCallback();
         if (cb != null && !isDestroyed()) {
@@ -325,6 +377,33 @@
         }
     }
 
+    private void transitionTo(Scene scene) {
+        Transition selected = null;
+        if (mTransitionOptions != null) {
+            final ActivityOptions opts = new ActivityOptions(mTransitionOptions);
+            mTransitionOptions = null;
+
+            String selectedName = null;
+            for (String sceneName : opts.getDestSceneNames()) {
+                final Transition t = mTransitionManager.getNamedTransition(sceneName, scene);
+                if (t != null) {
+                    // TODO handle args/state; inject into t/clone with params
+                    selected = t;
+                    selectedName = sceneName;
+                    break;
+                }
+            }
+            opts.dispatchSceneTransitionStarted(selectedName);
+        }
+
+        if (selected != null) {
+            TransitionManager.go(scene, selected);
+        } else {
+            mTransitionManager.transitionTo(scene);
+        }
+        mContentScene = scene;
+    }
+
     @Override
     public View getCurrentFocus() {
         return mDecor != null ? mDecor.findFocus() : null;
@@ -366,6 +445,7 @@
     }
 
     @Override
+    @Deprecated
     public void setTitleColor(int textColor) {
         if (mTitleView != null) {
             mTitleView.setTextColor(textColor);
@@ -2890,6 +2970,9 @@
             a.getValue(com.android.internal.R.styleable.Window_windowFixedHeightMinor,
                     mFixedHeightMinor);
         }
+        if (a.getBoolean(com.android.internal.R.styleable.Window_windowContentTransitions, false)) {
+            requestFeature(FEATURE_CONTENT_TRANSITIONS);
+        }
 
         final Context context = getContext();
         final int targetSdk = context.getApplicationInfo().targetSdkVersion;
@@ -3179,6 +3262,20 @@
                     });
                 }
             }
+
+            // Only inflate or create a new TransitionManager if the caller hasn't
+            // already set a custom one.
+            if (hasFeature(FEATURE_CONTENT_TRANSITIONS) && mTransitionManager == null) {
+                final int transitionRes = getWindowStyle().getResourceId(
+                        com.android.internal.R.styleable.Window_windowContentTransitionManager, 0);
+                if (transitionRes != 0) {
+                    final TransitionInflater inflater = TransitionInflater.from(getContext());
+                    mTransitionManager = inflater.inflateTransitionManager(transitionRes,
+                            mContentParent);
+                } else {
+                    mTransitionManager = new TransitionManager();
+                }
+            }
         }
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index f33ab40..8e83255 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -222,6 +222,9 @@
     // Vibrator pattern for a short vibration.
     long[] mKeyboardTapVibePattern;
 
+    // Vibrator pattern for a short vibration when tapping on an hour/minute tick of a Clock.
+    long[] mClockTickVibePattern;
+
     // Vibrator pattern for haptic feedback during boot when safe mode is disabled.
     long[] mSafeModeDisabledVibePattern;
 
@@ -304,17 +307,6 @@
     WindowState mFocusedWindow;
     IApplicationToken mFocusedApp;
 
-    private final class PointerLocationPointerEventListener implements PointerEventListener {
-        @Override
-        public void onPointerEvent(MotionEvent motionEvent) {
-            if (mPointerLocationView != null) {
-                mPointerLocationView.addPointerEvent(motionEvent);
-            }
-        }
-    }
-
-    // Pointer location view state, only modified on the mHandler Looper.
-    PointerLocationPointerEventListener mPointerLocationPointerEventListener;
     PointerLocationView mPointerLocationView;
 
     // The current size of the screen; really; extends into the overscan area of
@@ -964,6 +956,8 @@
                 com.android.internal.R.array.config_virtualKeyVibePattern);
         mKeyboardTapVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_keyboardTapVibePattern);
+        mClockTickVibePattern = getLongIntArray(mContext.getResources(),
+                com.android.internal.R.array.config_clockTickVibePattern);
         mSafeModeDisabledVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_safeModeDisabledVibePattern);
         mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
@@ -1183,7 +1177,6 @@
         if (mPointerLocationView == null) {
             mPointerLocationView = new PointerLocationView(mContext);
             mPointerLocationView.setPrintCoords(false);
-
             WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                     WindowManager.LayoutParams.MATCH_PARENT,
                     WindowManager.LayoutParams.MATCH_PARENT);
@@ -1203,22 +1196,14 @@
                     mContext.getSystemService(Context.WINDOW_SERVICE);
             lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
             wm.addView(mPointerLocationView, lp);
-
-            mPointerLocationPointerEventListener = new PointerLocationPointerEventListener();
-            mWindowManagerFuncs.registerPointerEventListener(mPointerLocationPointerEventListener);
+            mWindowManagerFuncs.registerPointerEventListener(mPointerLocationView);
         }
     }
 
     private void disablePointerLocation() {
-        if (mPointerLocationPointerEventListener != null) {
-            mWindowManagerFuncs.unregisterPointerEventListener(
-                    mPointerLocationPointerEventListener);
-            mPointerLocationPointerEventListener = null;
-        }
-
         if (mPointerLocationView != null) {
-            WindowManager wm = (WindowManager)
-                    mContext.getSystemService(Context.WINDOW_SERVICE);
+            mWindowManagerFuncs.unregisterPointerEventListener(mPointerLocationView);
+            WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
             wm.removeView(mPointerLocationView);
             mPointerLocationView = null;
         }
@@ -3275,8 +3260,9 @@
                             + mRestrictedScreenWidth;
                     pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedScreenTop
                             + mRestrictedScreenHeight;
-                } else if (attrs.type == TYPE_TOAST || attrs.type == TYPE_SYSTEM_ALERT) {
-                    // Toasts are stable to interim decor changes.
+                } else if (attrs.type == TYPE_TOAST || attrs.type == TYPE_SYSTEM_ALERT
+                        || attrs.type == TYPE_VOLUME_OVERLAY) {
+                    // These dialogs are stable to interim decor changes.
                     pf.left = df.left = of.left = cf.left = mStableLeft;
                     pf.top = df.top = of.top = cf.top = mStableTop;
                     pf.right = df.right = of.right = cf.right = mStableRight;
@@ -3380,13 +3366,10 @@
                                 WindowManager.LayoutParams attrs) {
         if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
                 + win.isVisibleOrBehindKeyguardLw());
-        if (mTopFullscreenOpaqueWindowState == null && (win.getAttrs().privateFlags
-                &WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_NAV_BAR) != 0
-                || (win.isVisibleLw() && attrs.type == TYPE_INPUT_METHOD)) {
-            if (mForcingShowNavBarLayer < 0) {
-                mForcingShowNavBar = true;
-                mForcingShowNavBarLayer = win.getSurfaceLayer();
-            }
+        if (mTopFullscreenOpaqueWindowState == null
+                && win.isVisibleLw() && attrs.type == TYPE_INPUT_METHOD) {
+            mForcingShowNavBar = true;
+            mForcingShowNavBarLayer = win.getSurfaceLayer();
         }
         if (mTopFullscreenOpaqueWindowState == null &&
                 win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) {
@@ -5019,6 +5002,9 @@
             case HapticFeedbackConstants.KEYBOARD_TAP:
                 pattern = mKeyboardTapVibePattern;
                 break;
+            case HapticFeedbackConstants.CLOCK_TICK:
+                pattern = mClockTickVibePattern;
+                break;
             case HapticFeedbackConstants.SAFE_MODE_DISABLED:
                 pattern = mSafeModeDisabledVibePattern;
                 break;
@@ -5220,6 +5206,11 @@
     }
 
     @Override
+    public int getInputMethodWindowVisibleHeightLw() {
+        return mDockBottom - mCurBottom;
+    }
+
+    @Override
     public void setCurrentUserLw(int newUserId) {
         mCurrentUserId = newUserId;
         if (mKeyguardDelegate != null) {
diff --git a/policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java b/policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java
index 8d87728..3490bd4 100644
--- a/policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java
+++ b/policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java
@@ -21,7 +21,6 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
 import android.widget.LinearLayout;
diff --git a/policy/src/com/android/internal/policy/impl/ShortcutManager.java b/policy/src/com/android/internal/policy/impl/ShortcutManager.java
index 75a1b01..bb898f7 100644
--- a/policy/src/com/android/internal/policy/impl/ShortcutManager.java
+++ b/policy/src/com/android/internal/policy/impl/ShortcutManager.java
@@ -25,7 +25,6 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
 
 import java.net.URISyntaxException;
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
index 1357462..a6cae66 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
@@ -12,7 +12,6 @@
 import android.os.UserHandle;
 import android.util.Log;
 import android.util.Slog;
-import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
diff --git a/sax/java/android/sax/Element.java b/sax/java/android/sax/Element.java
index 8c8334c..c3e275f 100644
--- a/sax/java/android/sax/Element.java
+++ b/sax/java/android/sax/Element.java
@@ -21,8 +21,6 @@
 
 import java.util.ArrayList;
 
-import android.util.Log;
-
 /**
  * An XML element. Provides access to child elements and hooks to listen
  * for events related to this element.
diff --git a/services/input/Android.mk b/services/input/Android.mk
index 6e944ef..eb2bebe 100644
--- a/services/input/Android.mk
+++ b/services/input/Android.mk
@@ -42,6 +42,8 @@
 LOCAL_C_INCLUDES := \
     external/skia/include/core
 
+LOCAL_CFLAGS += -Wno-unused-parameter
+
 LOCAL_MODULE:= libinputservice
 
 LOCAL_MODULE_TAGS := optional
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index 4d70d5f..09fca04 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -49,6 +49,7 @@
 #include <sys/ioctl.h>
 #include <sys/limits.h>
 #include <sys/sha1.h>
+#include <sys/utsname.h>
 
 /* this macro is used to tell if "bit" is set in "array"
  * it selects a byte from the array, and does a boolean AND
@@ -93,6 +94,14 @@
     return out;
 }
 
+static void getLinuxRelease(int* major, int* minor) {
+    struct utsname info;
+    if (uname(&info) || sscanf(info.release, "%d.%d", major, minor) <= 0) {
+        *major = 0, *minor = 0;
+        ALOGE("Could not get linux version: %s", strerror(errno));
+    }
+}
+
 static void setDescriptor(InputDeviceIdentifier& identifier) {
     // Compute a device descriptor that uniquely identifies the device.
     // The descriptor is assumed to be a stable identifier.  Its value should not
@@ -236,6 +245,11 @@
     result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
     LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance.  errno=%d",
             errno);
+
+    int major, minor;
+    getLinuxRelease(&major, &minor);
+    // EPOLLWAKEUP was introduced in kernel 3.5
+    mUsingEpollWakeup = major > 3 || (major == 3 && minor >= 5);
 }
 
 EventHub::~EventHub(void) {
@@ -509,8 +523,9 @@
 bool EventHub::hasLed(int32_t deviceId, int32_t led) const {
     AutoMutex _l(mLock);
     Device* device = getDeviceLocked(deviceId);
-    if (device && led >= 0 && led <= LED_MAX) {
-        if (test_bit(led, device->ledBitmask)) {
+    int32_t sc;
+    if (device && mapLed(device, led, &sc) == NO_ERROR) {
+        if (test_bit(sc, device->ledBitmask)) {
             return true;
         }
     }
@@ -520,12 +535,17 @@
 void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) {
     AutoMutex _l(mLock);
     Device* device = getDeviceLocked(deviceId);
-    if (device && !device->isVirtual() && led >= 0 && led <= LED_MAX) {
+    setLedStateLocked(device, led, on);
+}
+
+void EventHub::setLedStateLocked(Device* device, int32_t led, bool on) {
+    int32_t sc;
+    if (device && !device->isVirtual() && mapLed(device, led, &sc) != NAME_NOT_FOUND) {
         struct input_event ev;
         ev.time.tv_sec = 0;
         ev.time.tv_usec = 0;
         ev.type = EV_LED;
-        ev.code = led;
+        ev.code = sc;
         ev.value = on ? 1 : 0;
 
         ssize_t nWrite;
@@ -1239,12 +1259,13 @@
 
     if (device->classes & (INPUT_DEVICE_CLASS_JOYSTICK | INPUT_DEVICE_CLASS_GAMEPAD)) {
         device->controllerNumber = getNextControllerNumberLocked(device);
+        setLedForController(device);
     }
 
     // Register with epoll.
     struct epoll_event eventItem;
     memset(&eventItem, 0, sizeof(eventItem));
-    eventItem.events = EPOLLIN;
+    eventItem.events = mUsingEpollWakeup ? EPOLLIN : EPOLLIN | EPOLLWAKEUP;
     eventItem.data.u32 = deviceId;
     if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) {
         ALOGE("Could not add device fd to epoll instance.  errno=%d", errno);
@@ -1252,9 +1273,20 @@
         return -1;
     }
 
-    // Enable wake-lock behavior on kernels that support it.
-    // TODO: Only need this for devices that can really wake the system.
-    bool usingSuspendBlockIoctl = !ioctl(fd, EVIOCSSUSPENDBLOCK, 1);
+    String8 wakeMechanism("EPOLLWAKEUP");
+    if (!mUsingEpollWakeup) {
+#ifndef EVIOCSSUSPENDBLOCK
+        // uapi headers don't include EVIOCSSUSPENDBLOCK, and future kernels
+        // will use an epoll flag instead, so as long as we want to support
+        // this feature, we need to be prepared to define the ioctl ourselves.
+#define EVIOCSSUSPENDBLOCK _IOW('E', 0x91, int)
+#endif
+        if (ioctl(fd, EVIOCSSUSPENDBLOCK, 1)) {
+            wakeMechanism = "<none>";
+        } else {
+            wakeMechanism = "EVIOCSSUSPENDBLOCK";
+        }
+    }
 
     // Tell the kernel that we want to use the monotonic clock for reporting timestamps
     // associated with input events.  This is important because the input system
@@ -1276,14 +1308,14 @@
 
     ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, "
             "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, "
-            "usingSuspendBlockIoctl=%s, usingClockIoctl=%s",
+            "wakeMechanism=%s, usingClockIoctl=%s",
          deviceId, fd, devicePath, device->identifier.name.string(),
          device->classes,
          device->configurationFile.string(),
          device->keyMap.keyLayoutFile.string(),
          device->keyMap.keyCharacterMapFile.string(),
          toString(mBuiltInKeyboardId == deviceId),
-         toString(usingSuspendBlockIoctl), toString(usingClockIoctl));
+         wakeMechanism.string(), toString(usingClockIoctl));
 
     addDeviceLocked(device);
     return 0;
@@ -1372,6 +1404,11 @@
     mControllerNumbers.clearBit(static_cast<uint32_t>(num - 1));
 }
 
+void EventHub::setLedForController(Device* device) {
+    for (int i = 0; i < MAX_CONTROLLER_LEDS; i++) {
+        setLedStateLocked(device, ALED_CONTROLLER_1 + i, device->controllerNumber == i + 1);
+    }
+}
 
 bool EventHub::hasKeycodeLocked(Device* device, int keycode) const {
     if (!device->keyMap.haveKeyLayout() || !device->keyBitmask) {
@@ -1391,6 +1428,21 @@
     return false;
 }
 
+status_t EventHub::mapLed(Device* device, int32_t led, int32_t* outScanCode) const {
+    if (!device->keyMap.haveKeyLayout() || !device->ledBitmask) {
+        return NAME_NOT_FOUND;
+    }
+
+    int32_t scanCode;
+    if(device->keyMap.keyLayoutMap->findScanCodeForLed(led, &scanCode) != NAME_NOT_FOUND) {
+        if(scanCode >= 0 && scanCode <= LED_MAX && test_bit(scanCode, device->ledBitmask)) {
+            *outScanCode = scanCode;
+            return NO_ERROR;
+        }
+    }
+    return NAME_NOT_FOUND;
+}
+
 status_t EventHub::closeDeviceByPathLocked(const char *devicePath) {
     Device* device = getDeviceByPathLocked(devicePath);
     if (device) {
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index ae28f01..a9a28d2 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -231,6 +231,8 @@
             uint8_t* outFlags) const = 0;
 
     virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const = 0;
+
+    /* LED related functions expect Android LED constants, not scan codes or HID usages */
     virtual bool hasLed(int32_t deviceId, int32_t led) const = 0;
     virtual void setLedState(int32_t deviceId, int32_t led, bool on) = 0;
 
@@ -393,6 +395,10 @@
 
     int32_t getNextControllerNumberLocked(Device* device);
     void releaseControllerNumberLocked(Device* device);
+    void setLedForController(Device* device);
+
+    status_t mapLed(Device* device, int32_t led, int32_t* outScanCode) const;
+    void setLedStateLocked(Device* device, int32_t led, bool on);
 
     // Protect all internal state.
     mutable Mutex mLock;
@@ -440,6 +446,8 @@
     size_t mPendingEventCount;
     size_t mPendingEventIndex;
     bool mPendingINotify;
+
+    bool mUsingEpollWakeup;
 };
 
 }; // namespace android
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 03852a5..a683c4b 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -2197,9 +2197,9 @@
 }
 
 void KeyboardInputMapper::resetLedState() {
-    initializeLedState(mCapsLockLedState, LED_CAPSL);
-    initializeLedState(mNumLockLedState, LED_NUML);
-    initializeLedState(mScrollLockLedState, LED_SCROLLL);
+    initializeLedState(mCapsLockLedState, ALED_CAPS_LOCK);
+    initializeLedState(mNumLockLedState, ALED_NUM_LOCK);
+    initializeLedState(mScrollLockLedState, ALED_SCROLL_LOCK);
 
     updateLedState(true);
 }
@@ -2210,11 +2210,11 @@
 }
 
 void KeyboardInputMapper::updateLedState(bool reset) {
-    updateLedStateForModifier(mCapsLockLedState, LED_CAPSL,
+    updateLedStateForModifier(mCapsLockLedState, ALED_CAPS_LOCK,
             AMETA_CAPS_LOCK_ON, reset);
-    updateLedStateForModifier(mNumLockLedState, LED_NUML,
+    updateLedStateForModifier(mNumLockLedState, ALED_NUM_LOCK,
             AMETA_NUM_LOCK_ON, reset);
-    updateLedStateForModifier(mScrollLockLedState, LED_SCROLLL,
+    updateLedStateForModifier(mScrollLockLedState, ALED_SCROLL_LOCK,
             AMETA_SCROLL_LOCK_ON, reset);
 }
 
@@ -6283,7 +6283,7 @@
 
                 // To eliminate noise while the joystick is at rest, filter out small variations
                 // in axis values up front.
-                axis.filter = axis.flat * 0.25f;
+                axis.filter = axis.fuzz ? axis.fuzz : axis.flat * 0.25f;
 
                 mAxes.add(abs, axis);
             }
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index a8bb636..e6f45b6 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -574,8 +574,8 @@
 private:
     InputReaderContext* mContext;
     int32_t mId;
-    int32_t mControllerNumber;
     int32_t mGeneration;
+    int32_t mControllerNumber;
     InputDeviceIdentifier mIdentifier;
     String8 mAlias;
     uint32_t mClasses;
diff --git a/services/input/SpriteController.cpp b/services/input/SpriteController.cpp
index fd9c66b..2667a72 100644
--- a/services/input/SpriteController.cpp
+++ b/services/input/SpriteController.cpp
@@ -216,12 +216,12 @@
                 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
                 surfaceCanvas.drawBitmap(update.state.icon.bitmap, 0, 0, &paint);
 
-                if (outBuffer.width > uint32_t(update.state.icon.bitmap.width())) {
+                if (outBuffer.width > update.state.icon.bitmap.width()) {
                     paint.setColor(0); // transparent fill color
                     surfaceCanvas.drawRectCoords(update.state.icon.bitmap.width(), 0,
                             outBuffer.width, update.state.icon.bitmap.height(), paint);
                 }
-                if (outBuffer.height > uint32_t(update.state.icon.bitmap.height())) {
+                if (outBuffer.height > update.state.icon.bitmap.height()) {
                     paint.setColor(0); // transparent fill color
                     surfaceCanvas.drawRectCoords(0, update.state.icon.bitmap.height(),
                             outBuffer.width, outBuffer.height, paint);
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 5f3f894..b234a4e 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -160,7 +160,7 @@
 
         mBatteryPropertiesListener = new BatteryListener();
 
-        IBinder b = ServiceManager.getService("batterypropreg");
+        IBinder b = ServiceManager.getService("batteryproperties");
         mBatteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b);
 
         try {
@@ -314,8 +314,6 @@
                     + ", batteryLevel=" + mBatteryProps.batteryLevel
                     + ", batteryTechnology=" + mBatteryProps.batteryTechnology
                     + ", batteryVoltage=" + mBatteryProps.batteryVoltage
-                    + ", batteryCurrentNow=" + mBatteryProps.batteryCurrentNow
-                    + ", batteryChargeCounter=" + mBatteryProps.batteryChargeCounter
                     + ", batteryTemperature=" + mBatteryProps.batteryTemperature
                     + ", mBatteryLevelCritical=" + mBatteryLevelCritical
                     + ", mPlugType=" + mPlugType);
@@ -616,15 +614,6 @@
                 pw.println("  level: " + mBatteryProps.batteryLevel);
                 pw.println("  scale: " + BATTERY_SCALE);
                 pw.println("  voltage: " + mBatteryProps.batteryVoltage);
-
-                if (mBatteryProps.batteryCurrentNow != Integer.MIN_VALUE) {
-                    pw.println("  current now: " + mBatteryProps.batteryCurrentNow);
-                }
-
-                if (mBatteryProps.batteryChargeCounter != Integer.MIN_VALUE) {
-                    pw.println("  charge counter: " + mBatteryProps.batteryChargeCounter);
-                }
-
                 pw.println("  temperature: " + mBatteryProps.batteryTemperature);
                 pw.println("  technology: " + mBatteryProps.batteryTechnology);
             } else if (args.length == 3 && "set".equals(args[0])) {
diff --git a/services/java/com/android/server/CommonTimeManagementService.java b/services/java/com/android/server/CommonTimeManagementService.java
index 710fb9d..60b366a 100644
--- a/services/java/com/android/server/CommonTimeManagementService.java
+++ b/services/java/com/android/server/CommonTimeManagementService.java
@@ -18,7 +18,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.net.InetAddress;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -26,10 +25,8 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
 import android.net.INetworkManagementEventObserver;
 import android.net.InterfaceConfiguration;
-import android.net.NetworkInfo;
 import android.os.Binder;
 import android.os.CommonTimeConfig;
 import android.os.Handler;
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index baff661..6574898 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -112,6 +112,7 @@
 import com.android.internal.telephony.DctConstants;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.XmlUtils;
 import com.android.server.am.BatteryStatsService;
@@ -142,7 +143,6 @@
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.URL;
-import java.net.URLConnection;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -1567,9 +1567,12 @@
             return false;
         }
         NetworkStateTracker tracker = mNetTrackers[networkType];
-        DetailedState netState = tracker.getNetworkInfo().getDetailedState();
+        DetailedState netState = DetailedState.DISCONNECTED;
+        if (tracker != null) {
+            netState = tracker.getNetworkInfo().getDetailedState();
+        }
 
-        if (tracker == null || (netState != DetailedState.CONNECTED &&
+        if ((netState != DetailedState.CONNECTED &&
                 netState != DetailedState.CAPTIVE_PORTAL_CHECK) ||
                 tracker.isTeardownRequested()) {
             if (VDBG) {
@@ -2322,36 +2325,6 @@
         }
     }
 
-    private void handleCaptivePortalTrackerCheck(NetworkInfo info) {
-        if (DBG) log("Captive portal check " + info);
-        int type = info.getType();
-        final NetworkStateTracker thisNet = mNetTrackers[type];
-        if (mNetConfigs[type].isDefault()) {
-            if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != type) {
-                if (isNewNetTypePreferredOverCurrentNetType(type)) {
-                    if (DBG) log("Captive check on " + info.getTypeName());
-                    mCaptivePortalTracker.detectCaptivePortal(new NetworkInfo(info));
-                    return;
-                } else {
-                    if (DBG) log("Tear down low priority net " + info.getTypeName());
-                    teardown(thisNet);
-                    return;
-                }
-            }
-        }
-
-        if (DBG) log("handleCaptivePortalTrackerCheck: call captivePortalCheckComplete ni=" + info);
-        thisNet.captivePortalCheckComplete();
-    }
-
-    /** @hide */
-    @Override
-    public void captivePortalCheckComplete(NetworkInfo info) {
-        enforceConnectivityInternalPermission();
-        if (DBG) log("captivePortalCheckComplete: ni=" + info);
-        mNetTrackers[info.getType()].captivePortalCheckComplete();
-    }
-
     /** @hide */
     @Override
     public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
@@ -2978,9 +2951,6 @@
                     if (info.getDetailedState() ==
                             NetworkInfo.DetailedState.FAILED) {
                         handleConnectionFailure(info);
-                    } else if (info.getDetailedState() ==
-                            DetailedState.CAPTIVE_PORTAL_CHECK) {
-                        handleCaptivePortalTrackerCheck(info);
                     } else if (info.isConnectedToProvisioningNetwork()) {
                         /**
                          * TODO: Create ConnectivityManager.TYPE_MOBILE_PROVISIONING
@@ -4560,15 +4530,27 @@
             mdst.enableMobileProvisioning(url);
         } else {
             if (DBG) log("handleMobileProvisioningAction: on default network");
-            Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
-                    Intent.CATEGORY_APP_BROWSER);
-            newIntent.setData(Uri.parse(url));
-            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
-                    Intent.FLAG_ACTIVITY_NEW_TASK);
-            try {
-                mContext.startActivity(newIntent);
-            } catch (ActivityNotFoundException e) {
-                loge("handleMobileProvisioningAction: startActivity failed" + e);
+            // Check for  apps that can handle provisioning first
+            Intent provisioningIntent = new Intent(TelephonyIntents.ACTION_CARRIER_SETUP);
+            provisioningIntent.addCategory(TelephonyIntents.CATEGORY_MCCMNC_PREFIX
+                    + mTelephonyManager.getSimOperator());
+            if (mContext.getPackageManager().resolveActivity(provisioningIntent, 0 /* flags */)
+                    != null) {
+                provisioningIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
+                        Intent.FLAG_ACTIVITY_NEW_TASK);
+                mContext.startActivity(provisioningIntent);
+            } else {
+                // If no apps exist, use standard URL ACTION_VIEW method
+                Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
+                        Intent.CATEGORY_APP_BROWSER);
+                newIntent.setData(Uri.parse(url));
+                newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
+                        Intent.FLAG_ACTIVITY_NEW_TASK);
+                try {
+                    mContext.startActivity(newIntent);
+                } catch (ActivityNotFoundException e) {
+                    loge("handleMobileProvisioningAction: startActivity failed" + e);
+                }
             }
         }
     }
diff --git a/services/java/com/android/server/ConsumerIrService.java b/services/java/com/android/server/ConsumerIrService.java
index 783dff1..066a9c4 100644
--- a/services/java/com/android/server/ConsumerIrService.java
+++ b/services/java/com/android/server/ConsumerIrService.java
@@ -16,33 +16,13 @@
 
 package com.android.server;
 
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.PackageManager;
-import android.database.ContentObserver;
-import android.hardware.input.InputManager;
 import android.hardware.IConsumerIrService;
-import android.os.Handler;
 import android.os.PowerManager;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.Binder;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.WorkSource;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
 import android.util.Slog;
-import android.view.InputDevice;
 
 import java.lang.RuntimeException;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.ListIterator;
 
 public class ConsumerIrService extends IConsumerIrService.Stub {
     private static final String TAG = "ConsumerIrService";
diff --git a/services/java/com/android/server/DiskStatsService.java b/services/java/com/android/server/DiskStatsService.java
index ac25dc5..bc12fc5 100644
--- a/services/java/com/android/server/DiskStatsService.java
+++ b/services/java/com/android/server/DiskStatsService.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.os.Binder;
 import android.os.Environment;
-import android.os.FileUtils;
 import android.os.StatFs;
 import android.os.SystemClock;
 
diff --git a/services/java/com/android/server/EntropyMixer.java b/services/java/com/android/server/EntropyMixer.java
index fbb66f9..24d8d1e 100644
--- a/services/java/com/android/server/EntropyMixer.java
+++ b/services/java/com/android/server/EntropyMixer.java
@@ -20,7 +20,6 @@
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.OutputStream;
 import java.io.PrintWriter;
 
 import android.content.BroadcastReceiver;
@@ -36,7 +35,8 @@
 
 /**
  * A service designed to load and periodically save &quot;randomness&quot;
- * for the Linux kernel.
+ * for the Linux kernel RNG and to mix in data from Hardware RNG (if present)
+ * into the Linux RNG.
  *
  * <p>When a Linux system starts up, the entropy pool associated with
  * {@code /dev/random} may be in a fairly predictable state.  Applications which
@@ -45,6 +45,13 @@
  * this effect, it's helpful to carry the entropy pool information across
  * shutdowns and startups.
  *
+ * <p>On systems with Hardware RNG (/dev/hw_random), a block of output from HW
+ * RNG is mixed into the Linux RNG on EntropyMixer's startup and whenever
+ * EntropyMixer periodically runs to save a block of output from Linux RNG on
+ * disk. This mixing is done in a way that does not increase the Linux RNG's
+ * entropy estimate is not increased. This is to avoid having to trust/verify
+ * the quality and authenticity of the &quot;randomness&quot; of the HW RNG.
+ *
  * <p>This class was modeled after the script in
  * <a href="http://www.kernel.org/doc/man-pages/online/pages/man4/random.4.html">man
  * 4 random</a>.
@@ -57,6 +64,7 @@
     private static final long START_NANOTIME = System.nanoTime();
 
     private final String randomDevice;
+    private final String hwRandomDevice;
     private final String entropyFile;
 
     /**
@@ -69,6 +77,7 @@
                 Slog.e(TAG, "Will not process invalid message");
                 return;
             }
+            addHwRandomEntropy();
             writeEntropy();
             scheduleEntropyWriter();
         }
@@ -82,18 +91,25 @@
     };
 
     public EntropyMixer(Context context) {
-        this(context, getSystemDir() + "/entropy.dat", "/dev/urandom");
+        this(context, getSystemDir() + "/entropy.dat", "/dev/urandom", "/dev/hw_random");
     }
 
     /** Test only interface, not for public use */
-    public EntropyMixer(Context context, String entropyFile, String randomDevice) {
+    public EntropyMixer(
+            Context context,
+            String entropyFile,
+            String randomDevice,
+            String hwRandomDevice) {
         if (randomDevice == null) { throw new NullPointerException("randomDevice"); }
+        if (hwRandomDevice == null) { throw new NullPointerException("hwRandomDevice"); }
         if (entropyFile == null) { throw new NullPointerException("entropyFile"); }
 
         this.randomDevice = randomDevice;
+        this.hwRandomDevice = hwRandomDevice;
         this.entropyFile = entropyFile;
         loadInitialEntropy();
         addDeviceSpecificEntropy();
+        addHwRandomEntropy();
         writeEntropy();
         scheduleEntropyWriter();
         IntentFilter broadcastFilter = new IntentFilter(Intent.ACTION_SHUTDOWN);
@@ -168,6 +184,20 @@
         }
     }
 
+    /**
+     * Mixes in the output from HW RNG (if present) into the Linux RNG.
+     */
+    private void addHwRandomEntropy() {
+        try {
+            RandomBlock.fromFile(hwRandomDevice).toFile(randomDevice, false);
+            Slog.i(TAG, "Added HW RNG output to entropy pool");
+        } catch (FileNotFoundException ignored) {
+            // HW RNG not present/exposed -- ignore
+        } catch (IOException e) {
+            Slog.w(TAG, "Failed to add HW RNG output to entropy pool", e);
+        }
+    }
+
     private static String getSystemDir() {
         File dataDir = Environment.getDataDirectory();
         File systemDir = new File(dataDir, "system");
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index a996dbd..f061149 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -16,6 +16,8 @@
 package com.android.server;
 
 import com.android.internal.content.PackageMonitor;
+import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController;
+import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
 import com.android.internal.inputmethod.InputMethodUtils;
 import com.android.internal.inputmethod.InputMethodUtils.InputMethodSettings;
 import com.android.internal.os.HandlerCaller;
@@ -114,12 +116,9 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
-import java.util.TreeMap;
 
 /**
  * This class provides a system service that manages input methods.
@@ -150,7 +149,7 @@
 
     static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
 
-    static final long TIME_TO_RECONNECT = 10*1000;
+    static final long TIME_TO_RECONNECT = 3 * 1000;
 
     static final int SECURE_SUGGESTION_SPANS_MAX_SIZE = 20;
 
@@ -167,7 +166,6 @@
     final HandlerCaller mCaller;
     final boolean mHasFeature;
     private InputMethodFileManager mFileManager;
-    private InputMethodAndSubtypeListManager mImListManager;
     private final HardKeyboardListener mHardKeyboardListener;
     private final WindowManagerService mWindowManagerService;
 
@@ -179,6 +177,7 @@
     final HashMap<String, InputMethodInfo> mMethodMap = new HashMap<String, InputMethodInfo>();
     private final LruCache<SuggestionSpan, InputMethodInfo> mSecureSuggestionSpans =
             new LruCache<SuggestionSpan, InputMethodInfo>(SECURE_SUGGESTION_SPANS_MAX_SIZE);
+    private final InputMethodSubtypeSwitchingController mSwitchingController;
 
     // Used to bring IME service up to visible adjustment while it is being shown.
     final ServiceConnection mVisibleConnection = new ServiceConnection() {
@@ -677,7 +676,8 @@
         mSettings = new InputMethodSettings(
                 mRes, context.getContentResolver(), mMethodMap, mMethodList, userId);
         mFileManager = new InputMethodFileManager(mMethodMap, userId);
-        mImListManager = new InputMethodAndSubtypeListManager(context, this);
+        mSwitchingController = new InputMethodSubtypeSwitchingController(mSettings);
+        mSwitchingController.resetCircularListLocked(context);
 
         // Just checking if defaultImiId is empty or not
         final String defaultImiId = mSettings.getSelectedInputMethod();
@@ -757,8 +757,8 @@
             if (DEBUG) {
                 Slog.i(TAG, "Locale has been changed to " + newLocale);
             }
-            // InputMethodAndSubtypeListManager should be reset when the locale is changed.
-            mImListManager = new InputMethodAndSubtypeListManager(mContext, this);
+            // CircularList should be reset when the locale is changed.
+            mSwitchingController.resetCircularListLocked(mContext);
             buildInputMethodListLocked(mMethodList, mMethodMap, resetDefaultEnabledIme);
             if (!updateOnlyWhenLocaleChanged) {
                 final String selectedImiId = mSettings.getSelectedInputMethod();
@@ -960,17 +960,6 @@
         }
     }
 
-    private HashMap<InputMethodInfo, List<InputMethodSubtype>>
-            getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked() {
-        HashMap<InputMethodInfo, List<InputMethodSubtype>> enabledInputMethodAndSubtypes =
-                new HashMap<InputMethodInfo, List<InputMethodSubtype>>();
-        for (InputMethodInfo imi: mSettings.getEnabledInputMethodListLocked()) {
-            enabledInputMethodAndSubtypes.put(
-                    imi, mSettings.getEnabledInputMethodSubtypeListLocked(mContext, imi, true));
-        }
-        return enabledInputMethodAndSubtypes;
-    }
-
     /**
      * @param imiId if null, returns enabled subtypes for the current imi
      * @return enabled subtypes of the specified imi
@@ -2153,7 +2142,7 @@
             return false;
         }
         synchronized (mMethodMap) {
-            final ImeSubtypeListItem nextSubtype = mImListManager.getNextInputMethod(
+            final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethod(
                     onlyCurrentIme, mMethodMap.get(mCurMethodId), mCurrentSubtype);
             if (nextSubtype == null) {
                 return false;
@@ -2169,7 +2158,7 @@
             return false;
         }
         synchronized (mMethodMap) {
-            final ImeSubtypeListItem nextSubtype = mImListManager.getNextInputMethod(
+            final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethod(
                     false /* onlyCurrentIme */, mMethodMap.get(mCurMethodId), mCurrentSubtype);
             if (nextSubtype == null) {
                 return false;
@@ -2242,6 +2231,22 @@
         return;
     }
 
+    @Override
+    public int getInputMethodWindowVisibleHeight() {
+        return mWindowManagerService.getInputMethodWindowVisibleHeight();
+    }
+
+    @Override
+    public void notifyTextCommitted() {
+        if (DEBUG) {
+            Slog.d(TAG, "Got the notification of commitText");
+        }
+        final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
+        if (imi != null) {
+            mSwitchingController.onCommitText(imi, mCurrentSubtype);
+        }
+    }
+
     private void setInputMethodWithSubtypeId(IBinder token, String id, int subtypeId) {
         synchronized (mMethodMap) {
             if (token == null) {
@@ -2620,7 +2625,8 @@
 
         synchronized (mMethodMap) {
             final HashMap<InputMethodInfo, List<InputMethodSubtype>> immis =
-                    getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked();
+                    mSettings.getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked(
+                            mContext);
             if (immis == null || immis.size() == 0) {
                 return;
             }
@@ -2628,7 +2634,7 @@
             hideInputMethodMenuLocked();
 
             final List<ImeSubtypeListItem> imList =
-                    mImListManager.getSortedInputMethodAndSubtypeList(
+                    mSwitchingController.getSortedInputMethodAndSubtypeList(
                             showSubtypes, mInputShown, isScreenLocked);
 
             if (lastInputMethodSubtypeId == NOT_A_SUBTYPE_ID) {
@@ -2747,66 +2753,6 @@
         }
     }
 
-    private static class ImeSubtypeListItem implements Comparable<ImeSubtypeListItem> {
-        public final CharSequence mImeName;
-        public final CharSequence mSubtypeName;
-        public final InputMethodInfo mImi;
-        public final int mSubtypeId;
-        private final boolean mIsSystemLocale;
-        private final boolean mIsSystemLanguage;
-
-        public ImeSubtypeListItem(CharSequence imeName, CharSequence subtypeName,
-                InputMethodInfo imi, int subtypeId, String subtypeLocale, String systemLocale) {
-            mImeName = imeName;
-            mSubtypeName = subtypeName;
-            mImi = imi;
-            mSubtypeId = subtypeId;
-            if (TextUtils.isEmpty(subtypeLocale)) {
-                mIsSystemLocale = false;
-                mIsSystemLanguage = false;
-            } else {
-                mIsSystemLocale = subtypeLocale.equals(systemLocale);
-                mIsSystemLanguage = mIsSystemLocale
-                        || subtypeLocale.startsWith(systemLocale.substring(0, 2));
-            }
-        }
-
-        @Override
-        public int compareTo(ImeSubtypeListItem other) {
-            if (TextUtils.isEmpty(mImeName)) {
-                return 1;
-            }
-            if (TextUtils.isEmpty(other.mImeName)) {
-                return -1;
-            }
-            if (!TextUtils.equals(mImeName, other.mImeName)) {
-                return mImeName.toString().compareTo(other.mImeName.toString());
-            }
-            if (TextUtils.equals(mSubtypeName, other.mSubtypeName)) {
-                return 0;
-            }
-            if (mIsSystemLocale) {
-                return -1;
-            }
-            if (other.mIsSystemLocale) {
-                return 1;
-            }
-            if (mIsSystemLanguage) {
-                return -1;
-            }
-            if (other.mIsSystemLanguage) {
-                return 1;
-            }
-            if (TextUtils.isEmpty(mSubtypeName)) {
-                return 1;
-            }
-            if (TextUtils.isEmpty(other.mSubtypeName)) {
-                return -1;
-            }
-            return mSubtypeName.toString().compareTo(other.mSubtypeName.toString());
-        }
-    }
-
     private static class ImeSubtypeListAdapter extends ArrayAdapter<ImeSubtypeListItem> {
         private final LayoutInflater mInflater;
         private final int mTextViewResourceId;
@@ -3178,123 +3124,6 @@
         }
     }
 
-    private static class InputMethodAndSubtypeListManager {
-        private final Context mContext;
-        // Used to load label
-        private final PackageManager mPm;
-        private final InputMethodManagerService mImms;
-        private final String mSystemLocaleStr;
-        public InputMethodAndSubtypeListManager(Context context, InputMethodManagerService imms) {
-            mContext = context;
-            mPm = context.getPackageManager();
-            mImms = imms;
-            final Locale locale = context.getResources().getConfiguration().locale;
-            mSystemLocaleStr = locale != null ? locale.toString() : "";
-        }
-
-        private final TreeMap<InputMethodInfo, List<InputMethodSubtype>> mSortedImmis =
-                new TreeMap<InputMethodInfo, List<InputMethodSubtype>>(
-                        new Comparator<InputMethodInfo>() {
-                            @Override
-                            public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
-                                if (imi2 == null) return 0;
-                                if (imi1 == null) return 1;
-                                if (mPm == null) {
-                                    return imi1.getId().compareTo(imi2.getId());
-                                }
-                                CharSequence imiId1 = imi1.loadLabel(mPm) + "/" + imi1.getId();
-                                CharSequence imiId2 = imi2.loadLabel(mPm) + "/" + imi2.getId();
-                                return imiId1.toString().compareTo(imiId2.toString());
-                            }
-                        });
-
-        public ImeSubtypeListItem getNextInputMethod(
-                boolean onlyCurrentIme, InputMethodInfo imi, InputMethodSubtype subtype) {
-            if (imi == null) {
-                return null;
-            }
-            final List<ImeSubtypeListItem> imList = getSortedInputMethodAndSubtypeList();
-            if (imList.size() <= 1) {
-                return null;
-            }
-            final int N = imList.size();
-            final int currentSubtypeId = subtype != null
-                    ? InputMethodUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode())
-                    : NOT_A_SUBTYPE_ID;
-            for (int i = 0; i < N; ++i) {
-                final ImeSubtypeListItem isli = imList.get(i);
-                if (isli.mImi.equals(imi) && isli.mSubtypeId == currentSubtypeId) {
-                    if (!onlyCurrentIme) {
-                        return imList.get((i + 1) % N);
-                    }
-                    for (int j = 0; j < N - 1; ++j) {
-                        final ImeSubtypeListItem candidate = imList.get((i + j + 1) % N);
-                        if (candidate.mImi.equals(imi)) {
-                            return candidate;
-                        }
-                    }
-                    return null;
-                }
-            }
-            return null;
-        }
-
-        public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList() {
-            return getSortedInputMethodAndSubtypeList(true, false, false);
-        }
-
-        public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(boolean showSubtypes,
-                boolean inputShown, boolean isScreenLocked) {
-            final ArrayList<ImeSubtypeListItem> imList = new ArrayList<ImeSubtypeListItem>();
-            final HashMap<InputMethodInfo, List<InputMethodSubtype>> immis =
-                    mImms.getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked();
-            if (immis == null || immis.size() == 0) {
-                return Collections.emptyList();
-            }
-            mSortedImmis.clear();
-            mSortedImmis.putAll(immis);
-            for (InputMethodInfo imi : mSortedImmis.keySet()) {
-                if (imi == null) continue;
-                List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypeList = immis.get(imi);
-                HashSet<String> enabledSubtypeSet = new HashSet<String>();
-                for (InputMethodSubtype subtype: explicitlyOrImplicitlyEnabledSubtypeList) {
-                    enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
-                }
-                final CharSequence imeLabel = imi.loadLabel(mPm);
-                if (showSubtypes && enabledSubtypeSet.size() > 0) {
-                    final int subtypeCount = imi.getSubtypeCount();
-                    if (DEBUG) {
-                        Slog.v(TAG, "Add subtypes: " + subtypeCount + ", " + imi.getId());
-                    }
-                    for (int j = 0; j < subtypeCount; ++j) {
-                        final InputMethodSubtype subtype = imi.getSubtypeAt(j);
-                        final String subtypeHashCode = String.valueOf(subtype.hashCode());
-                        // We show all enabled IMEs and subtypes when an IME is shown.
-                        if (enabledSubtypeSet.contains(subtypeHashCode)
-                                && ((inputShown && !isScreenLocked) || !subtype.isAuxiliary())) {
-                            final CharSequence subtypeLabel =
-                                    subtype.overridesImplicitlyEnabledSubtype() ? null
-                                            : subtype.getDisplayName(mContext, imi.getPackageName(),
-                                                    imi.getServiceInfo().applicationInfo);
-                            imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, imi, j,
-                                    subtype.getLocale(), mSystemLocaleStr));
-
-                            // Removing this subtype from enabledSubtypeSet because we no longer
-                            // need to add an entry of this subtype to imList to avoid duplicated
-                            // entries.
-                            enabledSubtypeSet.remove(subtypeHashCode);
-                        }
-                    }
-                } else {
-                    imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID,
-                            null, mSystemLocaleStr));
-                }
-            }
-            Collections.sort(imList);
-            return imList;
-        }
-    }
-
     // TODO: Cache the state for each user and reset when the cached user is removed.
     private static class InputMethodFileManager {
         private static final String SYSTEM_PATH = "system";
diff --git a/services/java/com/android/server/LockSettingsService.java b/services/java/com/android/server/LockSettingsService.java
index 35e7afa..fe814fc 100644
--- a/services/java/com/android/server/LockSettingsService.java
+++ b/services/java/com/android/server/LockSettingsService.java
@@ -16,7 +16,6 @@
 
 package com.android.server;
 
-import android.app.ActivityManagerNative;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
@@ -29,8 +28,6 @@
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
 import android.database.sqlite.SQLiteStatement;
-import android.media.AudioManager;
-import android.media.AudioService;
 import android.os.Binder;
 import android.os.Environment;
 import android.os.RemoteException;
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 92f99c2..40ea49e 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -136,6 +136,7 @@
         public static final int BandwidthControl          = 601;
         public static final int InterfaceClassActivity    = 613;
         public static final int InterfaceAddressChange    = 614;
+        public static final int InterfaceDnsServerInfo    = 615;
     }
 
     /**
@@ -404,7 +405,7 @@
     /**
      * Notify our observers of a new or updated interface address.
      */
-    private void notifyAddressUpdated(String address, String iface, int flags, int scope) {
+    private void notifyAddressUpdated(LinkAddress address, String iface, int flags, int scope) {
         final int length = mObservers.beginBroadcast();
         for (int i = 0; i < length; i++) {
             try {
@@ -419,7 +420,7 @@
     /**
      * Notify our observers of a deleted interface address.
      */
-    private void notifyAddressRemoved(String address, String iface, int flags, int scope) {
+    private void notifyAddressRemoved(LinkAddress address, String iface, int flags, int scope) {
         final int length = mObservers.beginBroadcast();
         for (int i = 0; i < length; i++) {
             try {
@@ -431,6 +432,21 @@
         mObservers.finishBroadcast();
     }
 
+    /**
+     * Notify our observers of DNS server information received.
+     */
+    private void notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) {
+        final int length = mObservers.beginBroadcast();
+        for (int i = 0; i < length; i++) {
+            try {
+                mObservers.getBroadcastItem(i).interfaceDnsServerInfo(iface, lifetime, addresses);
+            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
+            }
+        }
+        mObservers.finishBroadcast();
+    }
+
     //
     // Netd Callback handling
     //
@@ -455,6 +471,7 @@
 
         @Override
         public boolean onEvent(int code, String raw, String[] cooked) {
+            String errorMessage = String.format("Invalid event from daemon (%s)", raw);
             switch (code) {
             case NetdResponseCode.InterfaceChange:
                     /*
@@ -465,8 +482,7 @@
                      *         "NNN Iface linkstatus <name> <up/down>"
                      */
                     if (cooked.length < 4 || !cooked[1].equals("Iface")) {
-                        throw new IllegalStateException(
-                                String.format("Invalid event from daemon (%s)", raw));
+                        throw new IllegalStateException(errorMessage);
                     }
                     if (cooked[2].equals("added")) {
                         notifyInterfaceAdded(cooked[3]);
@@ -481,8 +497,7 @@
                         notifyInterfaceLinkStateChanged(cooked[3], cooked[4].equals("up"));
                         return true;
                     }
-                    throw new IllegalStateException(
-                            String.format("Invalid event from daemon (%s)", raw));
+                    throw new IllegalStateException(errorMessage);
                     // break;
             case NetdResponseCode.BandwidthControl:
                     /*
@@ -490,15 +505,13 @@
                      * Format: "NNN limit alert <alertName> <ifaceName>"
                      */
                     if (cooked.length < 5 || !cooked[1].equals("limit")) {
-                        throw new IllegalStateException(
-                                String.format("Invalid event from daemon (%s)", raw));
+                        throw new IllegalStateException(errorMessage);
                     }
                     if (cooked[2].equals("alert")) {
                         notifyLimitReached(cooked[3], cooked[4]);
                         return true;
                     }
-                    throw new IllegalStateException(
-                            String.format("Invalid event from daemon (%s)", raw));
+                    throw new IllegalStateException(errorMessage);
                     // break;
             case NetdResponseCode.InterfaceClassActivity:
                     /*
@@ -506,8 +519,7 @@
                      * Format: "NNN IfaceClass <active/idle> <label>"
                      */
                     if (cooked.length < 4 || !cooked[1].equals("IfaceClass")) {
-                        throw new IllegalStateException(
-                                String.format("Invalid event from daemon (%s)", raw));
+                        throw new IllegalStateException(errorMessage);
                     }
                     boolean isActive = cooked[2].equals("active");
                     notifyInterfaceClassActivity(cooked[3], isActive);
@@ -519,24 +531,47 @@
                      * Format: "NNN Address updated <addr> <iface> <flags> <scope>"
                      *         "NNN Address removed <addr> <iface> <flags> <scope>"
                      */
-                    String msg = String.format("Invalid event from daemon (%s)", raw);
-                    if (cooked.length < 6 || !cooked[1].equals("Address")) {
-                        throw new IllegalStateException(msg);
+                    if (cooked.length < 7 || !cooked[1].equals("Address")) {
+                        throw new IllegalStateException(errorMessage);
                     }
 
                     int flags;
                     int scope;
+                    LinkAddress address;
                     try {
                         flags = Integer.parseInt(cooked[5]);
                         scope = Integer.parseInt(cooked[6]);
-                    } catch(NumberFormatException e) {
-                        throw new IllegalStateException(msg);
+                        address = new LinkAddress(cooked[3]);
+                    } catch(NumberFormatException e) {     // Non-numeric lifetime or scope.
+                        throw new IllegalStateException(errorMessage, e);
+                    } catch(IllegalArgumentException e) {  // Malformed IP address.
+                        throw new IllegalStateException(errorMessage, e);
                     }
 
                     if (cooked[2].equals("updated")) {
-                        notifyAddressUpdated(cooked[3], cooked[4], flags, scope);
+                        notifyAddressUpdated(address, cooked[4], flags, scope);
                     } else {
-                        notifyAddressRemoved(cooked[3], cooked[4], flags, scope);
+                        notifyAddressRemoved(address, cooked[4], flags, scope);
+                    }
+                    return true;
+                    // break;
+            case NetdResponseCode.InterfaceDnsServerInfo:
+                    /*
+                     * Information about available DNS servers has been received.
+                     * Format: "NNN DnsInfo servers <interface> <lifetime> <servers>"
+                     */
+                    long lifetime;  // Actually a 32-bit unsigned integer.
+
+                    if (cooked.length == 6 &&
+                        cooked[1].equals("DnsInfo") &&
+                        cooked[2].equals("servers")) {
+                        try {
+                            lifetime = Long.parseLong(cooked[4]);
+                        } catch (NumberFormatException e) {
+                            throw new IllegalStateException(errorMessage);
+                        }
+                        String[] servers = cooked[5].split(",");
+                        notifyInterfaceDnsServerInfo(cooked[3], lifetime, servers);
                     }
                     return true;
                     // break;
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index 16d2468..74633ae 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -26,11 +26,8 @@
 import android.net.nsd.INsdManager;
 import android.net.nsd.NsdManager;
 import android.os.Binder;
-import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.Message;
 import android.os.Messenger;
-import android.os.IBinder;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
@@ -39,20 +36,13 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.net.InetAddress;
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
-import com.android.server.am.BatteryStatsService;
-import com.android.server.NativeDaemonConnector.Command;
-import com.android.internal.R;
 
 /**
  * Network Service Discovery Service handles remote service discovery operation requests by
diff --git a/services/java/com/android/server/RandomBlock.java b/services/java/com/android/server/RandomBlock.java
index e5d7301..6d6d901 100644
--- a/services/java/com/android/server/RandomBlock.java
+++ b/services/java/com/android/server/RandomBlock.java
@@ -27,13 +27,13 @@
 import java.io.RandomAccessFile;
 
 /**
- * A 4k block of random {@code byte}s.
+ * A block of 512 random {@code byte}s.
  */
 class RandomBlock {
 
     private static final String TAG = "RandomBlock";
     private static final boolean DEBUG = false;
-    private static final int BLOCK_SIZE = 4096;
+    private static final int BLOCK_SIZE = 512;
     private byte[] block = new byte[BLOCK_SIZE];
 
     private RandomBlock() { }
diff --git a/services/java/com/android/server/ServiceWatcher.java b/services/java/com/android/server/ServiceWatcher.java
index 5c7bfab..9274295 100644
--- a/services/java/com/android/server/ServiceWatcher.java
+++ b/services/java/com/android/server/ServiceWatcher.java
@@ -37,7 +37,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 
diff --git a/services/java/com/android/server/ShutdownActivity.java b/services/java/com/android/server/ShutdownActivity.java
index be65141..56172ed0 100644
--- a/services/java/com/android/server/ShutdownActivity.java
+++ b/services/java/com/android/server/ShutdownActivity.java
@@ -20,14 +20,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.IPowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Slog;
 
-import com.android.server.power.ShutdownThread;
-
 public class ShutdownActivity extends Activity {
 
     private static final String TAG = "ShutdownActivity";
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 0964767..d4c436f 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -33,7 +33,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
diff --git a/services/java/com/android/server/UpdateLockService.java b/services/java/com/android/server/UpdateLockService.java
index 0f778cd..7f33973 100644
--- a/services/java/com/android/server/UpdateLockService.java
+++ b/services/java/com/android/server/UpdateLockService.java
@@ -24,7 +24,6 @@
 import android.os.IBinder;
 import android.os.IUpdateLock;
 import android.os.RemoteException;
-import android.os.SystemClock;
 import android.os.TokenWatcher;
 import android.os.UpdateLock;
 import android.os.UserHandle;
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index e17f42d..3e90078 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -22,14 +22,11 @@
 import com.android.server.am.ActivityManagerService;
 import com.android.server.power.PowerManagerService;
 
-import android.app.AlarmManager;
-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.os.BatteryManager;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.Looper;
@@ -45,7 +42,6 @@
 import java.io.FileWriter;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Calendar;
 
 /** This class calls its monitor every minute. Killing this process if they don't return **/
 public class Watchdog extends Thread {
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index ccac0d3..5e10d26 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -44,6 +44,7 @@
 import android.hardware.display.DisplayManager;
 import android.hardware.input.InputManager;
 import android.net.Uri;
+import android.opengl.Matrix;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -51,6 +52,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Parcel;
 import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -139,6 +141,51 @@
 
     private static final int MAX_POOL_SIZE = 10;
 
+    /** Matrix and offset used for converting color to grayscale. */
+    private static final float[] GRAYSCALE_MATRIX = new float[] {
+        .2126f, .2126f, .2126f, 0,
+        .7152f, .7152f, .7152f, 0,
+        .0722f, .0722f, .0722f, 0,
+             0,      0,      0, 1
+    };
+
+    /** Matrix and offset used for standard display inversion. */
+    private static final float[] INVERSION_MATRIX_STANDARD = new float[] {
+        -1,  0,  0, 0,
+         0, -1,  0, 0,
+         0,  0, -1, 0,
+         1,  1,  1, 1
+    };
+
+    /** Matrix and offset used for hue-only display inversion. */
+    private static final float[] INVERSION_MATRIX_HUE_ONLY = new float[] {
+          0, .5f, .5f, 0,
+        .5f,   0, .5f, 0,
+        .5f, .5f,   0, 0,
+          0,   0,   0, 1
+    };
+
+    /** Matrix and offset used for value-only display inversion. */
+    private static final float[] INVERSION_MATRIX_VALUE_ONLY = new float[] {
+           0, -.5f, -.5f, 0,
+        -.5f,    0, -.5f, 0,
+        -.5f, -.5f,    0, 0,
+           1,    1,    1, 1
+    };
+
+    /** Default contrast for display contrast enhancement. */
+    private static final float DEFAULT_DISPLAY_CONTRAST = 2;
+
+    /** Default brightness for display contrast enhancement. */
+    private static final float DEFAULT_DISPLAY_BRIGHTNESS = 0;
+
+    /** Default inversion mode for display color inversion. */
+    private static final int DEFAULT_DISPLAY_INVERSION = AccessibilityManager.INVERSION_STANDARD;
+
+    /** Default inversion mode for display color correction. */
+    private static final int DEFAULT_DISPLAY_DALTONIZER =
+            AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY;
+
     private static int sIdCounter = 0;
 
     private static int sNextWindowId;
@@ -1297,6 +1344,7 @@
         updateFilterKeyEventsLocked(userState);
         updateTouchExplorationLocked(userState);
         updateEnhancedWebAccessibilityLocked(userState);
+        updateDisplayColorAdjustmentSettingsLocked(userState);
         scheduleUpdateInputFilter(userState);
         scheduleUpdateClientsIfNeededLocked(userState);
     }
@@ -1355,6 +1403,7 @@
         somthingChanged |= readTouchExplorationEnabledSettingLocked(userState);
         somthingChanged |= readEnhancedWebAccessibilityEnabledChangedLocked(userState);
         somthingChanged |= readDisplayMagnificationEnabledSettingLocked(userState);
+        somthingChanged |= readDisplayColorAdjustmentSettingsLocked(userState);
         return somthingChanged;
     }
 
@@ -1403,6 +1452,124 @@
          return false;
     }
 
+    private boolean readDisplayColorAdjustmentSettingsLocked(UserState userState) {
+        final ContentResolver cr = mContext.getContentResolver();
+        final int userId = userState.mUserId;
+
+        boolean hasColorTransform = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, userId) == 1;
+
+        if (!hasColorTransform) {
+            hasColorTransform |= Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED, 0, userId) == 1;
+        }
+
+        if (!hasColorTransform) {
+            hasColorTransform |= Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, userId) == 1;
+        }
+
+        if (userState.mHasDisplayColorAdjustment != hasColorTransform) {
+            userState.mHasDisplayColorAdjustment = hasColorTransform;
+            return true;
+        }
+
+        // If adjustment is enabled, always assume there was a transform change.
+        return hasColorTransform;
+    }
+
+    private void updateDisplayColorAdjustmentSettingsLocked(UserState userState) {
+        final ContentResolver cr = mContext.getContentResolver();
+        final int userId = userState.mUserId;
+        float[] colorMatrix = new float[16];
+        float[] outputMatrix = new float[16];
+        boolean hasColorTransform = false;
+
+        Matrix.setIdentityM(colorMatrix, 0);
+
+        final boolean inversionEnabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, userId) == 1;
+        if (inversionEnabled) {
+            final int inversionMode = Settings.Secure.getIntForUser(cr,
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION, DEFAULT_DISPLAY_INVERSION,
+                    userId);
+            final float[] inversionMatrix;
+            switch (inversionMode) {
+                case AccessibilityManager.INVERSION_HUE_ONLY:
+                    inversionMatrix = INVERSION_MATRIX_HUE_ONLY;
+                    break;
+                case AccessibilityManager.INVERSION_VALUE_ONLY:
+                    inversionMatrix = INVERSION_MATRIX_VALUE_ONLY;
+                    break;
+                default:
+                    inversionMatrix = INVERSION_MATRIX_STANDARD;
+            }
+
+            Matrix.multiplyMM(outputMatrix, 0, colorMatrix, 0, inversionMatrix, 0);
+
+            final float[] temp = colorMatrix;
+            colorMatrix = outputMatrix;
+            outputMatrix = colorMatrix;
+
+            hasColorTransform = true;
+        }
+
+        final boolean contrastEnabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED, 0, userId) == 1;
+        if (contrastEnabled) {
+            final float contrast = Settings.Secure.getFloatForUser(cr,
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST, DEFAULT_DISPLAY_CONTRAST,
+                    userId);
+            final float brightness = Settings.Secure.getFloatForUser(cr,
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY_BRIGHTNESS,
+                    userId);
+            final float off = brightness * contrast - 0.5f * contrast + 0.5f;
+            final float[] contrastMatrix = {
+                    contrast, 0, 0, 0,
+                    0, contrast, 0, 0,
+                    0, 0, contrast, 0,
+                    off, off, off, 1
+            };
+
+            Matrix.multiplyMM(outputMatrix, 0, colorMatrix, 0, contrastMatrix, 0);
+
+            final float[] temp = colorMatrix;
+            colorMatrix = outputMatrix;
+            outputMatrix = colorMatrix;
+
+            hasColorTransform = true;
+        }
+
+        final boolean daltonizerEnabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, userId) != 0;
+        if (daltonizerEnabled) {
+            final int daltonizerMode = Settings.Secure.getIntForUser(cr,
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, DEFAULT_DISPLAY_DALTONIZER,
+                    userId);
+            // Monochromacy isn't supported by the native Daltonizer.
+            if (daltonizerMode == AccessibilityManager.DALTONIZER_SIMULATE_MONOCHROMACY) {
+                Matrix.multiplyMM(outputMatrix, 0, colorMatrix, 0, GRAYSCALE_MATRIX, 0);
+
+                final float[] temp = colorMatrix;
+                colorMatrix = outputMatrix;
+                outputMatrix = temp;
+
+                hasColorTransform = true;
+                nativeSetDaltonizerMode(AccessibilityManager.DALTONIZER_DISABLED);
+            } else {
+                nativeSetDaltonizerMode(daltonizerMode);
+            }
+        } else {
+            nativeSetDaltonizerMode(AccessibilityManager.DALTONIZER_DISABLED);
+        }
+
+        if (hasColorTransform) {
+            nativeSetColorTransform(colorMatrix);
+        } else {
+            nativeSetColorTransform(null);
+        }
+    }
+
     private void updateTouchExplorationLocked(UserState userState) {
         boolean enabled = false;
         final int serviceCount = userState.mBoundServices.size();
@@ -1529,6 +1696,56 @@
         }
     }
 
+    /**
+     * Sets the surface flinger's Daltonization mode. This adjusts the color
+     * space to correct for or simulate various types of color blindness.
+     *
+     * @param mode new Daltonization mode
+     */
+    private static void nativeSetDaltonizerMode(int mode) {
+        try {
+            final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
+            if (flinger != null) {
+                final Parcel data = Parcel.obtain();
+                data.writeInterfaceToken("android.ui.ISurfaceComposer");
+                data.writeInt(mode);
+                flinger.transact(1014, data, null, 0);
+                data.recycle();
+            }
+        } catch (RemoteException ex) {
+            Slog.e(LOG_TAG, "Failed to set Daltonizer mode", ex);
+        }
+    }
+
+    /**
+     * Sets the surface flinger's color transformation as a 4x4 matrix. If the
+     * matrix is null, color transformations are disabled.
+     *
+     * @param m the float array that holds the transformation matrix, or null to
+     *            disable transformation
+     */
+    private static void nativeSetColorTransform(float[] m) {
+        try {
+            final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
+            if (flinger != null) {
+                final Parcel data = Parcel.obtain();
+                data.writeInterfaceToken("android.ui.ISurfaceComposer");
+                if (m != null) {
+                    data.writeInt(1);
+                    for (int i = 0; i < 16; i++) {
+                        data.writeFloat(m[i]);
+                    }
+                } else {
+                    data.writeInt(0);
+                }
+                flinger.transact(1015, data, null, 0);
+                data.recycle();
+            }
+        } catch (RemoteException ex) {
+            Slog.e(LOG_TAG, "Failed to set color transform", ex);
+        }
+    }
+
     private class AccessibilityConnectionWrapper implements DeathRecipient {
         private final int mWindowId;
         private final int mUserId;
@@ -2952,6 +3169,7 @@
         public boolean mIsEnhancedWebAccessibilityEnabled;
         public boolean mIsDisplayMagnificationEnabled;
         public boolean mIsFilterKeyEventsEnabled;
+        public boolean mHasDisplayColorAdjustment;
 
         private Service mUiAutomationService;
         private IAccessibilityServiceClient mUiAutomationServiceClient;
@@ -3043,6 +3261,23 @@
         private final Uri mEnhancedWebAccessibilityUri = Settings.Secure
                 .getUriFor(Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION);
 
+        private final Uri mDisplayContrastEnabledUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED);
+        private final Uri mDisplayContrastUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST);
+        private final Uri mDisplayBrightnessUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS);
+
+        private final Uri mDisplayInversionEnabledUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
+        private final Uri mDisplayInversionUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION);
+
+        private final Uri mDisplayDaltonizerEnabledUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED);
+        private final Uri mDisplayDaltonizerUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER);
+
         public AccessibilityContentObserver(Handler handler) {
             super(handler);
         }
@@ -3061,6 +3296,20 @@
                     false, this, UserHandle.USER_ALL);
             contentResolver.registerContentObserver(mEnhancedWebAccessibilityUri,
                     false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayContrastEnabledUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayContrastUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayBrightnessUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayInversionEnabledUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayInversionUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayDaltonizerEnabledUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayDaltonizerUri, false, this, UserHandle.USER_ALL);
         }
 
         @Override
@@ -3125,6 +3374,22 @@
                         }
                     }
                 }
+            } else if (mDisplayContrastEnabledUri.equals(uri)
+                    || mDisplayInversionEnabledUri.equals(uri)
+                    || mDisplayDaltonizerEnabledUri.equals(uri)
+                    || mDisplayContrastUri.equals(uri)
+                    || mDisplayBrightnessUri.equals(uri)
+                    || mDisplayInversionUri.equals(uri)
+                    || mDisplayDaltonizerUri.equals(uri)) {
+                synchronized (mLock) {
+                    // We will update when the automation service dies.
+                    UserState userState = getCurrentUserStateLocked();
+                    if (userState.mUiAutomationService == null) {
+                        if (readDisplayColorAdjustmentSettingsLocked(userState)) {
+                            updateDisplayColorAdjustmentSettingsLocked(userState);
+                        }
+                    }
+                }
             }
         }
     }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index ea601433..3266ca7 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -29,9 +29,7 @@
 
 import android.app.AppOpsManager;
 import android.appwidget.AppWidgetManager;
-import android.graphics.Rect;
 import android.util.ArrayMap;
-import android.view.Display;
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IAppOpsService;
@@ -54,6 +52,7 @@
 import com.android.server.firewall.IntentFirewall;
 import com.android.server.pm.UserManagerService;
 import com.android.server.wm.AppTransition;
+import com.android.server.wm.StackBox;
 import com.android.server.wm.WindowManagerService;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
@@ -69,6 +68,7 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityManager.StackBoxInfo;
 import android.app.ActivityManager.StackInfo;
 import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
@@ -1326,7 +1326,7 @@
                     String pkg = bundle.getString("pkg");
                     String reason = bundle.getString("reason");
                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
-                            UserHandle.USER_ALL, reason);
+                            false, UserHandle.USER_ALL, reason);
                 }
             } break;
             case FINALIZE_PENDING_INTENT_MSG: {
@@ -1770,7 +1770,7 @@
     public void setWindowManager(WindowManagerService wm) {
         mWindowManager = wm;
         mStackSupervisor.setWindowManager(wm);
-        wm.createStack(HOME_STACK_ID, Display.DEFAULT_DISPLAY);
+        wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f);
     }
 
     public void startObservingNativeCrashes() {
@@ -3592,9 +3592,13 @@
      */
     private final void handleAppDiedLocked(ProcessRecord app,
             boolean restarting, boolean allowRestart) {
+        int pid = app.pid;
         cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
         if (!restarting) {
             removeLruProcessLocked(app);
+            if (pid > 0) {
+                ProcessList.remove(pid);
+            }
         }
 
         if (mProfileProc == app) {
@@ -4164,9 +4168,9 @@
                         == PackageManager.PERMISSION_GRANTED) {
                     forceStopPackageLocked(packageName, pkgUid, "clear data");
                 } else {
-                    throw new SecurityException(pid+" does not have permission:"+
-                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
-                                    "for process:"+packageName);
+                    throw new SecurityException("PID " + pid + " does not have permission "
+                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
+                                    + " of package " + packageName);
                 }
             }
 
@@ -4483,7 +4487,7 @@
 
     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
-                false, true, false, UserHandle.getUserId(uid), reason);
+                false, true, false, false, UserHandle.getUserId(uid), reason);
         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
                 Uri.fromParts("package", packageName, null));
         if (!mProcessesReady) {
@@ -4499,7 +4503,7 @@
     }
 
     private void forceStopUserLocked(int userId, String reason) {
-        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
+        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                 | Intent.FLAG_RECEIVER_FOREGROUND);
@@ -4584,7 +4588,7 @@
 
     private final boolean forceStopPackageLocked(String name, int appId,
             boolean callerWillRestart, boolean purgeCache, boolean doit,
-            boolean evenPersistent, int userId, String reason) {
+            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
         int i;
         int N;
 
@@ -4676,7 +4680,7 @@
         // Remove transient permissions granted from/to this package/user
         removeUriPermissionsForPackageLocked(name, userId, false);
 
-        if (name == null) {
+        if (name == null || uninstalling) {
             // Remove pending intents.  For now we only do this when force
             // stopping users, because we have some problems when doing this
             // for packages -- app widgets are not currently cleaned up for
@@ -5121,7 +5125,7 @@
                 if (pkgs != null) {
                     for (String pkg : pkgs) {
                         synchronized (ActivityManagerService.this) {
-                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
+                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
                                     "finished booting")) {
                                 setResultCode(Activity.RESULT_OK);
                                 return;
@@ -7096,15 +7100,16 @@
     }
 
     @Override
-    public int createStack(int taskId) {
+    public int createStack(int taskId, int relativeStackBoxId, int position, float weight) {
         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
                 "createStack()");
-        if (DEBUG_STACK) Slog.d(TAG, "createStack: taskId=" + taskId);
+        if (DEBUG_STACK) Slog.d(TAG, "createStack: taskId=" + taskId + " relStackBoxId=" +
+                relativeStackBoxId + " position=" + position + " weight=" + weight);
         synchronized (this) {
             long ident = Binder.clearCallingIdentity();
             try {
                 int stackId = mStackSupervisor.createStack();
-                mWindowManager.createStack(stackId, Display.DEFAULT_DISPLAY);
+                mWindowManager.createStack(stackId, relativeStackBoxId, position, weight);
                 if (taskId > 0) {
                     moveTaskToStack(taskId, stackId, true);
                 }
@@ -7136,40 +7141,99 @@
     }
 
     @Override
-    public void resizeStack(int stackBoxId, Rect bounds) {
+    public void resizeStackBox(int stackBoxId, float weight) {
         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
                 "resizeStackBox()");
         long ident = Binder.clearCallingIdentity();
         try {
-            mWindowManager.resizeStack(stackBoxId, bounds);
+            mWindowManager.resizeStackBox(stackBoxId, weight);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
     }
 
+    private ArrayList<StackInfo> getStacks() {
+        synchronized (this) {
+            ArrayList<ActivityManager.StackInfo> list = new ArrayList<ActivityManager.StackInfo>();
+            ArrayList<ActivityStack> stacks = mStackSupervisor.getStacks();
+            for (ActivityStack stack : stacks) {
+                ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo();
+                int stackId = stack.mStackId;
+                stackInfo.stackId = stackId;
+                stackInfo.bounds = mWindowManager.getStackBounds(stackId);
+                ArrayList<TaskRecord> tasks = stack.getAllTasks();
+                final int numTasks = tasks.size();
+                int[] taskIds = new int[numTasks];
+                String[] taskNames = new String[numTasks];
+                for (int i = 0; i < numTasks; ++i) {
+                    final TaskRecord task = tasks.get(i);
+                    taskIds[i] = task.taskId;
+                    taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
+                            : task.realActivity != null ? task.realActivity.flattenToString()
+                            : task.getTopActivity() != null ? task.getTopActivity().packageName
+                            : "unknown";
+                }
+                stackInfo.taskIds = taskIds;
+                stackInfo.taskNames = taskNames;
+                list.add(stackInfo);
+            }
+            return list;
+        }
+    }
+
+    private void addStackInfoToStackBoxInfo(StackBoxInfo stackBoxInfo, List<StackInfo> stackInfos) {
+        final int stackId = stackBoxInfo.stackId;
+        if (stackId >= 0) {
+            for (StackInfo stackInfo : stackInfos) {
+                if (stackId == stackInfo.stackId) {
+                    stackBoxInfo.stack = stackInfo;
+                    stackInfos.remove(stackInfo);
+                    return;
+                }
+            }
+        } else {
+            addStackInfoToStackBoxInfo(stackBoxInfo.children[0], stackInfos);
+            addStackInfoToStackBoxInfo(stackBoxInfo.children[1], stackInfos);
+        }
+    }
+
     @Override
-    public List<StackInfo> getAllStackInfos() {
+    public List<StackBoxInfo> getStackBoxes() {
         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
                 "getStackBoxes()");
         long ident = Binder.clearCallingIdentity();
         try {
+            List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
             synchronized (this) {
-                return mStackSupervisor.getAllStackInfos();
+                List<StackInfo> stackInfos = getStacks();
+                for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
+                    addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
+                }
             }
+            return stackBoxInfos;
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
     }
 
     @Override
-    public StackInfo getStackInfo(int stackId) {
+    public StackBoxInfo getStackBoxInfo(int stackBoxId) {
         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
-                "getStackInfo()");
+                "getStackBoxInfo()");
         long ident = Binder.clearCallingIdentity();
         try {
+            List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
+            StackBoxInfo info = null;
             synchronized (this) {
-                return mStackSupervisor.getStackInfo(stackId);
+                List<StackInfo> stackInfos = getStacks();
+                for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
+                    addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
+                    if (stackBoxInfo.stackBoxId == stackBoxId) {
+                        info = stackBoxInfo;
+                    }
+                }
             }
+            return info;
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
@@ -8374,7 +8438,7 @@
                 mDebugTransient = !persistent;
                 if (packageName != null) {
                     forceStopPackageLocked(packageName, -1, false, false, true, true,
-                            UserHandle.USER_ALL, "set debug app");
+                            false, UserHandle.USER_ALL, "set debug app");
                 }
             }
         } finally {
@@ -12313,6 +12377,7 @@
             boolean restarting, boolean allowRestart, int index) {
         if (index >= 0) {
             removeLruProcessLocked(app);
+            ProcessList.remove(app.pid);
         }
 
         mProcessesToGc.remove(app);
@@ -13298,7 +13363,7 @@
                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                         if (list != null && (list.length > 0)) {
                             for (String pkg : list) {
-                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
+                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
                                         "storage unmount");
                             }
                             sendPackageBroadcastLocked(
@@ -13310,10 +13375,13 @@
                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
                             boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
                                     intent.getAction());
+                            boolean fullUninstall = removed &&
+                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
                                 forceStopPackageLocked(ssp, UserHandle.getAppId(
                                         intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
-                                        false, userId, removed ? "pkg removed" : "pkg changed");
+                                        false, fullUninstall, userId,
+                                        removed ? "pkg removed" : "pkg changed");
                             }
                             if (removed) {
                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
@@ -13791,7 +13859,7 @@
 
             final long origId = Binder.clearCallingIdentity();
             // Instrumentation can kill and relaunch even persistent processes
-            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
+            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
                     "start instr");
             ProcessRecord app = addAppLocked(ai, false);
             app.instrumentationClass = className;
@@ -13859,7 +13927,7 @@
         app.instrumentationProfileFile = null;
         app.instrumentationArguments = null;
 
-        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
+        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
                 "finished inst");
     }
 
@@ -15172,16 +15240,13 @@
         }
 
         if (app.curAdj != app.setAdj) {
-            if (Process.setOomAdj(app.pid, app.curAdj)) {
-                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
-                    TAG, "Set " + app.pid + " " + app.processName +
-                    " adj " + app.curAdj + ": " + app.adjType);
-                app.setAdj = app.curAdj;
-            } else {
-                success = false;
-                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
-            }
+            ProcessList.setOomAdj(app.pid, app.curAdj);
+            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
+                TAG, "Set " + app.pid + " " + app.processName +
+                " adj " + app.curAdj + ": " + app.adjType);
+            app.setAdj = app.curAdj;
         }
+
         if (app.setSchedGroup != app.curSchedGroup) {
             app.setSchedGroup = app.curSchedGroup;
             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 49f29fe..8e85914 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -143,6 +143,7 @@
 
     private boolean inHistory;  // are we in the history stack?
     final ActivityStackSupervisor mStackSupervisor;
+    boolean mStartingWindowShown = false;
 
     void dump(PrintWriter pw, String prefix) {
         final long now = SystemClock.uptimeMillis();
@@ -722,6 +723,10 @@
         }
     }
 
+    ActivityOptions getOptionsForTargetActivityLocked() {
+        return pendingOptions != null ? pendingOptions.forTargetActivity() : null;
+    }
+
     void clearOptionsLocked() {
         if (pendingOptions != null) {
             pendingOptions.abort();
diff --git a/services/java/com/android/server/am/ActivityResult.java b/services/java/com/android/server/am/ActivityResult.java
index 6d5bdeb..395918e 100644
--- a/services/java/com/android/server/am/ActivityResult.java
+++ b/services/java/com/android/server/am/ActivityResult.java
@@ -18,7 +18,6 @@
 
 import android.app.ResultInfo;
 import android.content.Intent;
-import android.os.Bundle;
 
 /**
  * Pending result information to send back to an activity.
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 0e152611..2e914aa 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -36,6 +36,8 @@
 import static com.android.server.am.ActivityStackSupervisor.DEBUG_STATES;
 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
 
+import android.os.Trace;
+import android.util.Log;
 import com.android.internal.os.BatteryStatsImpl;
 import com.android.internal.util.Objects;
 import com.android.server.Watchdog;
@@ -121,8 +123,7 @@
     // convertToTranslucent().
     static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000;
 
-    static final boolean SCREENSHOT_FORCE_565 = ActivityManager
-            .isLowRamDeviceStatic() ? true : false;
+    static final boolean SCREENSHOT_FORCE_565 = ActivityManager.isLowRamDeviceStatic();
 
     enum ActivityState {
         INITIALIZING,
@@ -398,8 +399,9 @@
         // be simplified once we stop storing tasks with empty mActivities lists.
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
-            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
-                return activities.get(activityNdx);
+            final int topActivityNdx = activities.size() - 1;
+            if (topActivityNdx >= 0) {
+                return activities.get(topActivityNdx);
             }
         }
         return null;
@@ -436,25 +438,6 @@
         return null;
     }
 
-    boolean containsApp(ProcessRecord app) {
-        if (app == null) {
-            return false;
-        }
-        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
-            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
-            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
-                final ActivityRecord r = activities.get(activityNdx);
-                if (r.finishing) {
-                    continue;
-                }
-                if (r.app == app) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     final boolean updateLRUListLocked(ActivityRecord r) {
         final boolean hadit = mLRUActivities.remove(r);
         mLRUActivities.add(r);
@@ -1097,7 +1080,7 @@
                                 mWindowManager.setAppVisibility(r.appToken, true);
                             }
                             if (r != starting) {
-                                mStackSupervisor.startSpecificActivityLocked(r, false, false);
+                                mStackSupervisor.startSpecificActivityLocked(r, false, false, null);
                             }
                         }
 
@@ -1234,6 +1217,32 @@
         }
     }
 
+    /** If any activities below the top running one are in the INITIALIZING state and they have a
+     * starting window displayed then remove that starting window. It is possible that the activity
+     * in this state will never resumed in which case that starting window will be orphaned. */
+    void cancelInitializingActivities() {
+        final ActivityRecord topActivity = topRunningActivityLocked(null);
+        boolean aboveTop = true;
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if (aboveTop) {
+                    if (r == topActivity) {
+                        aboveTop = false;
+                    }
+                    continue;
+                }
+
+                if (r.state == ActivityState.INITIALIZING && r.mStartingWindowShown) {
+                    if (DEBUG_VISBILITY) Slog.w(TAG, "Found orphaned starting window " + r);
+                    r.mStartingWindowShown = false;
+                    mWindowManager.removeAppStartingWindow(r.appToken);
+                }
+            }
+        }
+    }
+
     /**
      * Ensure that the top activity in the stack is resumed.
      *
@@ -1250,6 +1259,8 @@
     final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
         if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
 
+        cancelInitializingActivities();
+
         // Find the first activity that is not finishing.
         ActivityRecord next = topRunningActivityLocked(null);
 
@@ -1502,7 +1513,13 @@
                 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN, false);
             }
         }
+
+        Bundle resumeAnimOptions = null;
         if (anim) {
+            ActivityOptions opts = next.getOptionsForTargetActivityLocked();
+            if (opts != null) {
+                resumeAnimOptions = opts.toBundle();
+            }
             next.applyOptionsLocked();
         } else {
             next.clearOptionsLocked();
@@ -1595,7 +1612,7 @@
                 next.app.pendingUiClean = true;
                 next.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
                 next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
-                        mService.isNextTransitionForward());
+                        mService.isNextTransitionForward(), resumeAnimOptions);
 
                 mStackSupervisor.checkReadyForSleepLocked();
 
@@ -1619,7 +1636,7 @@
                             next.nonLocalizedLabel, next.labelRes, next.icon, next.logo,
                             next.windowFlags, null, true);
                 }
-                mStackSupervisor.startSpecificActivityLocked(next, true, false);
+                mStackSupervisor.startSpecificActivityLocked(next, true, false, resumeAnimOptions);
                 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                 return true;
             }
@@ -1657,7 +1674,7 @@
                 if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next);
             }
             if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Restarting " + next);
-            mStackSupervisor.startSpecificActivityLocked(next, true, true);
+            mStackSupervisor.startSpecificActivityLocked(next, true, true, resumeAnimOptions);
         }
 
         if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
@@ -1816,6 +1833,7 @@
                                 r.info.applicationInfo), r.nonLocalizedLabel,
                         r.labelRes, r.icon, r.logo, r.windowFlags,
                         prev != null ? prev.appToken : null, showStartingIcon);
+                r.mStartingWindowShown = true;
             }
         } else {
             // If this is the first activity, don't do any fancy animations,
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 4a46288..04617af 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -34,7 +34,6 @@
 
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.ActivityManager.StackInfo;
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
@@ -71,11 +70,11 @@
 import android.util.Slog;
 import android.util.SparseIntArray;
 
-import android.view.Display;
 import com.android.internal.app.HeavyWeightSwitcherActivity;
 import com.android.internal.os.TransferPipe;
 import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
 import com.android.server.am.ActivityStack.ActivityState;
+import com.android.server.wm.StackBox;
 import com.android.server.wm.WindowManagerService;
 
 import java.io.FileDescriptor;
@@ -380,7 +379,7 @@
                 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                         && processName.equals(hr.processName)) {
                     try {
-                        if (realStartActivityLocked(hr, app, true, true)) {
+                        if (realStartActivityLocked(hr, app, true, true, null)) {
                             didSomething = true;
                         }
                     } catch (Exception e) {
@@ -869,7 +868,7 @@
     }
 
     final boolean realStartActivityLocked(ActivityRecord r,
-            ProcessRecord app, boolean andResume, boolean checkConfig)
+            ProcessRecord app, boolean andResume, boolean checkConfig, Bundle resumeArgs)
             throws RemoteException {
 
         r.startFreezingScreenLocked(app, 0);
@@ -961,13 +960,14 @@
                     }
                 }
             }
+
             app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
             app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                     System.identityHashCode(r), r.info,
                     new Configuration(mService.mConfiguration), r.compat,
                     app.repProcState, r.icicle, results, newIntents, !andResume,
                     mService.isNextTransitionForward(), profileFile, profileFd,
-                    profileAutoStop);
+                    profileAutoStop, resumeArgs);
 
             if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
                 // This may be a heavy-weight process!  Note that the package
@@ -1041,7 +1041,7 @@
     }
 
     void startSpecificActivityLocked(ActivityRecord r,
-            boolean andResume, boolean checkConfig) {
+            boolean andResume, boolean checkConfig, Bundle resumeArgs) {
         // Is this activity's application already running?
         ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                 r.info.applicationInfo.uid, true);
@@ -1058,7 +1058,7 @@
                     // separate apk in the process.
                     app.addPackage(r.info.packageName, mService.mProcessStats);
                 }
-                realStartActivityLocked(r, app, andResume, checkConfig);
+                realStartActivityLocked(r, app, andResume, checkConfig, resumeArgs);
                 return;
             } catch (RemoteException e) {
                 Slog.w(TAG, "Exception when starting activity "
@@ -1289,7 +1289,8 @@
             }
 
             // Time to create the first app stack for this user.
-            int stackId = mService.createStack(-1);
+            int stackId =
+                    mService.createStack(-1, HOME_STACK_ID, StackBox.TASK_STACK_GOES_OVER, 1.0f);
             if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
                     " stackId=" + stackId);
             mFocusedStack = getStack(stackId);
@@ -2644,43 +2645,4 @@
             }
         }
     }
-
-    StackInfo getStackInfo(ActivityStack stack) {
-        StackInfo info = new StackInfo();
-        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
-        info.displayId = Display.DEFAULT_DISPLAY;
-        info.stackId = stack.mStackId;
-
-        ArrayList<TaskRecord> tasks = stack.getAllTasks();
-        final int numTasks = tasks.size();
-        int[] taskIds = new int[numTasks];
-        String[] taskNames = new String[numTasks];
-        for (int i = 0; i < numTasks; ++i) {
-            final TaskRecord task = tasks.get(i);
-            taskIds[i] = task.taskId;
-            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
-                    : task.realActivity != null ? task.realActivity.flattenToString()
-                    : task.getTopActivity() != null ? task.getTopActivity().packageName
-                    : "unknown";
-        }
-        info.taskIds = taskIds;
-        info.taskNames = taskNames;
-        return info;
-    }
-
-    StackInfo getStackInfo(int stackId) {
-        ActivityStack stack = getStack(stackId);
-        if (stack != null) {
-            return getStackInfo(stack);
-        }
-        return null;
-    }
-
-    ArrayList<StackInfo> getAllStackInfos() {
-        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
-        for (int ndx = mStacks.size() - 1; ndx >= 0; --ndx) {
-            list.add(getStackInfo(mStacks.get(ndx)));
-        }
-        return list;
-    }
 }
diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java
index bfb667f..d0dd75d 100644
--- a/services/java/com/android/server/am/BroadcastQueue.java
+++ b/services/java/com/android/server/am/BroadcastQueue.java
@@ -27,7 +27,6 @@
 import android.content.IIntentReceiver;
 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.os.Bundle;
diff --git a/services/java/com/android/server/am/ContentProviderRecord.java b/services/java/com/android/server/am/ContentProviderRecord.java
index 646b7d2..ff22764 100644
--- a/services/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/java/com/android/server/am/ContentProviderRecord.java
@@ -31,7 +31,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 
 final class ContentProviderRecord {
     final ActivityManagerService service;
diff --git a/services/java/com/android/server/am/IntentBindRecord.java b/services/java/com/android/server/am/IntentBindRecord.java
index 21cf266..ba6010a 100644
--- a/services/java/com/android/server/am/IntentBindRecord.java
+++ b/services/java/com/android/server/am/IntentBindRecord.java
@@ -22,8 +22,6 @@
 import android.util.ArrayMap;
 
 import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.Iterator;
 
 /**
  * A particular Intent that has been bound to a Service.
diff --git a/services/java/com/android/server/am/ProcessList.java b/services/java/com/android/server/am/ProcessList.java
index d3777c7..755a23722 100644
--- a/services/java/com/android/server/am/ProcessList.java
+++ b/services/java/com/android/server/am/ProcessList.java
@@ -16,8 +16,9 @@
 
 package com.android.server.am;
 
-import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
 
 import android.app.ActivityManager;
 import com.android.internal.util.MemInfoReader;
@@ -26,6 +27,8 @@
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.os.SystemProperties;
+import android.net.LocalSocketAddress;
+import android.net.LocalSocket;
 import android.util.Slog;
 import android.view.Display;
 
@@ -141,6 +144,16 @@
     // Threshold of number of cached+empty where we consider memory critical.
     static final int TRIM_LOW_THRESHOLD = 5;
 
+    // Low Memory Killer Daemon command codes.
+    // These must be kept in sync with the definitions in lmkd.c
+    //
+    // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
+    // LMK_PROCPRIO <pid> <prio>
+    // LMK_PROCREMOVE <pid>
+    static final byte LMK_TARGET = 0;
+    static final byte LMK_PROCPRIO = 1;
+    static final byte LMK_PROCREMOVE = 2;
+
     // These are the various interesting memory levels that we will give to
     // the OOM killer.  Note that the OOM killer only supports 6 slots, so we
     // can't give it a different value for every possible kind of process.
@@ -150,18 +163,18 @@
     };
     // These are the low-end OOM level limits.  This is appropriate for an
     // HVGA or smaller phone with less than 512MB.  Values are in KB.
-    private final long[] mOomMinFreeLow = new long[] {
+    private final int[] mOomMinFreeLow = new int[] {
             8192, 12288, 16384,
             24576, 28672, 32768
     };
     // These are the high-end OOM level limits.  This is appropriate for a
     // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.
-    private final long[] mOomMinFreeHigh = new long[] {
+    private final int[] mOomMinFreeHigh = new int[] {
             49152, 61440, 73728,
             86016, 98304, 122880
     };
     // The actual OOM killer memory levels we are using.
-    private final long[] mOomMinFree = new long[mOomAdj.length];
+    private final int[] mOomMinFree = new int[mOomAdj.length];
 
     private final long mTotalMemMb;
 
@@ -169,6 +182,9 @@
 
     private boolean mHaveDisplaySize;
 
+    private static LocalSocket sLmkdSocket;
+    private static OutputStream sLmkdOutputStream;
+
     ProcessList() {
         MemInfoReader minfo = new MemInfoReader();
         minfo.readMemInfo();
@@ -202,9 +218,6 @@
                     + " dh=" + displayHeight);
         }
 
-        StringBuilder adjString = new StringBuilder();
-        StringBuilder memString = new StringBuilder();
-
         float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
         if (scale < 0) scale = 0;
         else if (scale > 1) scale = 1;
@@ -217,20 +230,20 @@
         }
 
         for (int i=0; i<mOomAdj.length; i++) {
-            long low = mOomMinFreeLow[i];
-            long high = mOomMinFreeHigh[i];
-            mOomMinFree[i] = (long)(low + ((high-low)*scale));
+            int low = mOomMinFreeLow[i];
+            int high = mOomMinFreeHigh[i];
+            mOomMinFree[i] = (int)(low + ((high-low)*scale));
         }
 
         if (minfree_abs >= 0) {
             for (int i=0; i<mOomAdj.length; i++) {
-                mOomMinFree[i] = (long)((float)minfree_abs * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]);
+                mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]);
             }
         }
 
         if (minfree_adj != 0) {
             for (int i=0; i<mOomAdj.length; i++) {
-                mOomMinFree[i] += (long)((float)minfree_adj * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]);
+                mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]);
                 if (mOomMinFree[i] < 0) {
                     mOomMinFree[i] = 0;
                 }
@@ -242,15 +255,6 @@
         // before killing background processes.
         mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024) / 3;
 
-        for (int i=0; i<mOomAdj.length; i++) {
-            if (i > 0) {
-                adjString.append(',');
-                memString.append(',');
-            }
-            adjString.append(mOomAdj[i]);
-            memString.append((mOomMinFree[i]*1024)/PAGE_SIZE);
-        }
-
         // Ask the kernel to try to keep enough memory free to allocate 3 full
         // screen 32bpp buffers without entering direct reclaim.
         int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
@@ -268,10 +272,15 @@
             }
         }
 
-        //Slog.i("XXXXXXX", "******************************* MINFREE: " + memString);
         if (write) {
-            writeFile("/sys/module/lowmemorykiller/parameters/adj", adjString.toString());
-            writeFile("/sys/module/lowmemorykiller/parameters/minfree", memString.toString());
+            ByteBuffer buf = ByteBuffer.allocate(4 * (2*mOomAdj.length + 1));
+            buf.putInt(LMK_TARGET);
+            for (int i=0; i<mOomAdj.length; i++) {
+                buf.putInt((mOomMinFree[i]*1024)/PAGE_SIZE);
+                buf.putInt(mOomAdj[i]);
+            }
+
+            writeLmkd(buf);
             SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
         }
         // GB: 2048,3072,4096,6144,7168,8192
@@ -506,19 +515,78 @@
         return mCachedRestoreLevel;
     }
 
-    private void writeFile(String path, String data) {
-        FileOutputStream fos = null;
+    /**
+     * Set the out-of-memory badness adjustment for a process.
+     *
+     * @param pid The process identifier to set.
+     * @param amt Adjustment value -- lmkd allows -16 to +15.
+     *
+     * {@hide}
+     */
+    public static final void setOomAdj(int pid, int amt) {
+        if (amt == UNKNOWN_ADJ)
+            return;
+
+        ByteBuffer buf = ByteBuffer.allocate(4 * 3);
+        buf.putInt(LMK_PROCPRIO);
+        buf.putInt(pid);
+        buf.putInt(amt);
+        writeLmkd(buf);
+    }
+
+    /*
+     * {@hide}
+     */
+    public static final void remove(int pid) {
+        ByteBuffer buf = ByteBuffer.allocate(4 * 2);
+        buf.putInt(LMK_PROCREMOVE);
+        buf.putInt(pid);
+        writeLmkd(buf);
+    }
+
+    private static boolean openLmkdSocket() {
         try {
-            fos = new FileOutputStream(path);
-            fos.write(data.getBytes());
-        } catch (IOException e) {
-            Slog.w(ActivityManagerService.TAG, "Unable to write " + path);
-        } finally {
-            if (fos != null) {
+            sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
+            sLmkdSocket.connect(
+                new LocalSocketAddress("lmkd",
+                        LocalSocketAddress.Namespace.RESERVED));
+            sLmkdOutputStream = sLmkdSocket.getOutputStream();
+        } catch (IOException ex) {
+            Slog.w(ActivityManagerService.TAG,
+                   "lowmemorykiller daemon socket open failed");
+            sLmkdSocket = null;
+            return false;
+        }
+
+        return true;
+    }
+
+    private static void writeLmkd(ByteBuffer buf) {
+
+        for (int i = 0; i < 3; i++) {
+            if (sLmkdSocket == null) {
+                    if (openLmkdSocket() == false) {
+                        try {
+                            Thread.sleep(1000);
+                        } catch (InterruptedException ie) {
+                        }
+                        continue;
+                    }
+            }
+
+            try {
+                sLmkdOutputStream.write(buf.array(), 0, buf.position());
+                return;
+            } catch (IOException ex) {
+                Slog.w(ActivityManagerService.TAG,
+                       "Error writing to lowmemorykiller socket");
+
                 try {
-                    fos.close();
-                } catch (IOException e) {
+                    sLmkdSocket.close();
+                } catch (IOException ex2) {
                 }
+
+                sLmkdSocket = null;
             }
         }
     }
diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java
index e05fcda..4a45aac 100644
--- a/services/java/com/android/server/am/ProcessStatsService.java
+++ b/services/java/com/android/server/am/ProcessStatsService.java
@@ -16,8 +16,6 @@
 
 package com.android.server.am;
 
-import android.app.AppGlobals;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.Parcel;
@@ -25,7 +23,6 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
-import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.AtomicFile;
 import android.util.Slog;
diff --git a/services/java/com/android/server/am/ReceiverList.java b/services/java/com/android/server/am/ReceiverList.java
index fa8c1df..6ade736 100644
--- a/services/java/com/android/server/am/ReceiverList.java
+++ b/services/java/com/android/server/am/ReceiverList.java
@@ -17,11 +17,8 @@
 package com.android.server.am;
 
 import android.content.IIntentReceiver;
-import android.content.Intent;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.IBinder;
-import android.os.RemoteException;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
 
diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/java/com/android/server/am/UsageStatsService.java
index e96d8b1..2260c7f 100644
--- a/services/java/com/android/server/am/UsageStatsService.java
+++ b/services/java/com/android/server/am/UsageStatsService.java
@@ -20,7 +20,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.IPackageManager;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.IBinder;
@@ -54,7 +53,6 @@
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
diff --git a/services/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 98dead3..b6391b6 100644
--- a/services/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -42,16 +42,13 @@
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.AtomicFile;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.TypedValue;
diff --git a/services/java/com/android/server/backup/BackupManagerService.java b/services/java/com/android/server/backup/BackupManagerService.java
index c2b0d10c..18c8ec4 100644
--- a/services/java/com/android/server/backup/BackupManagerService.java
+++ b/services/java/com/android/server/backup/BackupManagerService.java
@@ -82,7 +82,6 @@
 import com.android.internal.backup.BackupConstants;
 import com.android.internal.backup.IBackupTransport;
 import com.android.internal.backup.IObbBackupService;
-import com.android.internal.backup.LocalTransport;
 import com.android.server.EventLogTags;
 import com.android.server.backup.PackageManagerBackupAgent.Metadata;
 
@@ -2215,6 +2214,7 @@
             mSavedStateName = new File(mStateDir, packageName);
             mBackupDataName = new File(mDataDir, packageName + ".data");
             mNewStateName = new File(mStateDir, packageName + ".new");
+            if (MORE_DEBUG) Slog.d(TAG, "data file: " + mBackupDataName);
 
             mSavedState = null;
             mBackupData = null;
diff --git a/services/java/com/android/server/clipboard/ClipboardService.java b/services/java/com/android/server/clipboard/ClipboardService.java
index 6aa596d..f47d66d 100644
--- a/services/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/java/com/android/server/clipboard/ClipboardService.java
@@ -31,7 +31,6 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.IBinder;
@@ -40,7 +39,6 @@
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 
diff --git a/services/java/com/android/server/connectivity/PacManager.java b/services/java/com/android/server/connectivity/PacManager.java
index 7786fe6..8815d0f 100644
--- a/services/java/com/android/server/connectivity/PacManager.java
+++ b/services/java/com/android/server/connectivity/PacManager.java
@@ -24,16 +24,13 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
-import android.net.Proxy;
 import android.net.ProxyProperties;
-import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 231a40a..5971737 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -28,7 +28,6 @@
 import android.hardware.usb.UsbManager;
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
-import android.net.INetworkManagementEventObserver;
 import android.net.INetworkStatsService;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
@@ -51,7 +50,7 @@
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
 import com.android.server.IoThread;
-import com.google.android.collect.Lists;
+import com.android.server.net.BaseNetworkObserver;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -70,7 +69,7 @@
  *
  * TODO - look for parent classes and code sharing
  */
-public class Tethering extends INetworkManagementEventObserver.Stub {
+public class Tethering extends BaseNetworkObserver {
 
     private Context mContext;
     private final static String TAG = "Tethering";
@@ -315,14 +314,6 @@
         }
     }
 
-    public void addressUpdated(String address, String iface, int flags, int scope) {}
-
-    public void addressRemoved(String address, String iface, int flags, int scope) {}
-
-    public void limitReached(String limitName, String iface) {}
-
-    public void interfaceClassDataActivityChanged(String label, boolean active) {}
-
     public int tether(String iface) {
         if (DBG) Log.d(TAG, "Tethering " + iface);
         TetherInterfaceSM sm = null;
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index f5a7039..d87387f 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -29,7 +29,6 @@
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
@@ -63,14 +62,12 @@
 import android.security.KeyStore;
 import android.util.Log;
 import android.util.SparseBooleanArray;
-import android.widget.Toast;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.R;
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
 import com.android.internal.net.VpnProfile;
-import com.android.internal.util.Preconditions;
 import com.android.server.ConnectivityService.VpnCallback;
 import com.android.server.net.BaseNetworkObserver;
 
@@ -78,10 +75,8 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.Inet4Address;
-import java.net.InetAddress;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
-import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import libcore.io.IoUtils;
@@ -597,10 +592,10 @@
         int appId = UserHandle.getAppId(Binder.getCallingUid());
         final long token = Binder.clearCallingIdentity();
         try {
-            // System dialogs are also allowed to control VPN.
+            // System VPN dialogs are also allowed to control VPN.
             PackageManager pm = mContext.getPackageManager();
             ApplicationInfo app = pm.getApplicationInfo(VpnConfig.DIALOGS_PACKAGE, 0);
-            if (appId == app.uid) {
+            if (((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) && (appId == app.uid)) {
                 return;
             }
         } catch (Exception e) {
diff --git a/services/java/com/android/server/content/ContentService.java b/services/java/com/android/server/content/ContentService.java
index 023bf2b..c7d2871 100644
--- a/services/java/com/android/server/content/ContentService.java
+++ b/services/java/com/android/server/content/ContentService.java
@@ -19,11 +19,13 @@
 import android.Manifest;
 import android.accounts.Account;
 import android.app.ActivityManager;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IContentService;
 import android.content.ISyncStatusObserver;
 import android.content.PeriodicSync;
+import android.content.pm.PackageManager;
 import android.content.SyncAdapterType;
 import android.content.SyncInfo;
 import android.content.SyncRequest;
@@ -41,7 +43,6 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseIntArray;
 
@@ -315,7 +316,6 @@
         }
     }
 
-    @Override
     public void requestSync(Account account, String authority, Bundle extras) {
         ContentResolver.validateSyncExtrasBundle(extras);
         int userId = UserHandle.getCallingUserId();
@@ -345,46 +345,56 @@
      * Depending on the request, we enqueue to suit in the SyncManager.
      * @param request The request object. Validation of this object is done by its builder.
      */
-    @Override
     public void sync(SyncRequest request) {
-        Bundle extras = request.getBundle();
-        long flextime = request.getSyncFlexTime();
-        long runAtTime = request.getSyncRunTime();
         int userId = UserHandle.getCallingUserId();
-        int uId = Binder.getCallingUid();
-
+        int callerUid = Binder.getCallingUid();
         // This makes it so that future permission checks will be in the context of this
         // process rather than the caller's process. We will restore this before returning.
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
-            if (syncManager != null) {
-                if (request.hasAuthority()) {
-                    // Sync Adapter registered with the system - old API.
-                    final  Account account = request.getAccount();
-                    final String provider = request.getProvider();
-                    if (request.isPeriodic()) {
-                        mContext.enforceCallingOrSelfPermission(
-                                Manifest.permission.WRITE_SYNC_SETTINGS,
-                                "no permission to write the sync settings");
-                        if (runAtTime < 60) {
-                            Slog.w(TAG, "Requested poll frequency of " + runAtTime
-                                    + " seconds being rounded up to 60 seconds.");
-                            runAtTime = 60;
-                        }
-                        PeriodicSync syncToAdd =
-                                new PeriodicSync(account, provider, extras, runAtTime, flextime);
-                        getSyncManager().getSyncStorageEngine().addPeriodicSync(syncToAdd, userId);
-                    } else {
-                        long beforeRuntimeMillis = (flextime) * 1000;
-                        long runtimeMillis = runAtTime * 1000;
-                        syncManager.scheduleSync(
-                                account, userId, uId, provider, extras,
-                                beforeRuntimeMillis, runtimeMillis,
-                                false /* onlyThoseWithUnknownSyncableState */);
-                    }
+            if (syncManager == null) {
+                return;
+            }
+
+            Bundle extras = request.getBundle();
+            long flextime = request.getSyncFlexTime();
+            long runAtTime = request.getSyncRunTime();
+            if (request.isPeriodic()) {
+                mContext.enforceCallingOrSelfPermission(
+                        Manifest.permission.WRITE_SYNC_SETTINGS,
+                        "no permission to write the sync settings");
+                SyncStorageEngine.EndPoint info;
+                if (!request.hasAuthority()) {
+                    // Extra permissions checking for sync service.
+                    verifySignatureForPackage(callerUid,
+                            request.getService().getPackageName(), "sync");
+                    info = new SyncStorageEngine.EndPoint(request.getService(), userId);
                 } else {
-                    Log.w(TAG, "Unrecognised sync parameters, doing nothing.");
+                    info = new SyncStorageEngine.EndPoint(
+                            request.getAccount(), request.getProvider(), userId);
+                }
+                if (runAtTime < 60) {
+                    Slog.w(TAG, "Requested poll frequency of " + runAtTime
+                            + " seconds being rounded up to 60 seconds.");
+                    runAtTime = 60;
+                }
+                // Schedule periodic sync.
+                getSyncManager().getSyncStorageEngine()
+                    .updateOrAddPeriodicSync(info, runAtTime, flextime, extras);
+            } else {
+                long beforeRuntimeMillis = (flextime) * 1000;
+                long runtimeMillis = runAtTime * 1000;
+                if (request.hasAuthority()) {
+                syncManager.scheduleSync(
+                        request.getAccount(), userId, callerUid, request.getProvider(), extras,
+                        beforeRuntimeMillis, runtimeMillis,
+                        false /* onlyThoseWithUnknownSyncableState */);
+                } else {
+                    syncManager.scheduleSync(
+                            request.getService(), userId, callerUid, extras,
+                            beforeRuntimeMillis,
+                            runtimeMillis); // Empty function.
                 }
             }
         } finally {
@@ -395,11 +405,14 @@
     /**
      * Clear all scheduled sync operations that match the uri and cancel the active sync
      * if they match the authority and account, if they are present.
-     * @param account filter the pending and active syncs to cancel using this account
-     * @param authority filter the pending and active syncs to cancel using this authority
+     *
+     * @param account filter the pending and active syncs to cancel using this account, or null.
+     * @param authority filter the pending and active syncs to cancel using this authority, or
+     * null.
+     * @param cname cancel syncs running on this service, or null for provider/account.
      */
     @Override
-    public void cancelSync(Account account, String authority) {
+    public void cancelSync(Account account, String authority, ComponentName cname) {
         if (authority != null && authority.length() == 0) {
             throw new IllegalArgumentException("Authority must be non-empty");
         }
@@ -411,14 +424,54 @@
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                syncManager.clearScheduledSyncOperations(account, userId, authority);
-                syncManager.cancelActiveSync(account, userId, authority);
+                SyncStorageEngine.EndPoint info;
+                if (cname == null) {
+                    info = new SyncStorageEngine.EndPoint(account, authority, userId);
+                } else {
+                    info = new SyncStorageEngine.EndPoint(cname, userId);
+                }
+                syncManager.clearScheduledSyncOperations(info);
+                syncManager.cancelActiveSync(info, null /* all syncs for this adapter */);
             }
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
+    public void cancelRequest(SyncRequest request) {
+        SyncManager syncManager = getSyncManager();
+        if (syncManager == null) return;
+        int userId = UserHandle.getCallingUserId();
+        int callerUid = Binder.getCallingUid();
+
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncStorageEngine.EndPoint info;
+            Bundle extras = new Bundle(request.getBundle());
+            if (request.hasAuthority()) {
+                Account account = request.getAccount();
+                String provider = request.getProvider();
+                info = new SyncStorageEngine.EndPoint(account, provider, userId);
+            } else {
+                // Only allowed to manipulate syncs for a service which you own.
+                ComponentName service = request.getService();
+                verifySignatureForPackage(callerUid, service.getPackageName(), "cancel");
+                info = new SyncStorageEngine.EndPoint(service, userId);
+            }
+            if (request.isPeriodic()) {
+                // Remove periodic sync.
+                mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
+                        "no permission to write the sync settings");
+                getSyncManager().getSyncStorageEngine().removePeriodicSync(info, extras);
+            }
+            // Cancel active syncs and clear pending syncs from the queue.
+            syncManager.cancelScheduledSyncOperation(info, extras);
+            syncManager.cancelActiveSync(info, extras);
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
     /**
      * Get information about the SyncAdapters that are known to the system.
      * @return an array of SyncAdapters that have registered with the system
@@ -447,8 +500,8 @@
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                return syncManager.getSyncStorageEngine().getSyncAutomatically(
-                        account, userId, providerName);
+                return syncManager.getSyncStorageEngine()
+                        .getSyncAutomatically(account, userId, providerName);
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -469,8 +522,8 @@
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                syncManager.getSyncStorageEngine().setSyncAutomatically(
-                        account, userId, providerName, sync);
+                syncManager.getSyncStorageEngine()
+                .setSyncAutomatically(account, userId, providerName, sync);
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -496,21 +549,22 @@
                     + " seconds being rounded up to 60 seconds.");
             pollFrequency = 60;
         }
+        long defaultFlex = SyncStorageEngine.calculateDefaultFlexTime(pollFrequency);
 
         long identityToken = clearCallingIdentity();
         try {
-            // Add default flex time to this sync.
-            PeriodicSync syncToAdd =
-                    new PeriodicSync(account, authority, extras,
-                            pollFrequency,
-                            SyncStorageEngine.calculateDefaultFlexTime(pollFrequency));
-            getSyncManager().getSyncStorageEngine().addPeriodicSync(syncToAdd, userId);
+            SyncStorageEngine.EndPoint info =
+                    new SyncStorageEngine.EndPoint(account, authority, userId);
+            getSyncManager().getSyncStorageEngine()
+                .updateOrAddPeriodicSync(info,
+                        pollFrequency,
+                        defaultFlex,
+                        extras);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
-    @Override
     public void removePeriodicSync(Account account, String authority, Bundle extras) {
         if (account == null) {
             throw new IllegalArgumentException("Account must not be null");
@@ -524,24 +578,18 @@
         int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
-            PeriodicSync syncToRemove = new PeriodicSync(account, authority, extras,
-                    0 /* Not read for removal */, 0 /* Not read for removal */);
-            getSyncManager().getSyncStorageEngine().removePeriodicSync(syncToRemove, userId);
+            getSyncManager().getSyncStorageEngine()
+                .removePeriodicSync(
+                        new SyncStorageEngine.EndPoint(account, authority, userId),
+                        extras);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
-    /**
-     * TODO: Implement.
-     * @param request Sync to remove.
-     */
-    public void removeSync(SyncRequest request) {
 
-    }
-
-    @Override
-    public List<PeriodicSync> getPeriodicSyncs(Account account, String providerName) {
+    public List<PeriodicSync> getPeriodicSyncs(Account account, String providerName,
+            ComponentName cname) {
         if (account == null) {
             throw new IllegalArgumentException("Account must not be null");
         }
@@ -551,11 +599,20 @@
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                 "no permission to read the sync settings");
 
+        int callerUid = Binder.getCallingUid();
         int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
-            return getSyncManager().getSyncStorageEngine().getPeriodicSyncs(
-                    account, userId, providerName);
+            if (cname == null) {
+                return getSyncManager().getSyncStorageEngine().getPeriodicSyncs(
+                        new SyncStorageEngine.EndPoint(account, providerName, userId));
+            } else if (account == null && providerName == null) {
+                verifySignatureForPackage(callerUid, cname.getPackageName(), "getPeriodicSyncs");
+                return getSyncManager().getSyncStorageEngine().getPeriodicSyncs(
+                        new SyncStorageEngine.EndPoint(cname, userId));
+            } else {
+                throw new IllegalArgumentException("Invalid authority specified");
+            }
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -579,7 +636,6 @@
         return -1;
     }
 
-    @Override
     public void setIsSyncable(Account account, String providerName, int syncable) {
         if (TextUtils.isEmpty(providerName)) {
             throw new IllegalArgumentException("Authority must not be empty");
@@ -600,6 +656,45 @@
         }
     }
 
+    public void setServiceActive(ComponentName cname, boolean active) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
+                "no permission to write the sync settings");
+        verifySignatureForPackage(Binder.getCallingUid(), cname.getPackageName(),
+                "setServiceActive");
+
+        int userId = UserHandle.getCallingUserId();
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                syncManager.getSyncStorageEngine().setIsTargetServiceActive(
+                        cname, userId, active);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
+    public boolean isServiceActive(ComponentName cname) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
+                "no permission to read the sync settings");
+        verifySignatureForPackage(Binder.getCallingUid(), cname.getPackageName(),
+                "isServiceActive");
+
+        int userId = UserHandle.getCallingUserId();
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                return syncManager.getSyncStorageEngine()
+                        .getIsTargetServiceActive(cname, userId);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+        return false;
+    }
+
     @Override
     public boolean getMasterSyncAutomatically() {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
@@ -635,17 +730,24 @@
         }
     }
 
-    public boolean isSyncActive(Account account, String authority) {
+    public boolean isSyncActive(Account account, String authority, ComponentName cname) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                 "no permission to read the sync stats");
         int userId = UserHandle.getCallingUserId();
-
+        int callingUid = Binder.getCallingUid();
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
-            if (syncManager != null) {
+            if (syncManager == null) {
+                return false;
+            }
+            if (cname == null) {
                 return syncManager.getSyncStorageEngine().isSyncActive(
-                        account, userId, authority);
+                        new SyncStorageEngine.EndPoint(account, authority, userId));
+            } else if (account == null && authority == null) {
+                verifySignatureForPackage(callingUid, cname.getPackageName(), "isSyncActive");
+                return syncManager.getSyncStorageEngine().isSyncActive(
+                        new SyncStorageEngine.EndPoint(cname, userId));
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -666,7 +768,7 @@
         }
     }
 
-    public SyncStatusInfo getSyncStatus(Account account, String authority) {
+    public SyncStatusInfo getSyncStatus(Account account, String authority, ComponentName cname) {
         if (TextUtils.isEmpty(authority)) {
             throw new IllegalArgumentException("Authority must not be empty");
         }
@@ -674,34 +776,52 @@
                 "no permission to read the sync stats");
 
         int userId = UserHandle.getCallingUserId();
+        int callerUid = Binder.getCallingUid();
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
-            if (syncManager != null) {
-                return syncManager.getSyncStorageEngine().getStatusByAccountAndAuthority(
-                        account, userId, authority);
+            if (syncManager == null) {
+                return null;
             }
+            SyncStorageEngine.EndPoint info;
+            if (cname == null) {
+                info = new SyncStorageEngine.EndPoint(account, authority, userId);
+            } else if (account == null && authority == null) {
+                verifySignatureForPackage(callerUid, cname.getPackageName(), "getSyncStatus");
+                info = new SyncStorageEngine.EndPoint(cname, userId);
+            } else {
+                throw new IllegalArgumentException("Must call sync status with valid authority");
+            }
+            return syncManager.getSyncStorageEngine().getStatusByAuthority(info);
         } finally {
             restoreCallingIdentity(identityToken);
         }
-        return null;
     }
 
-    public boolean isSyncPending(Account account, String authority) {
+    public boolean isSyncPending(Account account, String authority, ComponentName cname) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                 "no permission to read the sync stats");
 
+        int callerUid = Binder.getCallingUid();
         int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
+        SyncManager syncManager = getSyncManager();
+        if (syncManager == null) return false;
+
         try {
-            SyncManager syncManager = getSyncManager();
-            if (syncManager != null) {
-                return syncManager.getSyncStorageEngine().isSyncPending(account, userId, authority);
+            SyncStorageEngine.EndPoint info;
+            if (cname == null) {
+                info = new SyncStorageEngine.EndPoint(account, authority, userId);
+            } else if (account == null && authority == null) {
+                verifySignatureForPackage(callerUid, cname.getPackageName(), "isSyncPending");
+                info = new SyncStorageEngine.EndPoint(cname, userId);
+            } else {
+                throw new IllegalArgumentException("Invalid authority specified");
             }
+            return syncManager.getSyncStorageEngine().isSyncPending(info);
         } finally {
             restoreCallingIdentity(identityToken);
         }
-        return false;
     }
 
     public void addStatusChangeListener(int mask, ISyncStatusObserver callback) {
@@ -735,6 +855,30 @@
     }
 
     /**
+     * Helper to verify that the provided package name shares the same cert as the caller.
+     * @param callerUid uid of the calling process.
+     * @param packageName package to verify against package of calling application.
+     * @param tag a tag to use when throwing an exception if the signatures don't
+     * match. Cannot be null.
+     * @return true if the calling application and the provided package are signed with the same
+     * certificate.
+     */
+    private boolean verifySignatureForPackage(int callerUid, String packageName, String tag) {
+        PackageManager pm = mContext.getPackageManager();
+        try {
+            int serviceUid = pm.getApplicationInfo(packageName, 0).uid;
+            if (pm.checkSignatures(callerUid, serviceUid) == PackageManager.SIGNATURE_MATCH) {
+                return true;
+            } else {
+                throw new SecurityException(tag + ": Caller certificate does not match that for - "
+                        + packageName);
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new IllegalArgumentException(tag + ": " + packageName + " package not found.");
+        }
+    }
+
+    /**
      * Hide this class since it is not part of api,
      * but current unittest framework requires it to be public
      * @hide
diff --git a/services/java/com/android/server/content/SyncManager.java b/services/java/com/android/server/content/SyncManager.java
index 71d8d99..5add5b0 100644
--- a/services/java/com/android/server/content/SyncManager.java
+++ b/services/java/com/android/server/content/SyncManager.java
@@ -31,6 +31,7 @@
 import android.content.Context;
 import android.content.ISyncAdapter;
 import android.content.ISyncContext;
+import android.content.ISyncServiceAdapter;
 import android.content.ISyncStatusObserver;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -85,10 +86,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -99,7 +98,6 @@
 import java.util.Map;
 import java.util.Random;
 import java.util.Set;
-import java.util.concurrent.CountDownLatch;
 
 /**
  * @hide
@@ -202,8 +200,9 @@
                             Log.v(TAG, "Internal storage is low.");
                         }
                         mStorageIsLow = true;
-                        cancelActiveSync(null /* any account */, UserHandle.USER_ALL,
-                                null /* any authority */);
+                        cancelActiveSync(
+                                SyncStorageEngine.EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL,
+                                null /* any sync */);
                     } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.v(TAG, "Internal storage is ok.");
@@ -221,19 +220,6 @@
         }
     };
 
-    private BroadcastReceiver mBackgroundDataSettingChanged = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (getConnectivityManager().getBackgroundDataSetting()) {
-                scheduleSync(null /* account */, UserHandle.USER_ALL,
-                        SyncOperation.REASON_BACKGROUND_DATA_SETTINGS_CHANGED,
-                        null /* authority */,
-                        new Bundle(), 0 /* delay */, 0 /* delay */,
-                        false /* onlyThoseWithUnknownSyncableState */);
-            }
-        }
-    };
-
     private BroadcastReceiver mAccountsUpdatedReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -278,16 +264,16 @@
             doDatabaseCleanup();
         }
 
+        AccountAndUser[] accounts = mRunningAccounts;
         for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) {
-            if (!containsAccountAndUser(mRunningAccounts,
-                    currentSyncContext.mSyncOperation.account,
-                    currentSyncContext.mSyncOperation.userId)) {
+            if (!containsAccountAndUser(accounts,
+                    currentSyncContext.mSyncOperation.target.account,
+                    currentSyncContext.mSyncOperation.target.userId)) {
                 Log.d(TAG, "canceling sync since the account is no longer running");
                 sendSyncFinishedOrCanceledMessage(currentSyncContext,
                         null /* no result since this is a cancel */);
             }
         }
-
         // we must do this since we don't bother scheduling alarms when
         // the accounts are not set yet
         sendCheckAlarmsMessage();
@@ -316,9 +302,7 @@
                     if (Log.isLoggable(TAG, Log.VERBOSE)) {
                         Log.v(TAG, "Reconnection detected: clearing all backoffs");
                     }
-                    synchronized(mSyncQueue) {
-                        mSyncStorageEngine.clearAllBackoffsLocked(mSyncQueue);
-                    }
+                    mSyncStorageEngine.clearAllBackoffs(mSyncQueue);
                 }
                 sendCheckAlarmsMessage();
             }
@@ -384,12 +368,17 @@
         mSyncStorageEngine = SyncStorageEngine.getSingleton();
         mSyncStorageEngine.setOnSyncRequestListener(new OnSyncRequestListener() {
             @Override
-            public void onSyncRequest(Account account, int userId, int reason, String authority,
-                    Bundle extras) {
-                scheduleSync(account, userId, reason, authority, extras,
-                    0 /* no delay */,
-                    0 /* no delay */,
-                    false);
+            public void onSyncRequest(SyncStorageEngine.EndPoint info, int reason, Bundle extras) {
+                if (info.target_provider) {
+                    scheduleSync(info.account, info.userId, reason, info.provider, extras,
+                        0 /* no flex */,
+                        0 /* run immediately */,
+                        false);
+                } else if (info.target_service) {
+                    scheduleSync(info.service, info.userId, reason, extras,
+                            0 /* no flex */,
+                            0 /* run immediately */);
+                }
             }
         });
 
@@ -421,9 +410,6 @@
             context.registerReceiver(mBootCompletedReceiver, intentFilter);
         }
 
-        intentFilter = new IntentFilter(ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
-        context.registerReceiver(mBackgroundDataSettingChanged, intentFilter);
-
         intentFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
         intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
         context.registerReceiver(mStorageIntentReceiver, intentFilter);
@@ -538,11 +524,78 @@
 
     private void ensureAlarmService() {
         if (mAlarmService == null) {
-            mAlarmService = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
+            mAlarmService = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
         }
     }
 
     /**
+     * Initiate a sync using the new anonymous service API.
+     * @param cname SyncService component bound to in order to perform the sync. 
+     * @param userId the id of the user whose accounts are to be synced. If userId is USER_ALL,
+     *          then all users' accounts are considered.
+     * @param uid Linux uid of the application that is performing the sync. 
+     * @param extras a Map of SyncAdapter-specific information to control
+     *          syncs of a specific provider. Cannot be null.
+     * @param beforeRunTimeMillis milliseconds before <code>runtimeMillis</code> that this sync may
+     * be run.
+     * @param runtimeMillis milliseconds from now by which this sync must be run.
+     */
+    public void scheduleSync(ComponentName cname, int userId, int uid, Bundle extras,
+            long beforeRunTimeMillis, long runtimeMillis) {
+        boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
+        if (isLoggable) {
+            Log.d(TAG, "one off sync for: " + cname + " " + extras.toString());
+        }
+
+        Boolean expedited = extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false);
+        if (expedited) {
+            runtimeMillis = -1; // this means schedule at the front of the queue
+        }
+
+        final boolean ignoreSettings =
+                extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false);
+        int source = SyncStorageEngine.SOURCE_SERVICE;
+        boolean isEnabled = mSyncStorageEngine.getIsTargetServiceActive(cname, userId);
+        // Only schedule this sync if
+        //   - we've explicitly been told to ignore settings.
+        //   - global sync is enabled for this user.
+        boolean syncAllowed =
+                ignoreSettings
+                || mSyncStorageEngine.getMasterSyncAutomatically(userId);
+        if (!syncAllowed) {
+            if (isLoggable) {
+                Log.d(TAG, "scheduleSync: sync of " + cname + " not allowed, dropping request.");
+            }
+            return;
+        }
+        if (!isEnabled) {
+            if (isLoggable) {
+                Log.d(TAG, "scheduleSync: " + cname + " is not enabled, dropping request");
+            }
+            return;
+        }
+        SyncStorageEngine.EndPoint info = new SyncStorageEngine.EndPoint(cname, userId);
+        Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(info);
+        long delayUntil = mSyncStorageEngine.getDelayUntilTime(info);
+        final long backoffTime = backoff != null ? backoff.first : 0;
+        if (isLoggable) {
+                Log.v(TAG, "schedule Sync:"
+                        + ", delay until " + delayUntil
+                        + ", run by " + runtimeMillis
+                        + ", flex " + beforeRunTimeMillis
+                        + ", source " + source
+                        + ", sync service " + cname
+                        + ", extras " + extras);
+        }
+        scheduleSyncOperation(
+                new SyncOperation(cname, userId, uid, source, extras,
+                        runtimeMillis /* runtime */,
+                        beforeRunTimeMillis /* flextime */,
+                        backoffTime,
+                        delayUntil));
+    }
+
+    /**
      * Initiate a sync. This can start a sync for all providers
      * (pass null to url, set onlyTicklable to false), only those
      * providers that are marked as ticklable (pass null to url,
@@ -588,9 +641,6 @@
             long runtimeMillis, boolean onlyThoseWithUnkownSyncableState) {
         boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
 
-        final boolean backgroundDataUsageAllowed = !mBootCompleted ||
-                getConnectivityManager().getBackgroundDataSetting();
-
         if (extras == null) {
             extras = new Bundle();
         }
@@ -607,8 +657,6 @@
         if (requestedAccount != null && userId != UserHandle.USER_ALL) {
             accounts = new AccountAndUser[] { new AccountAndUser(requestedAccount, userId) };
         } else {
-            // if the accounts aren't configured yet then we can't support an account-less
-            // sync request
             accounts = mRunningAccounts;
             if (accounts.length == 0) {
                 if (isLoggable) {
@@ -683,12 +731,10 @@
                     continue;
                 }
 
-                // always allow if the isSyncable state is unknown
                 boolean syncAllowed =
-                        (isSyncable < 0)
+                        (isSyncable < 0) // always allow if the isSyncable state is unknown
                         || ignoreSettings
-                        || (backgroundDataUsageAllowed
-                                && mSyncStorageEngine.getMasterSyncAutomatically(account.userId)
+                        || (mSyncStorageEngine.getMasterSyncAutomatically(account.userId)
                                 && mSyncStorageEngine.getSyncAutomatically(account.account,
                                         account.userId, authority));
                 if (!syncAllowed) {
@@ -698,11 +744,12 @@
                     }
                     continue;
                 }
-
-                Pair<Long, Long> backoff = mSyncStorageEngine
-                        .getBackoff(account.account, account.userId, authority);
-                long delayUntil = mSyncStorageEngine.getDelayUntilTime(account.account,
-                        account.userId, authority);
+                SyncStorageEngine.EndPoint info =
+                        new SyncStorageEngine.EndPoint(
+                                account.account, authority, account.userId);
+                Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(info);
+                long delayUntil =
+                        mSyncStorageEngine.getDelayUntilTime(info);
                 final long backoffTime = backoff != null ? backoff.first : 0;
                 if (isSyncable < 0) {
                     // Initialisation sync.
@@ -712,6 +759,7 @@
                         Log.v(TAG, "schedule initialisation Sync:"
                                 + ", delay until " + delayUntil
                                 + ", run by " + 0
+                                + ", flex " + 0
                                 + ", source " + source
                                 + ", account " + account
                                 + ", authority " + authority
@@ -787,13 +835,12 @@
         mSyncHandler.sendMessage(msg);
     }
 
-    private void sendCancelSyncsMessage(final Account account, final int userId,
-            final String authority) {
+    private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_CANCEL");
         Message msg = mSyncHandler.obtainMessage();
         msg.what = SyncHandler.MESSAGE_CANCEL;
-        msg.obj = Pair.create(account, authority);
-        msg.arg1 = userId;
+        msg.setData(extras);
+        msg.obj = info;
         mSyncHandler.sendMessage(msg);
     }
 
@@ -816,10 +863,11 @@
     }
 
     private void clearBackoffSetting(SyncOperation op) {
-        mSyncStorageEngine.setBackoff(op.account, op.userId, op.authority,
-                SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE);
+        mSyncStorageEngine.setBackoff(op.target,
+                SyncStorageEngine.NOT_IN_BACKOFF_MODE,
+                SyncStorageEngine.NOT_IN_BACKOFF_MODE);
         synchronized (mSyncQueue) {
-            mSyncQueue.onBackoffChanged(op.account, op.userId, op.authority, 0);
+            mSyncQueue.onBackoffChanged(op.target, 0);
         }
     }
 
@@ -829,7 +877,7 @@
         final long now = SystemClock.elapsedRealtime();
 
         final Pair<Long, Long> previousSettings =
-                mSyncStorageEngine.getBackoff(op.account, op.userId, op.authority);
+                mSyncStorageEngine.getBackoff(op.target);
         long newDelayInMs = -1;
         if (previousSettings != null) {
             // don't increase backoff before current backoff is expired. This will happen for op's
@@ -860,14 +908,12 @@
 
         final long backoff = now + newDelayInMs;
 
-        mSyncStorageEngine.setBackoff(op.account, op.userId, op.authority,
-                backoff, newDelayInMs);
-
+        mSyncStorageEngine.setBackoff(op.target, backoff, newDelayInMs);
         op.backoff = backoff;
         op.updateEffectiveRunTime();
 
         synchronized (mSyncQueue) {
-            mSyncQueue.onBackoffChanged(op.account, op.userId, op.authority, backoff);
+            mSyncQueue.onBackoffChanged(op.target, backoff);
         }
     }
 
@@ -880,20 +926,20 @@
         } else {
             newDelayUntilTime = 0;
         }
-        mSyncStorageEngine
-                .setDelayUntilTime(op.account, op.userId, op.authority, newDelayUntilTime);
+        mSyncStorageEngine.setDelayUntilTime(op.target, newDelayUntilTime);
         synchronized (mSyncQueue) {
-            mSyncQueue.onDelayUntilTimeChanged(op.account, op.authority, newDelayUntilTime);
+            mSyncQueue.onDelayUntilTimeChanged(op.target, newDelayUntilTime);
         }
     }
 
     /**
-     * Cancel the active sync if it matches the authority and account.
-     * @param account limit the cancelations to syncs with this account, if non-null
-     * @param authority limit the cancelations to syncs with this authority, if non-null
+     * Cancel the active sync if it matches the target.
+     * @param info object containing info about which syncs to cancel. The target can
+     * have null account/provider info to specify all accounts/providers.
+     * @param extras if non-null, specifies the exact sync to remove.
      */
-    public void cancelActiveSync(Account account, int userId, String authority) {
-        sendCancelSyncsMessage(account, userId, authority);
+    public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras) {
+        sendCancelSyncsMessage(info, extras);
     }
 
     /**
@@ -922,24 +968,40 @@
 
     /**
      * Remove scheduled sync operations.
-     * @param account limit the removals to operations with this account, if non-null
-     * @param authority limit the removals to operations with this authority, if non-null
+     * @param info limit the removals to operations that match this target. The target can
+     * have null account/provider info to specify all accounts/providers.
      */
-    public void clearScheduledSyncOperations(Account account, int userId, String authority) {
+    public void clearScheduledSyncOperations(SyncStorageEngine.EndPoint info) {
         synchronized (mSyncQueue) {
-            mSyncQueue.remove(account, userId, authority);
+            mSyncQueue.remove(info, null /* all operations */);
         }
-        mSyncStorageEngine.setBackoff(account, userId, authority,
+        mSyncStorageEngine.setBackoff(info,
                 SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE);
     }
 
+    /**
+     * Remove a specified sync, if it exists.
+     * @param info Authority for which the sync is to be removed.
+     * @param extras extras bundle to uniquely identify sync.
+     */
+    public void cancelScheduledSyncOperation(SyncStorageEngine.EndPoint info, Bundle extras) {
+        synchronized (mSyncQueue) {
+            mSyncQueue.remove(info, extras);
+        }
+        // Reset the back-off if there are no more syncs pending.
+        if (!mSyncStorageEngine.isSyncPending(info)) {
+            mSyncStorageEngine.setBackoff(info,
+                    SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE);
+        }
+    }
+
     void maybeRescheduleSync(SyncResult syncResult, SyncOperation operation) {
         boolean isLoggable = Log.isLoggable(TAG, Log.DEBUG);
         if (isLoggable) {
             Log.d(TAG, "encountered error(s) during the sync: " + syncResult + ", " + operation);
         }
 
-        operation = new SyncOperation(operation);
+        operation = new SyncOperation(operation, 0L /* newRunTimeFromNow */);
 
         // The SYNC_EXTRAS_IGNORE_BACKOFF only applies to the first attempt to sync a given
         // request. Retries of the request will always honor the backoff, so clear the
@@ -948,25 +1010,29 @@
             operation.extras.remove(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF);
         }
 
-        // If this sync aborted because the internal sync loop retried too many times then
-        //   don't reschedule. Otherwise we risk getting into a retry loop.
-        // If the operation succeeded to some extent then retry immediately.
-        // If this was a two-way sync then retry soft errors with an exponential backoff.
-        // If this was an upward sync then schedule a two-way sync immediately.
-        // Otherwise do not reschedule.
         if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)) {
-            Log.d(TAG, "not retrying sync operation because SYNC_EXTRAS_DO_NOT_RETRY was specified "
-                    + operation);
+            if (isLoggable) {
+                Log.d(TAG, "not retrying sync operation because SYNC_EXTRAS_DO_NOT_RETRY was specified "
+                        + operation);
+            }
         } else if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false)
                 && !syncResult.syncAlreadyInProgress) {
+            // If this was an upward sync then schedule a two-way sync immediately.
             operation.extras.remove(ContentResolver.SYNC_EXTRAS_UPLOAD);
-            Log.d(TAG, "retrying sync operation as a two-way sync because an upload-only sync "
-                    + "encountered an error: " + operation);
+            if (isLoggable) {
+                Log.d(TAG, "retrying sync operation as a two-way sync because an upload-only sync "
+                        + "encountered an error: " + operation);
+            }
             scheduleSyncOperation(operation);
         } else if (syncResult.tooManyRetries) {
-            Log.d(TAG, "not retrying sync operation because it retried too many times: "
-                    + operation);
+            // If this sync aborted because the internal sync loop retried too many times then
+            //   don't reschedule. Otherwise we risk getting into a retry loop.
+            if (isLoggable) {
+                Log.d(TAG, "not retrying sync operation because it retried too many times: "
+                        + operation);
+            }
         } else if (syncResult.madeSomeProgress()) {
+            // If the operation succeeded to some extent then retry immediately.
             if (isLoggable) {
                 Log.d(TAG, "retrying sync operation because even though it had an error "
                         + "it achieved some success");
@@ -979,19 +1045,18 @@
             }
             scheduleSyncOperation(
                 new SyncOperation(
-                    operation.account, operation.userId,
-                    operation.reason,
-                    operation.syncSource,
-                    operation.authority, operation.extras,
-                    DELAY_RETRY_SYNC_IN_PROGRESS_IN_SECONDS * 1000, operation.flexTime,
-                    operation.backoff, operation.delayUntil, operation.allowParallelSyncs));
+                        operation,
+                        DELAY_RETRY_SYNC_IN_PROGRESS_IN_SECONDS * 1000 /* newRunTimeFromNow */)
+                );
         } else if (syncResult.hasSoftError()) {
+            // If this was a two-way sync then retry soft errors with an exponential backoff.
             if (isLoggable) {
                 Log.d(TAG, "retrying sync operation because it encountered a soft error: "
                         + operation);
             }
             scheduleSyncOperation(operation);
         } else {
+            // Otherwise do not reschedule.
             Log.d(TAG, "not retrying sync operation because the error is a hard error: "
                     + operation);
         }
@@ -1024,9 +1089,12 @@
         updateRunningAccounts();
 
         cancelActiveSync(
-                null /* any account */,
-                userId,
-                null /* any authority */);
+                new SyncStorageEngine.EndPoint(
+                        null /* any account */,
+                        null /* any authority */,
+                        userId),
+                        null /* any sync. */
+                );
     }
 
     private void onUserRemoved(int userId) {
@@ -1035,7 +1103,7 @@
         // Clean up the storage engine database
         mSyncStorageEngine.doDatabaseCleanup(new Account[0], userId);
         synchronized (mSyncQueue) {
-            mSyncQueue.removeUser(userId);
+            mSyncQueue.removeUserLocked(userId);
         }
     }
 
@@ -1047,6 +1115,7 @@
         final SyncOperation mSyncOperation;
         final long mHistoryRowId;
         ISyncAdapter mSyncAdapter;
+        ISyncServiceAdapter mSyncServiceAdapter;
         final long mStartTime;
         long mTimeoutStartTime;
         boolean mBound;
@@ -1072,10 +1141,10 @@
             mSyncOperation = syncOperation;
             mHistoryRowId = historyRowId;
             mSyncAdapter = null;
+            mSyncServiceAdapter = null;
             mStartTime = SystemClock.elapsedRealtime();
             mTimeoutStartTime = mStartTime;
-            mSyncWakeLock = mSyncHandler.getSyncWakeLock(
-                    mSyncOperation.account, mSyncOperation.authority);
+            mSyncWakeLock = mSyncHandler.getSyncWakeLock(mSyncOperation);
             mSyncWakeLock.setWorkSource(new WorkSource(syncAdapterUid));
             mSyncWakeLock.acquire();
         }
@@ -1102,7 +1171,7 @@
         public void onServiceConnected(ComponentName name, IBinder service) {
             Message msg = mSyncHandler.obtainMessage();
             msg.what = SyncHandler.MESSAGE_SERVICE_CONNECTED;
-            msg.obj = new ServiceConnectionData(this, ISyncAdapter.Stub.asInterface(service));
+            msg.obj = new ServiceConnectionData(this, service);
             mSyncHandler.sendMessage(msg);
         }
 
@@ -1113,13 +1182,13 @@
             mSyncHandler.sendMessage(msg);
         }
 
-        boolean bindToSyncAdapter(RegisteredServicesCache.ServiceInfo info, int userId) {
+        boolean bindToSyncAdapter(ComponentName serviceComponent, int userId) {
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                Log.d(TAG, "bindToSyncAdapter: " + info.componentName + ", connection " + this);
+                Log.d(TAG, "bindToSyncAdapter: " + serviceComponent + ", connection " + this);
             }
             Intent intent = new Intent();
             intent.setAction("android.content.SyncAdapter");
-            intent.setComponent(info.componentName);
+            intent.setComponent(serviceComponent);
             intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
                     com.android.internal.R.string.sync_binding_label);
             intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivityAsUser(
@@ -1129,7 +1198,7 @@
             final boolean bindResult = mContext.bindServiceAsUser(intent, this,
                     Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
                     | Context.BIND_ALLOW_OOM_MANAGEMENT,
-                    new UserHandle(mSyncOperation.userId));
+                    new UserHandle(mSyncOperation.target.userId));
             if (!bindResult) {
                 mBound = false;
             }
@@ -1152,7 +1221,6 @@
             mSyncWakeLock.setWorkSource(null);
         }
 
-        @Override
         public String toString() {
             StringBuilder sb = new StringBuilder();
             toString(sb);
@@ -1291,11 +1359,13 @@
                 int row = table.getNumRows();
                 Pair<AuthorityInfo, SyncStatusInfo> syncAuthoritySyncStatus = 
                         mSyncStorageEngine.getCopyOfAuthorityWithSyncStatus(
-                                account.account, account.userId, syncAdapterType.type.authority);
+                                new SyncStorageEngine.EndPoint(
+                                        account.account,
+                                        syncAdapterType.type.authority,
+                                        account.userId));
                 SyncStorageEngine.AuthorityInfo settings = syncAuthoritySyncStatus.first;
                 SyncStatusInfo status = syncAuthoritySyncStatus.second;
-
-                String authority = settings.authority;
+                String authority = settings.target.provider;
                 if (authority.length() > 50) {
                     authority = authority.substring(authority.length() - 50);
                 }
@@ -1416,14 +1486,25 @@
             int maxAuthority = 0;
             int maxAccount = 0;
             for (SyncStorageEngine.SyncHistoryItem item : items) {
-                SyncStorageEngine.AuthorityInfo authority
+                SyncStorageEngine.AuthorityInfo authorityInfo
                         = mSyncStorageEngine.getAuthority(item.authorityId);
                 final String authorityName;
                 final String accountKey;
-                if (authority != null) {
-                    authorityName = authority.authority;
-                    accountKey = authority.account.name + "/" + authority.account.type
-                            + " u" + authority.userId;
+                if (authorityInfo != null) {
+                    if (authorityInfo.target.target_provider) {
+                        authorityName = authorityInfo.target.provider;
+                        accountKey = authorityInfo.target.account.name + "/"
+                                + authorityInfo.target.account.type
+                                + " u" + authorityInfo.target.userId;
+                    } else if (authorityInfo.target.target_service) {
+                        authorityName = authorityInfo.target.service.getPackageName() + "/"
+                                + authorityInfo.target.service.getClassName()
+                                + " u" + authorityInfo.target.userId;
+                        accountKey = "no account";
+                    } else {
+                        authorityName = "Unknown";
+                        accountKey = "Unknown";
+                    }
                 } else {
                     authorityName = "Unknown";
                     accountKey = "Unknown";
@@ -1544,14 +1625,25 @@
             final PackageManager pm = mContext.getPackageManager();
             for (int i = 0; i < N; i++) {
                 SyncStorageEngine.SyncHistoryItem item = items.get(i);
-                SyncStorageEngine.AuthorityInfo authority
+                SyncStorageEngine.AuthorityInfo authorityInfo
                         = mSyncStorageEngine.getAuthority(item.authorityId);
                 final String authorityName;
                 final String accountKey;
-                if (authority != null) {
-                    authorityName = authority.authority;
-                    accountKey = authority.account.name + "/" + authority.account.type
-                            + " u" + authority.userId;
+                if (authorityInfo != null) {
+                    if (authorityInfo.target.target_provider) {
+                        authorityName = authorityInfo.target.provider;
+                        accountKey = authorityInfo.target.account.name + "/"
+                                + authorityInfo.target.account.type
+                                + " u" + authorityInfo.target.userId;
+                    } else if (authorityInfo.target.target_service) {
+                        authorityName = authorityInfo.target.service.getPackageName() + "/"
+                                + authorityInfo.target.service.getClassName()
+                                + " u" + authorityInfo.target.userId;
+                        accountKey = "none";
+                    } else {
+                        authorityName = "Unknown";
+                        accountKey = "Unknown";
+                    }
                 } else {
                     authorityName = "Unknown";
                     accountKey = "Unknown";
@@ -1610,14 +1702,25 @@
                 if (extras == null || extras.size() == 0) {
                     continue;
                 }
-                final SyncStorageEngine.AuthorityInfo authority
+                final SyncStorageEngine.AuthorityInfo authorityInfo
                         = mSyncStorageEngine.getAuthority(item.authorityId);
                 final String authorityName;
                 final String accountKey;
-                if (authority != null) {
-                    authorityName = authority.authority;
-                    accountKey = authority.account.name + "/" + authority.account.type
-                            + " u" + authority.userId;
+                if (authorityInfo != null) {
+                    if (authorityInfo.target.target_provider) {
+                        authorityName = authorityInfo.target.provider;
+                        accountKey = authorityInfo.target.account.name + "/"
+                                + authorityInfo.target.account.type
+                                + " u" + authorityInfo.target.userId;
+                    } else if (authorityInfo.target.target_service) {
+                        authorityName = authorityInfo.target.service.getPackageName() + "/"
+                                + authorityInfo.target.service.getClassName()
+                                + " u" + authorityInfo.target.userId;
+                        accountKey = "none";
+                    } else {
+                        authorityName = "Unknown";
+                        accountKey = "Unknown";
+                    }
                 } else {
                     authorityName = "Unknown";
                     accountKey = "Unknown";
@@ -1761,10 +1864,11 @@
 
     class ServiceConnectionData {
         public final ActiveSyncContext activeSyncContext;
-        public final ISyncAdapter syncAdapter;
-        ServiceConnectionData(ActiveSyncContext activeSyncContext, ISyncAdapter syncAdapter) {
+        public final IBinder adapter;
+
+        ServiceConnectionData(ActiveSyncContext activeSyncContext, IBinder adapter) {
             this.activeSyncContext = activeSyncContext;
-            this.syncAdapter = syncAdapter;
+            this.adapter = adapter;
         }
     }
 
@@ -1784,11 +1888,11 @@
         public final SyncNotificationInfo mSyncNotificationInfo = new SyncNotificationInfo();
         private Long mAlarmScheduleTime = null;
         public final SyncTimeTracker mSyncTimeTracker = new SyncTimeTracker();
-        private final HashMap<Pair<Account, String>, PowerManager.WakeLock> mWakeLocks =
-                Maps.newHashMap();
+        private final HashMap<String, PowerManager.WakeLock> mWakeLocks = Maps.newHashMap();
+
         private List<Message> mBootQueue = new ArrayList<Message>();
 
-        public void onBootCompleted() {
+      public void onBootCompleted() {
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "Boot completed, clearing boot queue.");
             }
@@ -1803,12 +1907,11 @@
             }
         }
 
-        private PowerManager.WakeLock getSyncWakeLock(Account account, String authority) {
-            final Pair<Account, String> wakeLockKey = Pair.create(account, authority);
+        private PowerManager.WakeLock getSyncWakeLock(SyncOperation operation) {
+            final String wakeLockKey = operation.wakeLockKey();
             PowerManager.WakeLock wakeLock = mWakeLocks.get(wakeLockKey);
             if (wakeLock == null) {
-                final String name = SYNC_WAKE_LOCK_PREFIX + "/" + authority + "/" + account.type
-                        + "/" + account.name;
+                final String name = SYNC_WAKE_LOCK_PREFIX + operation.wakeLockName();
                 wakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, name);
                 wakeLock.setReferenceCounted(false);
                 mWakeLocks.put(wakeLockKey, wakeLock);
@@ -1861,7 +1964,6 @@
             super(looper);
         }
 
-        @Override
         public void handleMessage(Message msg) {
             if (tryEnqueueMessageUntilReadyToRun(msg)) {
                 return;
@@ -1881,12 +1983,13 @@
                 earliestFuturePollTime = scheduleReadyPeriodicSyncs();
                 switch (msg.what) {
                     case SyncHandler.MESSAGE_CANCEL: {
-                        Pair<Account, String> payload = (Pair<Account, String>) msg.obj;
+                        SyncStorageEngine.EndPoint payload = (SyncStorageEngine.EndPoint) msg.obj;
+                        Bundle extras = msg.peekData();
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CANCEL: "
-                                    + payload.first + ", " + payload.second);
+                                    + payload + " bundle: " + extras);
                         }
-                        cancelActiveSyncLocked(payload.first, msg.arg1, payload.second);
+                        cancelActiveSyncLocked(payload, extras);
                         nextPendingSyncTime = maybeStartNextSyncLocked();
                         break;
                     }
@@ -1895,35 +1998,38 @@
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.v(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_FINISHED");
                         }
-                        SyncHandlerMessagePayload payload = (SyncHandlerMessagePayload)msg.obj;
+                        SyncHandlerMessagePayload payload = (SyncHandlerMessagePayload) msg.obj;
                         if (!isSyncStillActive(payload.activeSyncContext)) {
                             Log.d(TAG, "handleSyncHandlerMessage: dropping since the "
                                     + "sync is no longer active: "
                                     + payload.activeSyncContext);
                             break;
                         }
-                        runSyncFinishedOrCanceledLocked(payload.syncResult, payload.activeSyncContext);
+                        runSyncFinishedOrCanceledLocked(payload.syncResult,
+                                payload.activeSyncContext);
 
                         // since a sync just finished check if it is time to start a new sync
                         nextPendingSyncTime = maybeStartNextSyncLocked();
                         break;
 
                     case SyncHandler.MESSAGE_SERVICE_CONNECTED: {
-                        ServiceConnectionData msgData = (ServiceConnectionData)msg.obj;
+                        ServiceConnectionData msgData = (ServiceConnectionData) msg.obj;
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CONNECTED: "
                                     + msgData.activeSyncContext);
                         }
                         // check that this isn't an old message
                         if (isSyncStillActive(msgData.activeSyncContext)) {
-                            runBoundToSyncAdapter(msgData.activeSyncContext, msgData.syncAdapter);
+                            runBoundToAdapter(
+                                    msgData.activeSyncContext,
+                                    msgData.adapter);
                         }
                         break;
                     }
 
                     case SyncHandler.MESSAGE_SERVICE_DISCONNECTED: {
                         final ActiveSyncContext currentSyncContext =
-                                ((ServiceConnectionData)msg.obj).activeSyncContext;
+                                ((ServiceConnectionData) msg.obj).activeSyncContext;
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_DISCONNECTED: "
                                     + currentSyncContext);
@@ -1932,12 +2038,15 @@
                         if (isSyncStillActive(currentSyncContext)) {
                             // cancel the sync if we have a syncadapter, which means one is
                             // outstanding
-                            if (currentSyncContext.mSyncAdapter != null) {
-                                try {
+                            try {
+                                if (currentSyncContext.mSyncAdapter != null) {
                                     currentSyncContext.mSyncAdapter.cancelSync(currentSyncContext);
-                                } catch (RemoteException e) {
-                                    // we don't need to retry this in this case
+                                } else if (currentSyncContext.mSyncServiceAdapter != null) {
+                                    currentSyncContext.mSyncServiceAdapter
+                                        .cancelSync(currentSyncContext);
                                 }
+                            } catch (RemoteException e) {
+                                // We don't need to retry this in this case.
                             }
 
                             // pretend that the sync failed with an IOException,
@@ -1982,9 +2091,46 @@
             }
         }
 
+        private boolean isDispatchable(SyncStorageEngine.EndPoint target) {
+            final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
+            if (target.target_provider) {
+                // skip the sync if the account of this operation no longer exists
+                AccountAndUser[] accounts = mRunningAccounts;
+                if (!containsAccountAndUser(
+                        accounts, target.account, target.userId)) {
+                    return false;
+                }
+                if (!mSyncStorageEngine.getMasterSyncAutomatically(target.userId)
+                        || !mSyncStorageEngine.getSyncAutomatically(
+                                target.account,
+                                target.userId,
+                                target.provider)) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Not scheduling periodic operation: sync turned off.");
+                    }
+                    return false;
+                }
+                if (getIsSyncable(target.account, target.userId, target.provider)
+                        == 0) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Not scheduling periodic operation: isSyncable == 0.");
+                    }
+                    return false;
+                }
+            } else if (target.target_service) {
+                if (mSyncStorageEngine.getIsTargetServiceActive(target.service, target.userId)) {
+                    if (isLoggable) {
+                        Log.v(TAG, "   Not scheduling periodic operation: isEnabled == 0.");
+                    }
+                    return false;
+                }
+            }
+            return true;
+        }
+
         /**
          * Turn any periodic sync operations that are ready to run into pending sync operations.
-         * @return the desired start time of the earliest future  periodic sync operation,
+         * @return the desired start time of the earliest future periodic sync operation,
          * in milliseconds since boot
          */
         private long scheduleReadyPeriodicSyncs() {
@@ -1992,14 +2138,7 @@
             if (isLoggable) {
                 Log.v(TAG, "scheduleReadyPeriodicSyncs");
             }
-            final boolean backgroundDataUsageAllowed =
-                    getConnectivityManager().getBackgroundDataSetting();
             long earliestFuturePollTime = Long.MAX_VALUE;
-            if (!backgroundDataUsageAllowed) {
-                return earliestFuturePollTime;
-            }
-
-            AccountAndUser[] accounts = mRunningAccounts;
 
             final long nowAbsolute = System.currentTimeMillis();
             final long shiftedNowAbsolute = (0 < nowAbsolute - mSyncRandomOffsetMillis)
@@ -2010,40 +2149,31 @@
             for (Pair<AuthorityInfo, SyncStatusInfo> info : infos) {
                 final AuthorityInfo authorityInfo = info.first;
                 final SyncStatusInfo status = info.second;
-                if (TextUtils.isEmpty(authorityInfo.authority)) {
-                    Log.e(TAG, "Got an empty provider string. Skipping: " + authorityInfo);
-                    continue;
-                }
-                // skip the sync if the account of this operation no longer exists
-                if (!containsAccountAndUser(
-                        accounts, authorityInfo.account, authorityInfo.userId)) {
+
+                if (TextUtils.isEmpty(authorityInfo.target.provider)) {
+                    Log.e(TAG, "Got an empty provider string. Skipping: "
+                        + authorityInfo.target.provider);
                     continue;
                 }
 
-                if (!mSyncStorageEngine.getMasterSyncAutomatically(authorityInfo.userId)
-                        || !mSyncStorageEngine.getSyncAutomatically(
-                                authorityInfo.account, authorityInfo.userId,
-                                authorityInfo.authority)) {
-                    continue;
-                }
-
-                if (getIsSyncable(
-                        authorityInfo.account, authorityInfo.userId, authorityInfo.authority)
-                        == 0) {
+                if (!isDispatchable(authorityInfo.target)) {
                     continue;
                 }
 
                 for (int i = 0, N = authorityInfo.periodicSyncs.size(); i < N; i++) {
                     final PeriodicSync sync = authorityInfo.periodicSyncs.get(i);
                     final Bundle extras = sync.extras;
-                    final long periodInMillis = sync.period * 1000;
-                    final long flexInMillis = sync.flexTime * 1000;
+                    final Long periodInMillis = sync.period * 1000;
+                    final Long flexInMillis = sync.flexTime * 1000;
                     // Skip if the period is invalid.
                     if (periodInMillis <= 0) {
                         continue;
                     }
                     // Find when this periodic sync was last scheduled to run.
                     final long lastPollTimeAbsolute = status.getPeriodicSyncTime(i);
+                    final long shiftedLastPollTimeAbsolute =
+                            (0 < lastPollTimeAbsolute - mSyncRandomOffsetMillis) ?
+                                    (lastPollTimeAbsolute - mSyncRandomOffsetMillis) : 0;
                     long remainingMillis
                         = periodInMillis - (shiftedNowAbsolute % periodInMillis);
                     long timeSinceLastRunMillis
@@ -2054,12 +2184,13 @@
                     boolean runEarly = remainingMillis <= flexInMillis
                             && timeSinceLastRunMillis > periodInMillis - flexInMillis;
                     if (isLoggable) {
-                        Log.v(TAG, "sync: " + i + " for " + authorityInfo.authority + "."
+                        Log.v(TAG, "sync: " + i + " for " + authorityInfo.target + "."
                         + " period: " + (periodInMillis)
                         + " flex: " + (flexInMillis)
                         + " remaining: " + (remainingMillis)
                         + " time_since_last: " + timeSinceLastRunMillis
                         + " last poll absol: " + lastPollTimeAbsolute
+                        + " last poll shifed: " + shiftedLastPollTimeAbsolute
                         + " shifted now: " + shiftedNowAbsolute
                         + " run_early: " + runEarly);
                     }
@@ -2073,41 +2204,49 @@
                      * future, sync now and reinitialize. This can happen for
                      * example if the user changed the time, synced and changed
                      * back.
-                     * Case 3: If we failed to sync at the last scheduled
-                     * time.
+                     * Case 3: If we failed to sync at the last scheduled time.
                      * Case 4: This sync is close enough to the time that we can schedule it.
                      */
-                    if (runEarly // Case 4
-                            || remainingMillis == periodInMillis // Case 1
+                    if (remainingMillis == periodInMillis // Case 1
                             || lastPollTimeAbsolute > nowAbsolute // Case 2
-                            || timeSinceLastRunMillis >= periodInMillis) { // Case 3
+                            || timeSinceLastRunMillis >= periodInMillis // Case 3
+                            || runEarly) { // Case 4
                         // Sync now
-                        
-                        final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(
-                                authorityInfo.account, authorityInfo.userId,
-                                authorityInfo.authority);
-                        final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
-                        syncAdapterInfo = mSyncAdapters.getServiceInfo(
-                                SyncAdapterType.newKey(
-                                        authorityInfo.authority, authorityInfo.account.type),
-                                authorityInfo.userId);
-                        if (syncAdapterInfo == null) {
-                            continue;
-                        }
+                        SyncStorageEngine.EndPoint target = authorityInfo.target;
+                        final Pair<Long, Long> backoff =
+                                mSyncStorageEngine.getBackoff(target);
                         mSyncStorageEngine.setPeriodicSyncTime(authorityInfo.ident,
                                 authorityInfo.periodicSyncs.get(i), nowAbsolute);
-                        scheduleSyncOperation(
-                                new SyncOperation(authorityInfo.account, authorityInfo.userId,
-                                        SyncOperation.REASON_PERIODIC,
-                                        SyncStorageEngine.SOURCE_PERIODIC,
-                                        authorityInfo.authority, extras,
-                                        0 /* runtime */, 0 /* flex */,
-                                                backoff != null ? backoff.first : 0,
-                                        mSyncStorageEngine.getDelayUntilTime(
-                                                authorityInfo.account, authorityInfo.userId,
-                                                authorityInfo.authority),
-                                        syncAdapterInfo.type.allowParallelSyncs()));
-                        
+
+                        if (target.target_provider) {
+                            final RegisteredServicesCache.ServiceInfo<SyncAdapterType>
+                                syncAdapterInfo = mSyncAdapters.getServiceInfo(
+                                    SyncAdapterType.newKey(
+                                            target.provider, target.account.type),
+                                    target.userId);
+                            if (syncAdapterInfo == null) {
+                                continue;
+                            }
+                            scheduleSyncOperation(
+                                    new SyncOperation(target.account, target.userId,
+                                            SyncOperation.REASON_PERIODIC,
+                                            SyncStorageEngine.SOURCE_PERIODIC,
+                                            target.provider, extras,
+                                            0 /* runtime */, 0 /* flex */,
+                                            backoff != null ? backoff.first : 0,
+                                            mSyncStorageEngine.getDelayUntilTime(target),
+                                            syncAdapterInfo.type.allowParallelSyncs()));
+                        } else if (target.target_service) {
+                            scheduleSyncOperation(
+                                    new SyncOperation(target.service, target.userId,
+                                            SyncOperation.REASON_PERIODIC,
+                                            SyncStorageEngine.SOURCE_PERIODIC,
+                                            extras,
+                                            0 /* runtime */,
+                                            0 /* flex */,
+                                            backoff != null ? backoff.first : 0,
+                                            mSyncStorageEngine.getDelayUntilTime(target)));
+                        }
                     }
                     // Compute when this periodic sync should next run.
                     long nextPollTimeAbsolute;
@@ -2154,8 +2293,7 @@
 
             // If the accounts aren't known yet then we aren't ready to run. We will be kicked
             // when the account lookup request does complete.
-            AccountAndUser[] accounts = mRunningAccounts;
-            if (accounts == INITIAL_ACCOUNTS_ARRAY) {
+            if (mRunningAccounts == INITIAL_ACCOUNTS_ARRAY) {
                 if (isLoggable) {
                     Log.v(TAG, "maybeStartNextSync: accounts not known, skipping");
                 }
@@ -2165,9 +2303,6 @@
             // Otherwise consume SyncOperations from the head of the SyncQueue until one is
             // found that is runnable (not disabled, etc). If that one is ready to run then
             // start it, otherwise just get out.
-            final boolean backgroundDataUsageAllowed =
-                    getConnectivityManager().getBackgroundDataSetting();
-
             final long now = SystemClock.elapsedRealtime();
 
             // will be set to the next time that a sync should be considered for running
@@ -2189,40 +2324,23 @@
                 while (operationIterator.hasNext()) {
                     final SyncOperation op = operationIterator.next();
 
-                    // Drop the sync if the account of this operation no longer exists.
-                    if (!containsAccountAndUser(accounts, op.account, op.userId)) {
-                        operationIterator.remove();
-                        mSyncStorageEngine.deleteFromPending(op.pendingOperation);
-                        if (isLoggable) {
-                            Log.v(TAG, "    Dropping sync operation: account doesn't exist.");
-                        }
-                        continue;
-                    }
-
-                    // Drop this sync request if it isn't syncable.
-                    int syncableState = getIsSyncable(
-                            op.account, op.userId, op.authority);
-                    if (syncableState == 0) {
-                        operationIterator.remove();
-                        mSyncStorageEngine.deleteFromPending(op.pendingOperation);
-                        if (isLoggable) {
-                            Log.v(TAG, "    Dropping sync operation: isSyncable == 0.");
-                        }
-                        continue;
-                    }
-
-                    // If the user is not running, drop the request.
-                    if (!activityManager.isUserRunning(op.userId)) {
-                        final UserInfo userInfo = mUserManager.getUserInfo(op.userId);
+                    // If the user is not running, skip the request.
+                    if (!activityManager.isUserRunning(op.target.userId)) {
+                        final UserInfo userInfo = mUserManager.getUserInfo(op.target.userId);
                         if (userInfo == null) {
-                            removedUsers.add(op.userId);
+                            removedUsers.add(op.target.userId);
                         }
                         if (isLoggable) {
-                            Log.v(TAG, "    Dropping sync operation: user not running.");
+                            Log.v(TAG, "    Dropping all sync operations for + "
+                                    + op.target.userId + ": user not running.");
                         }
                         continue;
                     }
-
+                    if (!isOperationValidLocked(op)) {
+                        operationIterator.remove();
+                        mSyncStorageEngine.deleteFromPending(op.pendingOperation);
+                        continue;
+                    }
                     // If the next run time is in the future, even given the flexible scheduling,
                     // return the time.
                     if (op.effectiveRunTime - op.flexTime > now) {
@@ -2230,51 +2348,16 @@
                             nextReadyToRunTime = op.effectiveRunTime;
                         }
                         if (isLoggable) {
-                            Log.v(TAG, "    Dropping sync operation: Sync too far in future.");
+                            Log.v(TAG, "    Not running sync operation: Sync too far in future."
+                                    + "effective: " + op.effectiveRunTime + " flex: " + op.flexTime
+                                    + " now: " + now);
                         }
                         continue;
                     }
-
-                    // If the op isn't allowed on metered networks and we're on one, drop it.
-                    if (getConnectivityManager().isActiveNetworkMetered()
-                            && op.isMeteredDisallowed()) {
-                        operationIterator.remove();
-                        mSyncStorageEngine.deleteFromPending(op.pendingOperation);
-                        continue;
-                    }
-
-                    // TODO: change this behaviour for non-registered syncs.
-                    final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
-                    syncAdapterInfo = mSyncAdapters.getServiceInfo(
-                            SyncAdapterType.newKey(op.authority, op.account.type), op.userId);
-
-                    // only proceed if network is connected for requesting UID
-                    final boolean uidNetworkConnected;
-                    if (syncAdapterInfo != null) {
-                        final NetworkInfo networkInfo = getConnectivityManager()
-                                .getActiveNetworkInfoForUid(syncAdapterInfo.uid);
-                        uidNetworkConnected = networkInfo != null && networkInfo.isConnected();
-                    } else {
-                        uidNetworkConnected = false;
-                    }
-
-                    // skip the sync if it isn't manual, and auto sync or
-                    // background data usage is disabled or network is
-                    // disconnected for the target UID.
-                    if (!op.extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
-                            && (syncableState > 0)
-                            && (!mSyncStorageEngine.getMasterSyncAutomatically(op.userId)
-                                || !backgroundDataUsageAllowed
-                                || !uidNetworkConnected
-                                || !mSyncStorageEngine.getSyncAutomatically(
-                                       op.account, op.userId, op.authority))) {
-                        operationIterator.remove();
-                        mSyncStorageEngine.deleteFromPending(op.pendingOperation);
-                        continue;
-                    }
-
+                    // Add this sync to be run.
                     operations.add(op);
                 }
+
                 for (Integer user : removedUsers) {
                     // if it's still removed
                     if (mUserManager.getUserInfo(user) == null) {
@@ -2316,13 +2399,9 @@
                             }
                         }
                     }
-                    if (activeOp.account.type.equals(candidate.account.type)
-                            && activeOp.authority.equals(candidate.authority)
-                            && activeOp.userId == candidate.userId
-                            && (!activeOp.allowParallelSyncs
-                                || activeOp.account.name.equals(candidate.account.name))) {
+                    if (activeOp.isConflict(candidate)) {
                         conflict = activeSyncContext;
-                        // don't break out since we want to do a full count of the varieties
+                        // don't break out since we want to do a full count of the varieties.
                     } else {
                         if (candidateIsInitialization == activeOp.isInitialization()
                                 && activeSyncContext.mStartTime + MAX_TIME_PER_SYNC < now) {
@@ -2372,8 +2451,8 @@
                     // is null. Reschedule the active sync and start the candidate.
                     toReschedule = oldestNonExpeditedRegular;
                     if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "canceling and rescheduling sync since an expedited is ready to run, "
-                                + oldestNonExpeditedRegular);
+                        Log.v(TAG, "canceling and rescheduling sync since an expedited is ready to"
+                                + " run, " + oldestNonExpeditedRegular);
                     }
                 } else if (longRunning != null
                         && (candidateIsInitialization
@@ -2402,7 +2481,114 @@
             }
 
             return nextReadyToRunTime;
-     }
+        }
+
+        /**
+         * Determine if a sync is no longer valid and should be dropped from the sync queue and its
+         * pending op deleted.
+         * @param op operation for which the sync is to be scheduled.
+         */
+        private boolean isOperationValidLocked(SyncOperation op) {
+            final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
+            int targetUid;
+            int state;
+            final SyncStorageEngine.EndPoint target = op.target;
+            boolean syncEnabled = mSyncStorageEngine.getMasterSyncAutomatically(target.userId);
+            if (target.target_provider) {
+                // Drop the sync if the account of this operation no longer exists.
+                AccountAndUser[] accounts = mRunningAccounts;
+                if (!containsAccountAndUser(accounts, target.account, target.userId)) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: account doesn't exist.");
+                    }
+                    return false;
+                }
+                // Drop this sync request if it isn't syncable.
+                state = getIsSyncable(target.account, target.userId, target.provider);
+                if (state == 0) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: isSyncable == 0.");
+                    }
+                    return false;
+                }
+                syncEnabled = syncEnabled && mSyncStorageEngine.getSyncAutomatically(
+                        target.account, target.userId, target.provider);
+
+                final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
+                syncAdapterInfo = mSyncAdapters.getServiceInfo(
+                        SyncAdapterType.newKey(
+                                target.provider, target.account.type), target.userId);
+                if (syncAdapterInfo != null) {
+                    targetUid = syncAdapterInfo.uid;
+                } else {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: No sync adapter registered"
+                                + "for: " + target);
+                    }
+                    return false;
+                }
+            } else if (target.target_service) {
+                state = mSyncStorageEngine.getIsTargetServiceActive(target.service, target.userId)
+                            ? 1 : 0;
+                if (state == 0) {
+                    // TODO: Change this to not drop disabled syncs - keep them in the pending queue.
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: isActive == 0.");
+                    }
+                    return false;
+                }
+                try {
+                    targetUid = mContext.getPackageManager()
+                            .getServiceInfo(target.service, 0)
+                            .applicationInfo
+                            .uid;
+                } catch (PackageManager.NameNotFoundException e) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: No service registered for: "
+                                + target.service);
+                    }
+                    return false;
+                }
+            } else {
+                Log.e(TAG, "Unknown target for Sync Op: " + target);
+                return false;
+            }
+
+            // We ignore system settings that specify the sync is invalid if:
+            // 1) It's manual - we try it anyway. When/if it fails it will be rescheduled.
+            //      or
+            // 2) it's an initialisation sync - we just need to connect to it.
+            final boolean ignoreSystemConfiguration =
+                    op.extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
+                    || (state < 0);
+
+            // Sync not enabled.
+            if (!syncEnabled && !ignoreSystemConfiguration) {
+                if (isLoggable) {
+                    Log.v(TAG, "    Dropping sync operation: disallowed by settings/network.");
+                }
+                return false;
+            }
+            // Network down.
+            final NetworkInfo networkInfo = getConnectivityManager()
+                    .getActiveNetworkInfoForUid(targetUid);
+            final boolean uidNetworkConnected = networkInfo != null && networkInfo.isConnected();
+            if (!uidNetworkConnected && !ignoreSystemConfiguration) {
+                if (isLoggable) {
+                    Log.v(TAG, "    Dropping sync operation: disallowed by settings/network.");
+                }
+                return false;
+            }
+            // Metered network.
+            if (op.isNotAllowedOnMetered() && getConnectivityManager().isActiveNetworkMetered()
+                    && !ignoreSystemConfiguration) {
+                if (isLoggable) {
+                    Log.v(TAG, "    Dropping sync operation: not allowed on metered network.");
+                }
+                return false;
+            }
+            return true;
+        }
 
         private boolean dispatchSyncOperation(SyncOperation op) {
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -2412,27 +2598,48 @@
                     Log.v(TAG, syncContext.toString());
                 }
             }
-
-            // connect to the sync adapter
-            SyncAdapterType syncAdapterType = SyncAdapterType.newKey(op.authority, op.account.type);
-            final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
-            syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, op.userId);
-            if (syncAdapterInfo == null) {
-                Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
-                        + ", removing settings for it");
-                mSyncStorageEngine.removeAuthority(op.account, op.userId, op.authority);
-                return false;
+            // Connect to the sync adapter.
+            int targetUid;
+            ComponentName targetComponent;
+            final SyncStorageEngine.EndPoint info = op.target;
+            if (info.target_provider) {
+                SyncAdapterType syncAdapterType =
+                        SyncAdapterType.newKey(info.provider, info.account.type);
+                final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
+                syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, info.userId);
+                if (syncAdapterInfo == null) {
+                    Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
+                            + ", removing settings for it");
+                    mSyncStorageEngine.removeAuthority(info);
+                    return false;
+                }
+                targetUid = syncAdapterInfo.uid;
+                targetComponent = syncAdapterInfo.componentName;
+            } else {
+                // TODO: Store the uid of the service as part of the authority info in order to
+                // avoid this call?
+                try {
+                    targetUid = mContext.getPackageManager()
+                            .getServiceInfo(info.service, 0)
+                            .applicationInfo
+                            .uid;
+                    targetComponent = info.service;
+                } catch(PackageManager.NameNotFoundException e) {
+                    Log.d(TAG, "Can't find a service for " + info.service
+                            + ", removing settings for it");
+                    mSyncStorageEngine.removeAuthority(info);
+                    return false;
+                }
             }
-
             ActiveSyncContext activeSyncContext =
-                    new ActiveSyncContext(op, insertStartSyncEvent(op), syncAdapterInfo.uid);
+                    new ActiveSyncContext(op, insertStartSyncEvent(op), targetUid);
             activeSyncContext.mSyncInfo = mSyncStorageEngine.addActiveSync(activeSyncContext);
             mActiveSyncContexts.add(activeSyncContext);
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "dispatchSyncOperation: starting " + activeSyncContext);
             }
-            if (!activeSyncContext.bindToSyncAdapter(syncAdapterInfo, op.userId)) {
-                Log.e(TAG, "Bind attempt failed to " + syncAdapterInfo);
+            if (!activeSyncContext.bindToSyncAdapter(targetComponent, info.userId)) {
+                Log.e(TAG, "Bind attempt failed - target: " + targetComponent);
                 closeActiveSyncContext(activeSyncContext);
                 return false;
             }
@@ -2440,47 +2647,54 @@
             return true;
         }
 
-        private void runBoundToSyncAdapter(final ActiveSyncContext activeSyncContext,
-              ISyncAdapter syncAdapter) {
-            activeSyncContext.mSyncAdapter = syncAdapter;
+        private void runBoundToAdapter(final ActiveSyncContext activeSyncContext,
+                IBinder syncAdapter) {
             final SyncOperation syncOperation = activeSyncContext.mSyncOperation;
             try {
                 activeSyncContext.mIsLinkedToDeath = true;
-                syncAdapter.asBinder().linkToDeath(activeSyncContext, 0);
+                syncAdapter.linkToDeath(activeSyncContext, 0);
 
-                syncAdapter.startSync(activeSyncContext, syncOperation.authority,
-                        syncOperation.account, syncOperation.extras);
+                if (syncOperation.target.target_provider) {
+                    activeSyncContext.mSyncAdapter = ISyncAdapter.Stub.asInterface(syncAdapter);
+                    activeSyncContext.mSyncAdapter
+                        .startSync(activeSyncContext, syncOperation.target.provider,
+                                syncOperation.target.account, syncOperation.extras);
+                } else if (syncOperation.target.target_service) {
+                    activeSyncContext.mSyncServiceAdapter =
+                            ISyncServiceAdapter.Stub.asInterface(syncAdapter);
+                    activeSyncContext.mSyncServiceAdapter
+                        .startSync(activeSyncContext, syncOperation.extras);
+                }
             } catch (RemoteException remoteExc) {
                 Log.d(TAG, "maybeStartNextSync: caught a RemoteException, rescheduling", remoteExc);
                 closeActiveSyncContext(activeSyncContext);
                 increaseBackoffSetting(syncOperation);
-                scheduleSyncOperation(new SyncOperation(syncOperation));
+                scheduleSyncOperation(
+                        new SyncOperation(syncOperation, 0L /* newRunTimeFromNow */));
             } catch (RuntimeException exc) {
                 closeActiveSyncContext(activeSyncContext);
                 Log.e(TAG, "Caught RuntimeException while starting the sync " + syncOperation, exc);
             }
         }
 
-        private void cancelActiveSyncLocked(Account account, int userId, String authority) {
+        /**
+         * Cancel the sync for the provided target that matches the given bundle.
+         * @param info can have null fields to indicate all the active syncs for that field.
+         */
+        private void cancelActiveSyncLocked(SyncStorageEngine.EndPoint info, Bundle extras) {
             ArrayList<ActiveSyncContext> activeSyncs =
                     new ArrayList<ActiveSyncContext>(mActiveSyncContexts);
             for (ActiveSyncContext activeSyncContext : activeSyncs) {
                 if (activeSyncContext != null) {
-                    // if an account was specified then only cancel the sync if it matches
-                    if (account != null) {
-                        if (!account.equals(activeSyncContext.mSyncOperation.account)) {
-                            continue;
-                        }
+                    final SyncStorageEngine.EndPoint opInfo =
+                            activeSyncContext.mSyncOperation.target;
+                    if (!opInfo.matchesSpec(info)) {
+                        continue;
                     }
-                    // if an authority was specified then only cancel the sync if it matches
-                    if (authority != null) {
-                        if (!authority.equals(activeSyncContext.mSyncOperation.authority)) {
-                            continue;
-                        }
-                    }
-                    // check if the userid matches
-                    if (userId != UserHandle.USER_ALL
-                            && userId != activeSyncContext.mSyncOperation.userId) {
+                    if (extras != null &&
+                            !syncExtrasEquals(activeSyncContext.mSyncOperation.extras,
+                                    extras,
+                                    false /* no config settings */)) {
                         continue;
                     }
                     runSyncFinishedOrCanceledLocked(null /* no result since this is a cancel */,
@@ -2493,16 +2707,20 @@
                 ActiveSyncContext activeSyncContext) {
             boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
 
+            final SyncOperation syncOperation = activeSyncContext.mSyncOperation;
+            final SyncStorageEngine.EndPoint info = syncOperation.target;
+
             if (activeSyncContext.mIsLinkedToDeath) {
-                activeSyncContext.mSyncAdapter.asBinder().unlinkToDeath(activeSyncContext, 0);
+                if (info.target_provider) {
+                    activeSyncContext.mSyncAdapter.asBinder().unlinkToDeath(activeSyncContext, 0);
+                } else {
+                    activeSyncContext.mSyncServiceAdapter.asBinder()
+                        .unlinkToDeath(activeSyncContext, 0);
+                }
                 activeSyncContext.mIsLinkedToDeath = false;
             }
             closeActiveSyncContext(activeSyncContext);
-
-            final SyncOperation syncOperation = activeSyncContext.mSyncOperation;
-
             final long elapsedTime = SystemClock.elapsedRealtime() - activeSyncContext.mStartTime;
-
             String historyMessage;
             int downstreamActivity;
             int upstreamActivity;
@@ -2544,6 +2762,12 @@
                     } catch (RemoteException e) {
                         // we don't need to retry this in this case
                     }
+                } else if (activeSyncContext.mSyncServiceAdapter != null) {
+                    try {
+                        activeSyncContext.mSyncServiceAdapter.cancelSync(activeSyncContext);
+                    } catch (RemoteException e) {
+                        // we don't need to retry this in this case
+                    }
                 }
                 historyMessage = SyncStorageEngine.MESG_CANCELED;
                 downstreamActivity = 0;
@@ -2553,24 +2777,35 @@
             stopSyncEvent(activeSyncContext.mHistoryRowId, syncOperation, historyMessage,
                     upstreamActivity, downstreamActivity, elapsedTime);
 
-            if (syncResult != null && syncResult.tooManyDeletions) {
-                installHandleTooManyDeletesNotification(syncOperation.account,
-                        syncOperation.authority, syncResult.stats.numDeletes,
-                        syncOperation.userId);
+            // Check for full-resync and schedule it after closing off the last sync.
+            if (info.target_provider) {
+                if (syncResult != null && syncResult.tooManyDeletions) {
+                    installHandleTooManyDeletesNotification(info.account,
+                            info.provider, syncResult.stats.numDeletes,
+                            info.userId);
+                } else {
+                    mNotificationMgr.cancelAsUser(null,
+                            info.account.hashCode() ^ info.provider.hashCode(),
+                            new UserHandle(info.userId));
+                }
+                if (syncResult != null && syncResult.fullSyncRequested) {
+                    scheduleSyncOperation(
+                            new SyncOperation(info.account, info.userId,
+                                syncOperation.reason,
+                                syncOperation.syncSource, info.provider, new Bundle(),
+                                0 /* delay */, 0 /* flex */,
+                                syncOperation.backoff, syncOperation.delayUntil,
+                                syncOperation.allowParallelSyncs));
+                }
             } else {
-                mNotificationMgr.cancelAsUser(null,
-                        syncOperation.account.hashCode() ^ syncOperation.authority.hashCode(),
-                        new UserHandle(syncOperation.userId));
-            }
-
-            if (syncResult != null && syncResult.fullSyncRequested) {
-                scheduleSyncOperation(
-                        new SyncOperation(syncOperation.account, syncOperation.userId,
-                            syncOperation.reason,
-                            syncOperation.syncSource, syncOperation.authority, new Bundle(),
-                            0 /* delay */, 0 /* flex */,
-                            syncOperation.backoff, syncOperation.delayUntil,
-                            syncOperation.allowParallelSyncs));
+                if (syncResult != null && syncResult.fullSyncRequested) {
+                    scheduleSyncOperation(
+                            new SyncOperation(info.service, info.userId,
+                                syncOperation.reason,
+                                syncOperation.syncSource, new Bundle(),
+                                0 /* delay */, 0 /* flex */,
+                                syncOperation.backoff, syncOperation.delayUntil));
+                }
             }
             // no need to schedule an alarm, as that will be done by our caller.
         }
@@ -2579,7 +2814,7 @@
             activeSyncContext.close();
             mActiveSyncContexts.remove(activeSyncContext);
             mSyncStorageEngine.removeActiveSync(activeSyncContext.mSyncInfo,
-                    activeSyncContext.mSyncOperation.userId);
+                    activeSyncContext.mSyncOperation.target.userId);
         }
 
         /**
@@ -2842,26 +3077,16 @@
         }
 
         public long insertStartSyncEvent(SyncOperation syncOperation) {
-            final int source = syncOperation.syncSource;
             final long now = System.currentTimeMillis();
-
-            EventLog.writeEvent(2720, syncOperation.authority,
-                                SyncStorageEngine.EVENT_START, source,
-                                syncOperation.account.name.hashCode());
-
-            return mSyncStorageEngine.insertStartSyncEvent(
-                    syncOperation.account, syncOperation.userId, syncOperation.reason,
-                    syncOperation.authority,
-                    now, source, syncOperation.isInitialization(), syncOperation.extras
-            );
+            EventLog.writeEvent(2720,
+                    syncOperation.toEventLog(SyncStorageEngine.EVENT_START));
+            return mSyncStorageEngine.insertStartSyncEvent(syncOperation, now);
         }
 
         public void stopSyncEvent(long rowId, SyncOperation syncOperation, String resultMessage,
                 int upstreamActivity, int downstreamActivity, long elapsedTime) {
-            EventLog.writeEvent(2720, syncOperation.authority,
-                                SyncStorageEngine.EVENT_STOP, syncOperation.syncSource,
-                                syncOperation.account.name.hashCode());
-
+            EventLog.writeEvent(2720,
+                    syncOperation.toEventLog(SyncStorageEngine.EVENT_STOP));
             mSyncStorageEngine.stopSyncEvent(rowId, elapsedTime,
                     resultMessage, downstreamActivity, upstreamActivity);
         }
@@ -2876,6 +3101,83 @@
         return false;
     }
 
+    /**
+     * Sync extra comparison function.
+     * @param b1 bundle to compare
+     * @param b2 other bundle to compare
+     * @param includeSyncSettings if false, ignore system settings in bundle.
+     */
+    public static boolean syncExtrasEquals(Bundle b1, Bundle b2, boolean includeSyncSettings) {
+        if (b1 == b2) {
+            return true;
+        }
+        // Exit early if we can.
+        if (includeSyncSettings && b1.size() != b2.size()) {
+            return false;
+        }
+        Bundle bigger = b1.size() > b2.size() ? b1 : b2;
+        Bundle smaller = b1.size() > b2.size() ? b2 : b1;
+        for (String key : bigger.keySet()) {
+            if (!includeSyncSettings && isSyncSetting(key)) {
+                continue;
+            }
+            if (!smaller.containsKey(key)) {
+                return false;
+            }
+            if (!bigger.get(key).equals(smaller.get(key))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * TODO: Get rid of this when we separate sync settings extras from dev specified extras.
+     * @return true if the provided key is used by the SyncManager in scheduling the sync.
+     */
+    private static boolean isSyncSetting(String key) {
+        if (key.equals(ContentResolver.SYNC_EXTRAS_EXPEDITED)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_MANUAL)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_UPLOAD)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_PRIORITY)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_INITIALIZE)) {
+            return true;
+        }
+        return false;
+    }
+
     static class PrintTable {
         private ArrayList<Object[]> mTable = Lists.newArrayList();
         private final int mCols;
diff --git a/services/java/com/android/server/content/SyncOperation.java b/services/java/com/android/server/content/SyncOperation.java
index 48567478..036b21f 100644
--- a/services/java/com/android/server/content/SyncOperation.java
+++ b/services/java/com/android/server/content/SyncOperation.java
@@ -20,10 +20,9 @@
 import android.content.pm.PackageManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
-import android.content.SyncRequest;
 import android.os.Bundle;
 import android.os.SystemClock;
-import android.util.Pair;
+import android.util.Log;
 
 /**
  * Value type that represents a sync operation.
@@ -32,10 +31,13 @@
  * {@hide}
  */
 public class SyncOperation implements Comparable {
+    public static final String TAG = "SyncManager";
+
     public static final int REASON_BACKGROUND_DATA_SETTINGS_CHANGED = -1;
     public static final int REASON_ACCOUNTS_UPDATED = -2;
     public static final int REASON_SERVICE_CHANGED = -3;
     public static final int REASON_PERIODIC = -4;
+    /** Sync started because it has just been set to isSyncable. */
     public static final int REASON_IS_SYNCABLE = -5;
     /** Sync started because it has just been set to sync automatically. */
     public static final int REASON_SYNC_AUTO = -6;
@@ -54,19 +56,21 @@
             "UserStart",
     };
 
-    /** Account info to identify a SyncAdapter registered with the system. */
-    public final Account account;
-    /** Authority info to identify a SyncAdapter registered with the system. */
-    public final String authority;
-    /** Service to which this operation will bind to perform the sync. */
-    public final ComponentName service;
-    public final int userId;
+    public static final int SYNC_TARGET_UNKNOWN = 0;
+    public static final int SYNC_TARGET_ADAPTER = 1;
+    public static final int SYNC_TARGET_SERVICE = 2;
+
+    /** Identifying info for the target for this operation. */
+    public final SyncStorageEngine.EndPoint target;
+    /** Why this sync was kicked off. {@link #REASON_NAMES} */
     public final int reason;
+    /** Where this sync was initiated. */
     public int syncSource;
     public final boolean allowParallelSyncs;
     public Bundle extras;
     public final String key;
     public boolean expedited;
+    /** Bare-bones version of this operation that is persisted across reboots. */
     public SyncStorageEngine.PendingOperation pendingOperation;
     /** Elapsed real time in millis at which to run this sync. */
     public long latestRunTime;
@@ -79,25 +83,56 @@
      * Depends on max(backoff, latestRunTime, and delayUntil).
      */
     public long effectiveRunTime;
-    /** Amount of time before {@link effectiveRunTime} from which this sync can run. */
+    /** Amount of time before {@link #effectiveRunTime} from which this sync can run. */
     public long flexTime;
 
-    public SyncOperation(Account account, int userId, int reason, int source, String authority,
+    public SyncOperation(Account account, int userId, int reason, int source, String provider,
             Bundle extras, long runTimeFromNow, long flexTime, long backoff,
             long delayUntil, boolean allowParallelSyncs) {
-        this.service = null;
-        this.account = account;
-        this.authority = authority;
-        this.userId = userId;
+        this.target = new SyncStorageEngine.EndPoint(account, provider, userId);
         this.reason = reason;
-        this.syncSource = source;
         this.allowParallelSyncs = allowParallelSyncs;
+        this.key = initialiseOperation(this.target, source, extras, runTimeFromNow, flexTime,
+                backoff, delayUntil);
+    }
+
+    public SyncOperation(ComponentName service, int userId, int reason, int source,
+            Bundle extras, long runTimeFromNow, long flexTime, long backoff,
+            long delayUntil) {
+        this.target = new SyncStorageEngine.EndPoint(service, userId);
+        // Default to true for sync service. The service itself decides how to handle this.
+        this.allowParallelSyncs = true;
+        this.reason = reason;
+        this.key =
+                initialiseOperation(this.target,
+                        source, extras, runTimeFromNow, flexTime, backoff, delayUntil);
+    }
+
+    /** Used to reschedule a sync at a new point in time. */
+    SyncOperation(SyncOperation other, long newRunTimeFromNow) {
+        this.target = other.target;
+        this.reason = other.reason;
+        this.expedited = other.expedited;
+        this.allowParallelSyncs = other.allowParallelSyncs;
+        // re-use old flex, but only 
+        long newFlexTime = Math.min(other.flexTime, newRunTimeFromNow);
+        this.key =
+                initialiseOperation(this.target,
+                    other.syncSource, other.extras,
+                    newRunTimeFromNow /* runTimeFromNow*/,
+                    newFlexTime /* flexTime */,
+                    other.backoff,
+                    0L /* delayUntil */);
+    }
+
+    private String initialiseOperation(SyncStorageEngine.EndPoint info, int source, Bundle extras,
+            long runTimeFromNow, long flexTime, long backoff, long delayUntil) {
+        this.syncSource = source;
         this.extras = new Bundle(extras);
         cleanBundle(this.extras);
         this.delayUntil = delayUntil;
         this.backoff = backoff;
         final long now = SystemClock.elapsedRealtime();
-        // Checks the extras bundle. Must occur after we set the internal bundle.
         if (runTimeFromNow < 0 || isExpedited()) {
             this.expedited = true;
             this.latestRunTime = now;
@@ -108,7 +143,11 @@
             this.flexTime = flexTime;
         }
         updateEffectiveRunTime();
-        this.key = toKey();
+        return toKey(info, this.extras);
+    }
+
+    public boolean matchesAuthority(SyncOperation other) {
+        return this.target.matchesSpec(other.target);
     }
 
     /**
@@ -126,10 +165,6 @@
         removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_EXPEDITED);
         removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS);
         removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DISALLOW_METERED);
-
-        // Remove Config data.
-        bundle.remove(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD);
-        bundle.remove(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD);
     }
 
     private void removeFalseExtra(Bundle bundle, String extraName) {
@@ -138,22 +173,24 @@
         }
     }
 
-    /** Only used to immediately reschedule a sync. */
-    SyncOperation(SyncOperation other) {
-        this.service = other.service;
-        this.account = other.account;
-        this.authority = other.authority;
-        this.userId = other.userId;
-        this.reason = other.reason;
-        this.syncSource = other.syncSource;
-        this.extras = new Bundle(other.extras);
-        this.expedited = other.expedited;
-        this.latestRunTime = SystemClock.elapsedRealtime();
-        this.flexTime = 0L;
-        this.backoff = other.backoff;
-        this.allowParallelSyncs = other.allowParallelSyncs;
-        this.updateEffectiveRunTime();
-        this.key = toKey();
+    /**
+     * Determine whether if this sync operation is running, the provided operation would conflict
+     * with it.
+     * Parallel syncs allow multiple accounts to be synced at the same time. 
+     */
+    public boolean isConflict(SyncOperation toRun) {
+        final SyncStorageEngine.EndPoint other = toRun.target;
+        if (target.target_provider) {
+            return target.account.type.equals(other.account.type)
+                    && target.provider.equals(other.provider)
+                    && target.userId == other.userId
+                    && (!allowParallelSyncs
+                            || target.account.name.equals(other.account.name));
+        } else {
+            // Ops that target a service default to allow parallel syncs, which is handled by the
+            // service returning SYNC_IN_PROGRESS if they don't.
+            return target.service.equals(other.service) && !allowParallelSyncs;
+        }
     }
 
     @Override
@@ -162,18 +199,26 @@
     }
 
     public String dump(PackageManager pm, boolean useOneLine) {
-        StringBuilder sb = new StringBuilder()
-                .append(account.name)
+        StringBuilder sb = new StringBuilder();
+        if (target.target_provider) {
+            sb.append(target.account.name)
                 .append(" u")
-                .append(userId).append(" (")
-                .append(account.type)
+                .append(target.userId).append(" (")
+                .append(target.account.type)
                 .append(")")
                 .append(", ")
-                .append(authority)
-                .append(", ")
-                .append(SyncStorageEngine.SOURCES[syncSource])
-                .append(", latestRunTime ")
-                .append(latestRunTime);
+                .append(target.provider)
+                .append(", ");
+        } else if (target.target_service) {
+            sb.append(target.service.getPackageName())
+                .append(" u")
+                .append(target.userId).append(" (")
+                .append(target.service.getClassName()).append(")")
+                .append(", ");
+        }
+        sb.append(SyncStorageEngine.SOURCES[syncSource])
+            .append(", currentRunTime ")
+            .append(effectiveRunTime);
         if (expedited) {
             sb.append(", EXPEDITED");
         }
@@ -211,10 +256,6 @@
         }
     }
 
-    public boolean isMeteredDisallowed() {
-        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false);
-    }
-
     public boolean isInitialization() {
         return extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false);
     }
@@ -227,28 +268,39 @@
         return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false);
     }
 
+    public boolean isNotAllowedOnMetered() {
+        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false);
+    }
+
     /** Changed in V3. */
-    private String toKey() {
+    public static String toKey(SyncStorageEngine.EndPoint info, Bundle extras) {
         StringBuilder sb = new StringBuilder();
-        if (service == null) {
-            sb.append("authority: ").append(authority);
-            sb.append(" account {name=" + account.name + ", user=" + userId + ", type=" + account.type
+        if (info.target_provider) {
+            sb.append("provider: ").append(info.provider);
+            sb.append(" account {name=" + info.account.name
+                    + ", user="
+                    + info.userId
+                    + ", type="
+                    + info.account.type
                     + "}");
-        } else {
+        } else if (info.target_service) {
             sb.append("service {package=" )
-                .append(service.getPackageName())
+                .append(info.service.getPackageName())
                 .append(" user=")
-                .append(userId)
+                .append(info.userId)
                 .append(", class=")
-                .append(service.getClassName())
+                .append(info.service.getClassName())
                 .append("}");
+        } else {
+            Log.v(TAG, "Converting SyncOperaton to key, invalid target: " + info.toString());
+            return "";
         }
         sb.append(" extras: ");
         extrasToStringBuilder(extras, sb);
         return sb.toString();
     }
 
-    public static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
+    private static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
         sb.append("[");
         for (String key : bundle.keySet()) {
             sb.append(key).append("=").append(bundle.get(key)).append(" ");
@@ -256,6 +308,31 @@
         sb.append("]");
     }
 
+    public String wakeLockKey() {
+        if (target.target_provider) {
+            return target.account.name + "/" + target.account.type + ":" + target.provider;
+        } else if (target.target_service) {
+            return target.service.getPackageName() + "/" + target.service.getClassName();
+        } else {
+            Log.wtf(TAG, "Invalid target getting wakelock for operation - " + key);
+            return null;
+        }
+    }
+
+    public String wakeLockName() {
+        if (target.target_provider) {
+            return "/" + target.provider
+                    + "/" + target.account.type
+                    + "/" + target.account.name;
+        } else if (target.target_service) {
+            return "/" + target.service.getPackageName()
+                    + "/" + target.service.getClassName();
+        } else {
+            Log.wtf(TAG, "Invalid target getting wakelock name for operation - " + key);
+            return null;
+        }
+    }
+
     /**
      * Update the effective run time of this Operation based on latestRunTime (specified at
      * creation time of sync), delayUntil (specified by SyncAdapter), or backoff (specified by
@@ -291,4 +368,21 @@
             return 0;
         }
     }
+
+    // TODO: Test this to make sure that casting to object doesn't lose the type info for EventLog.
+    public Object[] toEventLog(int event) {
+        Object[] logArray = new Object[4];
+        logArray[1] = event;
+        logArray[2] = syncSource;
+        if (target.target_provider) {
+            logArray[0] = target.provider;
+            logArray[3] = target.account.name.hashCode();
+        } else if (target.target_service) {
+            logArray[0] = target.service.getPackageName();
+            logArray[3] = target.service.hashCode();
+        } else {
+            Log.wtf(TAG, "sync op with invalid target: " + key);
+        }
+        return logArray;
+    }
 }
diff --git a/services/java/com/android/server/content/SyncQueue.java b/services/java/com/android/server/content/SyncQueue.java
index 6f3fe6e..5d93882 100644
--- a/services/java/com/android/server/content/SyncQueue.java
+++ b/services/java/com/android/server/content/SyncQueue.java
@@ -16,12 +16,11 @@
 
 package com.android.server.content;
 
-import android.accounts.Account;
 import android.content.pm.PackageManager;
-import android.content.pm.RegisteredServicesCache;
 import android.content.SyncAdapterType;
 import android.content.SyncAdaptersCache;
 import android.content.pm.RegisteredServicesCache.ServiceInfo;
+import android.os.Bundle;
 import android.os.SystemClock;
 import android.text.format.DateUtils;
 import android.util.Log;
@@ -60,25 +59,51 @@
 
     public void addPendingOperations(int userId) {
         for (SyncStorageEngine.PendingOperation op : mSyncStorageEngine.getPendingOperations()) {
-            if (op.userId != userId) continue;
+            final SyncStorageEngine.EndPoint info = op.target;
+            if (info.userId != userId) continue;
 
-            final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(
-                    op.account, op.userId, op.authority);
-            final ServiceInfo<SyncAdapterType> syncAdapterInfo = mSyncAdapters.getServiceInfo(
-                    SyncAdapterType.newKey(op.authority, op.account.type), op.userId);
-            if (syncAdapterInfo == null) {
-                Log.w(TAG, "Missing sync adapter info for authority " + op.authority + ", userId "
-                        + op.userId);
-                continue;
+            final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(info);
+            SyncOperation operationToAdd;
+            if (info.target_provider) {
+                final ServiceInfo<SyncAdapterType> syncAdapterInfo = mSyncAdapters.getServiceInfo(
+                        SyncAdapterType.newKey(info.provider, info.account.type), info.userId);
+                if (syncAdapterInfo == null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, "Missing sync adapter info for authority " + op.target);
+                    }
+                    continue;
+                }
+                operationToAdd = new SyncOperation(
+                        info.account, info.userId, op.reason, op.syncSource, info.provider,
+                        op.extras,
+                        0 /* delay */,
+                        0 /* flex */,
+                        backoff != null ? backoff.first : 0,
+                        mSyncStorageEngine.getDelayUntilTime(info),
+                        syncAdapterInfo.type.allowParallelSyncs());
+                operationToAdd.expedited = op.expedited;
+                operationToAdd.pendingOperation = op;
+                add(operationToAdd, op);
+            } else if (info.target_service) {
+                try {
+                    mPackageManager.getServiceInfo(info.service, 0);
+                } catch (PackageManager.NameNotFoundException e) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.w(TAG, "Missing sync service for authority " + op.target);
+                    }
+                    continue;
+                }
+                operationToAdd = new SyncOperation(
+                        info.service, info.userId, op.reason, op.syncSource,
+                        op.extras,
+                        0 /* delay */,
+                        0 /* flex */,
+                        backoff != null ? backoff.first : 0,
+                        mSyncStorageEngine.getDelayUntilTime(info));
+                operationToAdd.expedited = op.expedited;
+                operationToAdd.pendingOperation = op;
+                add(operationToAdd, op);
             }
-            SyncOperation syncOperation = new SyncOperation(
-                    op.account, op.userId, op.reason, op.syncSource, op.authority, op.extras,
-                    0 /* delay */, 0 /* flex */, backoff != null ? backoff.first : 0,
-                    mSyncStorageEngine.getDelayUntilTime(op.account, op.userId, op.authority),
-                    syncAdapterInfo.type.allowParallelSyncs());
-            syncOperation.expedited = op.expedited;
-            syncOperation.pendingOperation = op;
-            add(syncOperation, op);
         }
     }
 
@@ -119,12 +144,8 @@
         operation.pendingOperation = pop;
         // Don't update the PendingOp if one already exists. This really is just a placeholder,
         // no actual scheduling info is placed here.
-        // TODO: Change this to support service components.
         if (operation.pendingOperation == null) {
-            pop = new SyncStorageEngine.PendingOperation(
-                    operation.account, operation.userId, operation.reason, operation.syncSource,
-                    operation.authority, operation.extras, operation.expedited);
-            pop = mSyncStorageEngine.insertIntoPending(pop);
+            pop = mSyncStorageEngine.insertIntoPending(operation);
             if (pop == null) {
                 throw new IllegalStateException("error adding pending sync operation "
                         + operation);
@@ -136,17 +157,16 @@
         return true;
     }
 
-    public void removeUser(int userId) {
+    public void removeUserLocked(int userId) {
         ArrayList<SyncOperation> opsToRemove = new ArrayList<SyncOperation>();
         for (SyncOperation op : mOperationsMap.values()) {
-            if (op.userId == userId) {
+            if (op.target.userId == userId) {
                 opsToRemove.add(op);
             }
         }
-
-        for (SyncOperation op : opsToRemove) {
-            remove(op);
-        }
+            for (SyncOperation op : opsToRemove) {
+                remove(op);
+            }
     }
 
     /**
@@ -154,8 +174,15 @@
      * @param operation the operation to remove
      */
     public void remove(SyncOperation operation) {
+        boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
         SyncOperation operationToRemove = mOperationsMap.remove(operation.key);
+        if (isLoggable) {
+            Log.v(TAG, "Attempting to remove: " + operation.key);
+        }
         if (operationToRemove == null) {
+            if (isLoggable) {
+                Log.v(TAG, "Could not find: " + operation.key);
+            }
             return;
         }
         if (!mSyncStorageEngine.deleteFromPending(operationToRemove.pendingOperation)) {
@@ -164,41 +191,58 @@
         }
     }
 
-    public void onBackoffChanged(Account account, int userId, String providerName, long backoff) {
-        // for each op that matches the account and provider update its
+    /** Reset backoffs for all operations in the queue. */
+    public void clearBackoffs() {
+        for (SyncOperation op : mOperationsMap.values()) {
+            op.backoff = 0L;
+            op.updateEffectiveRunTime();
+        }
+    }
+
+    public void onBackoffChanged(SyncStorageEngine.EndPoint target, long backoff) {
+        // For each op that matches the target of the changed op, update its
         // backoff and effectiveStartTime
         for (SyncOperation op : mOperationsMap.values()) {
-            if (op.account.equals(account) && op.authority.equals(providerName)
-                    && op.userId == userId) {
+            if (op.target.matchesSpec(target)) {
                 op.backoff = backoff;
                 op.updateEffectiveRunTime();
             }
         }
     }
 
-    public void onDelayUntilTimeChanged(Account account, String providerName, long delayUntil) {
-        // for each op that matches the account and provider update its
-        // delayUntilTime and effectiveStartTime
+    public void onDelayUntilTimeChanged(SyncStorageEngine.EndPoint target, long delayUntil) {
+        // for each op that matches the target info of the provided op, change the delay time.
         for (SyncOperation op : mOperationsMap.values()) {
-            if (op.account.equals(account) && op.authority.equals(providerName)) {
+            if (op.target.matchesSpec(target)) {
                 op.delayUntil = delayUntil;
                 op.updateEffectiveRunTime();
             }
         }
     }
 
-    public void remove(Account account, int userId, String authority) {
+    /**
+     * Remove all of the SyncOperations associated with a given target.
+     *
+     * @param info target object provided here can have null Account/provider. This is the case
+     * where you want to remove all ops associated with a provider (null Account) or all ops
+     * associated with an account (null provider).
+     * @param extras option bundle to include to further specify which operation to remove. If this
+     * bundle contains sync settings flags, they are ignored.
+     */
+    public void remove(final SyncStorageEngine.EndPoint info, Bundle extras) {
         Iterator<Map.Entry<String, SyncOperation>> entries = mOperationsMap.entrySet().iterator();
         while (entries.hasNext()) {
             Map.Entry<String, SyncOperation> entry = entries.next();
             SyncOperation syncOperation = entry.getValue();
-            if (account != null && !syncOperation.account.equals(account)) {
+            final SyncStorageEngine.EndPoint opInfo = syncOperation.target;
+            if (!opInfo.matchesSpec(info)) {
                 continue;
             }
-            if (authority != null && !syncOperation.authority.equals(authority)) {
-                continue;
-            }
-            if (userId != syncOperation.userId) {
+            if (extras != null
+                    && !SyncManager.syncExtrasEquals(
+                        syncOperation.extras,
+                        extras,
+                        false /* no config flags*/)) {
                 continue;
             }
             entries.remove();
diff --git a/services/java/com/android/server/content/SyncStorageEngine.java b/services/java/com/android/server/content/SyncStorageEngine.java
index 5ebf9ea..10f0ea7 100644
--- a/services/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/java/com/android/server/content/SyncStorageEngine.java
@@ -24,6 +24,7 @@
 import android.content.ISyncStatusObserver;
 import android.content.PeriodicSync;
 import android.content.SyncInfo;
+import android.content.SyncRequest;
 import android.content.SyncStatusInfo;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
@@ -36,10 +37,12 @@
 import android.os.Parcel;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.AtomicFile;
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
+import android.util.ArrayMap;
 import android.util.Xml;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -71,7 +74,6 @@
 public class SyncStorageEngine extends Handler {
 
     private static final String TAG = "SyncManager";
-    private static final boolean DEBUG = false;
     private static final String TAG_FILE = "SyncManagerFile";
 
     private static final String XML_ATTR_NEXT_AUTHORITY_ID = "nextAuthorityId";
@@ -108,10 +110,7 @@
 
     /** Enum value for a local-initiated sync. */
     public static final int SOURCE_LOCAL = 1;
-    /**
-     * Enum value for a poll-based sync (e.g., upon connection to
-     * network)
-     */
+    /** Enum value for a poll-based sync (e.g., upon connection to network) */
     public static final int SOURCE_POLL = 2;
 
     /** Enum value for a user-initiated sync. */
@@ -119,6 +118,9 @@
 
     /** Enum value for a periodic sync. */
     public static final int SOURCE_PERIODIC = 4;
+    
+    /** Enum value for a sync started for a service. */
+    public static final int SOURCE_SERVICE = 5;
 
     public static final long NOT_IN_BACKOFF_MODE = -1;
 
@@ -128,7 +130,8 @@
                                              "LOCAL",
                                              "POLL",
                                              "USER",
-                                             "PERIODIC" };
+                                             "PERIODIC",
+                                             "SERVICE"};
 
     // The MESG column will contain one of these or one of the Error types.
     public static final String MESG_SUCCESS = "success";
@@ -156,41 +159,54 @@
     }
 
     public static class PendingOperation {
-        final Account account;
-        final int userId;
+        final EndPoint target;
         final int reason;
         final int syncSource;
-        final String authority;
         final Bundle extras;        // note: read-only.
-        final ComponentName serviceName;
         final boolean expedited;
 
-        int authorityId;
+        final int authorityId;
+        // No longer used.
+        // Keep around for sake up updating from pending.bin to pending.xml
         byte[] flatExtras;
 
-        PendingOperation(Account account, int userId, int reason, int source,
-                String authority, Bundle extras, boolean expedited) {
-            this.account = account;
-            this.userId = userId;
+        PendingOperation(AuthorityInfo authority, int reason, int source,
+                 Bundle extras, boolean expedited) {
+            this.target = authority.target;
             this.syncSource = source;
             this.reason = reason;
-            this.authority = authority;
             this.extras = extras != null ? new Bundle(extras) : extras;
             this.expedited = expedited;
-            this.authorityId = -1;
-            this.serviceName = null;
+            this.authorityId = authority.ident;
         }
 
         PendingOperation(PendingOperation other) {
-            this.account = other.account;
-            this.userId = other.userId;
             this.reason = other.reason;
             this.syncSource = other.syncSource;
-            this.authority = other.authority;
+            this.target = other.target;
             this.extras = other.extras;
             this.authorityId = other.authorityId;
             this.expedited = other.expedited;
-            this.serviceName = other.serviceName;
+        }
+
+        /**
+         * Considered equal if they target the same sync adapter (A
+         * {@link android.content.SyncService}
+         * is considered an adapter), for the same userId.
+         * @param other PendingOperation to compare.
+         * @return true if the two pending ops are the same.
+         */
+        public boolean equals(PendingOperation other) {
+            return target.matchesSpec(other.target);
+        }
+
+        public String toString() {
+            return "service=" + target.service
+                        + " user=" + target.userId
+                        + " auth=" + target
+                        + " account=" + target.account
+                        + " src=" + syncSource
+                        + " extras=" + extras;
         }
     }
 
@@ -204,17 +220,96 @@
         }
     }
 
-    public static class AuthorityInfo {
+    /**  Bare bones representation of a sync target. */
+    public static class EndPoint {
+        public final static EndPoint USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL =
+                new EndPoint(null, null, UserHandle.USER_ALL);
         final ComponentName service;
         final Account account;
         final int userId;
-        final String authority;
+        final String provider;
+        final boolean target_service;
+        final boolean target_provider;
+
+        public EndPoint(ComponentName service, int userId) {
+            this.service = service;
+            this.userId = userId;
+            this.account = null;
+            this.provider = null;
+            this.target_service = true;
+            this.target_provider = false;
+        }
+
+        public EndPoint(Account account, String provider, int userId) {
+            this.account = account;
+            this.provider = provider;
+            this.userId = userId;
+            this.service = null;
+            this.target_service = false;
+            this.target_provider = true;
+        }
+
+        /**
+         * An Endpoint for a sync matches if it targets the same sync adapter for the same user.
+         *
+         * @param spec the Endpoint to match. If the spec has null fields, they indicate a wildcard
+         * and match any. 
+         */
+        public boolean matchesSpec(EndPoint spec) {
+            if (userId != spec.userId
+                    && userId != UserHandle.USER_ALL
+                    && spec.userId != UserHandle.USER_ALL) {
+                return false;
+            }
+            if (target_service && spec.target_service) {
+                return service.equals(spec.service);
+            } else if (target_provider && spec.target_provider) {
+                boolean accountsMatch;
+                if (spec.account == null) {
+                    accountsMatch = true;
+                } else {
+                    accountsMatch = account.equals(spec.account);
+                }
+                boolean providersMatch;
+                if (spec.provider == null) {
+                    providersMatch = true;
+                } else {
+                    providersMatch = provider.equals(spec.provider);
+                }
+                return accountsMatch && providersMatch;
+            }
+            return false;
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            if (target_provider) {
+                sb.append(account == null ? "ALL ACCS" : account.name)
+                    .append("/")
+                    .append(provider == null ? "ALL PDRS" : provider);
+            } else if (target_service) {
+                sb.append(service.getPackageName() + "/")
+                  .append(service.getClassName());
+            } else {
+                sb.append("invalid target");
+            }
+            sb.append(":u" + userId);
+            return sb.toString();
+        }
+    }
+
+    public static class AuthorityInfo {
+        final EndPoint target;
         final int ident;
         boolean enabled;
         int syncable;
+        /** Time at which this sync will run, taking into account backoff. */
         long backoffTime;
+        /** Amount of delay due to backoff. */
         long backoffDelay;
+        /** Time offset to add to any requests coming to this target. */
         long delayUntil;
+
         final ArrayList<PeriodicSync> periodicSyncs;
 
         /**
@@ -224,10 +319,7 @@
          * @param toCopy AuthorityInfo to be copied.
          */
         AuthorityInfo(AuthorityInfo toCopy) {
-            account = toCopy.account;
-            userId = toCopy.userId;
-            authority = toCopy.authority;
-            service = toCopy.service;
+            target = toCopy.target;
             ident = toCopy.ident;
             enabled = toCopy.enabled;
             syncable = toCopy.syncable;
@@ -241,56 +333,40 @@
             }
         }
 
-        /**
-         * Create an authority with one periodic sync scheduled with an empty bundle and syncing
-         * every day. An empty bundle is considered equal to any other bundle see
-         * {@link PeriodicSync.syncExtrasEquals}.
-         * @param account Account that this authority syncs.
-         * @param userId which user this sync is registered for.
-         * @param userId user for which this authority is registered.
-         * @param ident id of this authority.
-         */
-        AuthorityInfo(Account account, int userId, String authority, int ident) {
-            this.account = account;
-            this.userId = userId;
-            this.authority = authority;
-            this.service = null;
-            this.ident = ident;
-            enabled = SYNC_ENABLED_DEFAULT;
-            syncable = -1; // default to "unknown"
-            backoffTime = -1; // if < 0 then we aren't in backoff mode
-            backoffDelay = -1; // if < 0 then we aren't in backoff mode
+        AuthorityInfo(EndPoint info, int id) {
+            target = info;
+            ident = id;
+            enabled = info.target_provider ?
+                    SYNC_ENABLED_DEFAULT : true;
+            // Service is active by default,
+            if (info.target_service) {
+                this.syncable = 1;
+            }
             periodicSyncs = new ArrayList<PeriodicSync>();
-            // Old version adds one periodic sync a day.
-            periodicSyncs.add(new PeriodicSync(account, authority,
-                                new Bundle(),
-                                DEFAULT_POLL_FREQUENCY_SECONDS,
-                                calculateDefaultFlexTime(DEFAULT_POLL_FREQUENCY_SECONDS)));
+            defaultInitialisation();
         }
 
-        /**
-         * Create an authority with one periodic sync scheduled with an empty bundle and syncing
-         * every day using a sync service.
-         * @param cname sync service identifier.
-         * @param userId user for which this authority is registered.
-         * @param ident id of this authority.
-         */
-        AuthorityInfo(ComponentName cname, int userId, int ident) {
-            this.account = null;
-            this.userId = userId;
-            this.authority = null;
-            this.service = cname;
-            this.ident = ident;
-            // Sync service is always enabled.
-            enabled = true;
+        private void defaultInitialisation() {
             syncable = -1; // default to "unknown"
             backoffTime = -1; // if < 0 then we aren't in backoff mode
             backoffDelay = -1; // if < 0 then we aren't in backoff mode
-            periodicSyncs = new ArrayList<PeriodicSync>();
-            periodicSyncs.add(new PeriodicSync(account, authority,
-                                new Bundle(),
-                                DEFAULT_POLL_FREQUENCY_SECONDS,
-                                calculateDefaultFlexTime(DEFAULT_POLL_FREQUENCY_SECONDS)));
+            PeriodicSync defaultSync;
+            // Old version is one sync a day. Empty bundle gets replaced by any addPeriodicSync()
+            // call.
+            if (target.target_provider) {
+                defaultSync =
+                        new PeriodicSync(target.account, target.provider,
+                            new Bundle(),
+                            DEFAULT_POLL_FREQUENCY_SECONDS,
+                            calculateDefaultFlexTime(DEFAULT_POLL_FREQUENCY_SECONDS));
+                periodicSyncs.add(defaultSync);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return target + ", enabled=" + enabled + ", syncable=" + syncable + ", backoff="
+                    + backoffTime + ", delay=" + delayUntil;
         }
     }
 
@@ -322,16 +398,9 @@
     }
 
     interface OnSyncRequestListener {
-        /**
-         * Called when a sync is needed on an account(s) due to some change in state.
-         * @param account
-         * @param userId
-         * @param reason
-         * @param authority
-         * @param extras
-         */
-        public void onSyncRequest(Account account, int userId, int reason, String authority,
-                Bundle extras);
+
+        /** Called when a sync is needed on an account(s) due to some change in state. */
+        public void onSyncRequest(EndPoint info, int reason, Bundle extras);
     }
 
     // Primary list of all syncable authorities.  Also our global lock.
@@ -356,9 +425,9 @@
     private final RemoteCallbackList<ISyncStatusObserver> mChangeListeners
             = new RemoteCallbackList<ISyncStatusObserver>();
 
-    /** Reverse mapping for component name -> <userid -> authority id>. */
-    private final HashMap<ComponentName, SparseArray<AuthorityInfo>> mServices =
-            new HashMap<ComponentName, SparseArray<AuthorityInfo>>();
+    /** Reverse mapping for component name -> <userid -> target id>. */
+    private final ArrayMap<ComponentName, SparseArray<AuthorityInfo>> mServices =
+            new ArrayMap<ComponentName, SparseArray<AuthorityInfo>>();
 
     private int mNextAuthorityId = 0;
 
@@ -501,7 +570,7 @@
      * @return amount of seconds before syncTimeSeconds that the sync can occur.
      *      I.e.
      *      earliest_sync_time = syncTimeSeconds - calculateDefaultFlexTime(syncTimeSeconds)
-     * The flex time is capped at a percentage of the {@link DEFAULT_POLL_FREQUENCY_SECONDS}.
+     * The flex time is capped at a percentage of the {@link #DEFAULT_POLL_FREQUENCY_SECONDS}.
      */
     public static long calculateDefaultFlexTime(long syncTimeSeconds) {
         if (syncTimeSeconds < DEFAULT_MIN_FLEX_ALLOWED_SECS) {
@@ -535,7 +604,7 @@
             mChangeListeners.finishBroadcast();
         }
 
-        if (DEBUG) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "reportChange " + which + " to: " + reports);
         }
 
@@ -555,7 +624,8 @@
     public boolean getSyncAutomatically(Account account, int userId, String providerName) {
         synchronized (mAuthorities) {
             if (account != null) {
-                AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
+                AuthorityInfo authority = getAuthorityLocked(
+                        new EndPoint(account, providerName, userId),
                         "getSyncAutomatically");
                 return authority != null && authority.enabled;
             }
@@ -563,10 +633,9 @@
             int i = mAuthorities.size();
             while (i > 0) {
                 i--;
-                AuthorityInfo authority = mAuthorities.valueAt(i);
-                if (authority.authority.equals(providerName)
-                        && authority.userId == userId
-                        && authority.enabled) {
+                AuthorityInfo authorityInfo = mAuthorities.valueAt(i);
+                if (authorityInfo.target.matchesSpec(new EndPoint(account, providerName, userId))
+                        && authorityInfo.enabled) {
                     return true;
                 }
             }
@@ -576,15 +645,18 @@
 
     public void setSyncAutomatically(Account account, int userId, String providerName,
             boolean sync) {
-        if (DEBUG) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.d(TAG, "setSyncAutomatically: " + /* account + */" provider " + providerName
                     + ", user " + userId + " -> " + sync);
         }
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getOrCreateAuthorityLocked(account, userId, providerName, -1,
-                    false);
+            AuthorityInfo authority =
+                    getOrCreateAuthorityLocked(
+                            new EndPoint(account, providerName, userId),
+                            -1 /* ident */,
+                            false);
             if (authority.enabled == sync) {
-                if (DEBUG) {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
                     Log.d(TAG, "setSyncAutomatically: already set to " + sync + ", doing nothing");
                 }
                 return;
@@ -603,8 +675,9 @@
     public int getIsSyncable(Account account, int userId, String providerName) {
         synchronized (mAuthorities) {
             if (account != null) {
-                AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
-                        "getIsSyncable");
+                AuthorityInfo authority = getAuthorityLocked(
+                        new EndPoint(account, providerName, userId),
+                        "get authority syncable");
                 if (authority == null) {
                     return -1;
                 }
@@ -614,9 +687,10 @@
             int i = mAuthorities.size();
             while (i > 0) {
                 i--;
-                AuthorityInfo authority = mAuthorities.valueAt(i);
-                if (authority.authority.equals(providerName)) {
-                    return authority.syncable;
+                AuthorityInfo authorityInfo = mAuthorities.valueAt(i);
+                if (authorityInfo.target != null
+                        && authorityInfo.target.provider.equals(providerName)) {
+                    return authorityInfo.syncable;
                 }
             }
             return -1;
@@ -624,119 +698,178 @@
     }
 
     public void setIsSyncable(Account account, int userId, String providerName, int syncable) {
-        if (syncable > 1) {
-            syncable = 1;
-        } else if (syncable < -1) {
-            syncable = -1;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "setIsSyncable: " + account + ", provider " + providerName
-                    + ", user " + userId + " -> " + syncable);
-        }
+        setSyncableStateForEndPoint(new EndPoint(account, providerName, userId), syncable);
+    }
+
+    public boolean getIsTargetServiceActive(ComponentName cname, int userId) {
         synchronized (mAuthorities) {
-            AuthorityInfo authority =
-                    getOrCreateAuthorityLocked(account, userId, providerName, -1, false);
-            if (authority.syncable == syncable) {
-                if (DEBUG) {
+            if (cname != null) {
+                AuthorityInfo authority = getAuthorityLocked(
+                        new EndPoint(cname, userId),
+                        "get service active");
+                if (authority == null) {
+                    return false;
+                }
+                return (authority.syncable == 1);
+            }
+            return false;
+        }
+    }
+
+    public void setIsTargetServiceActive(ComponentName cname, int userId, boolean active) {
+        setSyncableStateForEndPoint(new EndPoint(cname, userId), active ? 1 : 0);
+    }
+
+    /**
+     * An enabled sync service and a syncable provider's adapter both get resolved to the same
+     * persisted variable - namely the "syncable" attribute for an AuthorityInfo in accounts.xml.
+     * @param target target to set value for.
+     * @param syncable 0 indicates unsyncable, <0 unknown, >0 is active/syncable.
+     */
+    private void setSyncableStateForEndPoint(EndPoint target, int syncable) {
+        AuthorityInfo aInfo;
+        synchronized (mAuthorities) {
+            aInfo = getOrCreateAuthorityLocked(target, -1, false);
+            if (syncable > 1) {
+                syncable = 1;
+            } else if (syncable < -1) {
+                syncable = -1;
+            }
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.d(TAG, "setIsSyncable: " + aInfo.toString() + " -> " + syncable);
+            }
+            if (aInfo.syncable == syncable) {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
                     Log.d(TAG, "setIsSyncable: already set to " + syncable + ", doing nothing");
                 }
                 return;
             }
-            authority.syncable = syncable;
+            aInfo.syncable = syncable;
             writeAccountInfoLocked();
         }
-
         if (syncable > 0) {
-            requestSync(account, userId, SyncOperation.REASON_IS_SYNCABLE,  providerName,
-                    new Bundle());
+            requestSync(aInfo, SyncOperation.REASON_IS_SYNCABLE, new Bundle());
         }
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
 
-    public Pair<Long, Long> getBackoff(Account account, int userId, String providerName) {
+    public Pair<Long, Long> getBackoff(EndPoint info) {
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
-                    "getBackoff");
-            if (authority == null || authority.backoffTime < 0) {
-                return null;
+            AuthorityInfo authority = getAuthorityLocked(info, "getBackoff");
+            if (authority != null) {
+                return Pair.create(authority.backoffTime, authority.backoffDelay);
             }
-            return Pair.create(authority.backoffTime, authority.backoffDelay);
+            return null;
         }
     }
 
-    public void setBackoff(Account account, int userId, String providerName,
-            long nextSyncTime, long nextDelay) {
-        if (DEBUG) {
-            Log.v(TAG, "setBackoff: " + account + ", provider " + providerName
-                    + ", user " + userId
+    /**
+     * Update the backoff for the given endpoint. The endpoint may be for a provider/account and
+     * the account or provider info be null, which signifies all accounts or providers.
+     */
+    public void setBackoff(EndPoint info, long nextSyncTime, long nextDelay) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "setBackoff: " + info
                     + " -> nextSyncTime " + nextSyncTime + ", nextDelay " + nextDelay);
         }
-        boolean changed = false;
+        boolean changed;
         synchronized (mAuthorities) {
-            if (account == null || providerName == null) {
-                for (AccountInfo accountInfo : mAccounts.values()) {
-                    if (account != null && !account.equals(accountInfo.accountAndUser.account)
-                            && userId != accountInfo.accountAndUser.userId) {
-                        continue;
-                    }
-                    for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
-                        if (providerName != null
-                                && !providerName.equals(authorityInfo.authority)) {
-                            continue;
-                        }
-                        if (authorityInfo.backoffTime != nextSyncTime
-                                || authorityInfo.backoffDelay != nextDelay) {
-                            authorityInfo.backoffTime = nextSyncTime;
-                            authorityInfo.backoffDelay = nextDelay;
-                            changed = true;
-                        }
-                    }
-                }
+            if (info.target_provider
+                    && (info.account == null || info.provider == null)) {
+                // Do more work for a provider sync if the provided info has specified all
+                // accounts/providers. 
+                changed = setBackoffLocked(
+                        info.account /* may be null */,
+                        info.userId,
+                        info.provider /* may be null */,
+                        nextSyncTime, nextDelay);
             } else {
-                AuthorityInfo authority =
-                        getOrCreateAuthorityLocked(account, userId, providerName, -1 /* ident */,
-                                true);
-                if (authority.backoffTime == nextSyncTime && authority.backoffDelay == nextDelay) {
-                    return;
+                AuthorityInfo authorityInfo =
+                        getOrCreateAuthorityLocked(info, -1 /* ident */, true);
+                if (authorityInfo.backoffTime == nextSyncTime
+                        && authorityInfo.backoffDelay == nextDelay) {
+                    changed = false;
+                } else {
+                    authorityInfo.backoffTime = nextSyncTime;
+                    authorityInfo.backoffDelay = nextDelay;
+                    changed = true;
                 }
-                authority.backoffTime = nextSyncTime;
-                authority.backoffDelay = nextDelay;
-                changed = true;
             }
         }
-
         if (changed) {
             reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
         }
     }
 
     /**
-     * Callers of this function need to hold a lock for syncQueue object passed in. Bear in mind
-     * this function grabs the lock for {@link #mAuthorities}
-     * @param syncQueue queue containing pending sync operations.
+     * Either set backoff for a specific authority, or set backoff for all the
+     * accounts on a specific adapter/all adapters.
+     *
+     * @param account account for which to set backoff. Null to specify all accounts.
+     * @param userId id of the user making this request.
+     * @param providerName provider for which to set backoff. Null to specify all providers.
+     * @return true if a change occured.
      */
-    public void clearAllBackoffsLocked(SyncQueue syncQueue) {
+    private boolean setBackoffLocked(Account account, int userId, String providerName,
+            long nextSyncTime, long nextDelay) {
+        boolean changed = false;
+        for (AccountInfo accountInfo : mAccounts.values()) {
+            if (account != null && !account.equals(accountInfo.accountAndUser.account)
+                    && userId != accountInfo.accountAndUser.userId) {
+                continue;
+            }
+            for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
+                if (providerName != null
+                        && !providerName.equals(authorityInfo.target.provider)) {
+                    continue;
+                }
+                if (authorityInfo.backoffTime != nextSyncTime
+                        || authorityInfo.backoffDelay != nextDelay) {
+                    authorityInfo.backoffTime = nextSyncTime;
+                    authorityInfo.backoffDelay = nextDelay;
+                    changed = true;
+                }
+            }
+        }
+        return changed;
+    }
+
+    public void clearAllBackoffs(SyncQueue syncQueue) {
         boolean changed = false;
         synchronized (mAuthorities) {
-            for (AccountInfo accountInfo : mAccounts.values()) {
-                for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
-                    if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE
-                            || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) {
-                        if (DEBUG) {
-                            Log.v(TAG, "clearAllBackoffs:"
-                                    + " authority:" + authorityInfo.authority
-                                    + " account:" + accountInfo.accountAndUser.account.name
-                                    + " user:" + accountInfo.accountAndUser.userId
-                                    + " backoffTime was: " + authorityInfo.backoffTime
-                                    + " backoffDelay was: " + authorityInfo.backoffDelay);
+            synchronized (syncQueue) {
+                // Clear backoff for all sync adapters.
+                for (AccountInfo accountInfo : mAccounts.values()) {
+                    for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
+                        if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE
+                                || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) {
+                            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                                Log.v(TAG, "clearAllBackoffs:"
+                                        + " authority:" + authorityInfo.target
+                                        + " account:" + accountInfo.accountAndUser.account.name
+                                        + " user:" + accountInfo.accountAndUser.userId
+                                        + " backoffTime was: " + authorityInfo.backoffTime
+                                        + " backoffDelay was: " + authorityInfo.backoffDelay);
+                            }
+                            authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
+                            authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
+                            changed = true;
                         }
-                        authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
-                        authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
-                        syncQueue.onBackoffChanged(accountInfo.accountAndUser.account,
-                                accountInfo.accountAndUser.userId, authorityInfo.authority, 0);
-                        changed = true;
                     }
                 }
+                // Clear backoff for all sync services.
+                for (ComponentName service : mServices.keySet()) {
+                    SparseArray<AuthorityInfo> aInfos = mServices.get(service);
+                    for (int i = 0; i < aInfos.size(); i++) {
+                        AuthorityInfo authorityInfo = aInfos.valueAt(i);
+                        if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE
+                                || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) {
+                            authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
+                            authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
+                        }
+                    }
+                }
+                syncQueue.clearBackoffs();
             }
         }
 
@@ -745,28 +878,9 @@
         }
     }
 
-    public void setDelayUntilTime(Account account, int userId, String providerName,
-            long delayUntil) {
-        if (DEBUG) {
-            Log.v(TAG, "setDelayUntil: " + account + ", provider " + providerName
-                    + ", user " + userId + " -> delayUntil " + delayUntil);
-        }
+    public long getDelayUntilTime(EndPoint info) {
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getOrCreateAuthorityLocked(
-                    account, userId, providerName, -1 /* ident */, true);
-            if (authority.delayUntil == delayUntil) {
-                return;
-            }
-            authority.delayUntil = delayUntil;
-        }
-
-        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
-    }
-
-    public long getDelayUntilTime(Account account, int userId, String providerName) {
-        synchronized (mAuthorities) {
-            AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
-                    "getDelayUntil");
+            AuthorityInfo authority = getAuthorityLocked(info, "getDelayUntil");
             if (authority == null) {
                 return 0;
             }
@@ -774,113 +888,147 @@
         }
     }
 
-    private void updateOrRemovePeriodicSync(PeriodicSync toUpdate, int userId, boolean add) {
-        if (DEBUG) {
-            Log.v(TAG, "addOrRemovePeriodicSync: " + toUpdate.account + ", user " + userId
-                    + ", provider " + toUpdate.authority
-                    + " -> period " + toUpdate.period + ", extras " + toUpdate.extras);
+    public void setDelayUntilTime(EndPoint info, long delayUntil) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "setDelayUntil: " + info
+                    + " -> delayUntil " + delayUntil);
         }
         synchronized (mAuthorities) {
-            if (toUpdate.period <= 0 && add) {
-                Log.e(TAG, "period < 0, should never happen in updateOrRemovePeriodicSync: add-"
-                        + add);
+            AuthorityInfo authority = getOrCreateAuthorityLocked(info, -1, true);
+            if (authority.delayUntil == delayUntil) {
+                return;
             }
-            if (toUpdate.extras == null) {
-                Log.e(TAG, "null extras, should never happen in updateOrRemovePeriodicSync: add-"
-                        + add);
+            authority.delayUntil = delayUntil;
+        }
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+    }
+
+    public void updateOrAddPeriodicSync(EndPoint info, long period, long flextime, Bundle extras) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "addPeriodicSync: " + info
+                    + " -> period " + period + ", flex " + flextime + ", extras "
+                    + extras.toString());
+        }
+        synchronized (mAuthorities) {
+            if (period <= 0) {
+                Log.e(TAG, "period < 0, should never happen in updateOrAddPeriodicSync");
+            }
+            if (extras == null) {
+                Log.e(TAG, "null extras, should never happen in updateOrAddPeriodicSync:");
             }
             try {
-                AuthorityInfo authority =
-                        getOrCreateAuthorityLocked(toUpdate.account, userId, toUpdate.authority,
-                                -1, false);
-                if (add) {
-                    // add this periodic sync if an equivalent periodic doesn't already exist.
-                    boolean alreadyPresent = false;
-                    for (int i = 0, N = authority.periodicSyncs.size(); i < N; i++) {
-                        PeriodicSync syncInfo = authority.periodicSyncs.get(i);
-                        if (PeriodicSync.syncExtrasEquals(
-                                toUpdate.extras,
-                                syncInfo.extras)) {
-                            if (toUpdate.period == syncInfo.period &&
-                                    toUpdate.flexTime == syncInfo.flexTime) {
-                                // Absolutely the same.
-                                return;
-                            }
-                            authority.periodicSyncs.set(i, new PeriodicSync(toUpdate));
-                            alreadyPresent = true;
-                            break;
-                        }
-                    }
-                    // If we added an entry to the periodicSyncs array also add an entry to
-                    // the periodic syncs status to correspond to it.
-                    if (!alreadyPresent) {
-                        authority.periodicSyncs.add(new PeriodicSync(toUpdate));
-                        SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
-                        status.setPeriodicSyncTime(authority.periodicSyncs.size() - 1, 0L);
-                    }
+                PeriodicSync toUpdate;
+                if (info.target_provider) {
+                    toUpdate = new PeriodicSync(info.account,
+                            info.provider,
+                            extras,
+                            period,
+                            flextime);
                 } else {
-                    // Remove any periodic syncs that match the authority and extras.
-                    SyncStatusInfo status = mSyncStatus.get(authority.ident);
-                    boolean changed = false;
-                    Iterator<PeriodicSync> iterator = authority.periodicSyncs.iterator();
-                    int i = 0;
-                    while (iterator.hasNext()) {
-                        PeriodicSync syncInfo = iterator.next();
-                        if (PeriodicSync.syncExtrasEquals(syncInfo.extras, toUpdate.extras)) {
-                            iterator.remove();
-                            changed = true;
-                            // If we removed an entry from the periodicSyncs array also
-                            // remove the corresponding entry from the status
-                            if (status != null) {
-                                status.removePeriodicSyncTime(i);
-                            } else {
-                                Log.e(TAG, "Tried removing sync status on remove periodic sync but"
-                                        + "did not find it.");
-                            }
-                        } else {
-                            i++;
+                    toUpdate = new PeriodicSync(info.service,
+                            extras,
+                            period,
+                            flextime);
+                }
+                AuthorityInfo authority =
+                        getOrCreateAuthorityLocked(info, -1, false);
+                // add this periodic sync if an equivalent periodic doesn't already exist.
+                boolean alreadyPresent = false;
+                for (int i = 0, N = authority.periodicSyncs.size(); i < N; i++) {
+                    PeriodicSync syncInfo = authority.periodicSyncs.get(i);
+                    if (SyncManager.syncExtrasEquals(syncInfo.extras,
+                            extras,
+                            true /* includeSyncSettings*/)) {
+                        if (period == syncInfo.period &&
+                                flextime == syncInfo.flexTime) {
+                            // Absolutely the same.
+                            return;
                         }
+                        authority.periodicSyncs.set(i, toUpdate);
+                        alreadyPresent = true;
+                        break;
                     }
-                    if (!changed) {
-                        return;
-                    }
+                }
+                // If we added an entry to the periodicSyncs array also add an entry to
+                // the periodic syncs status to correspond to it.
+                if (!alreadyPresent) {
+                    authority.periodicSyncs.add(toUpdate);
+                    SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
+                    // A new periodic sync is initialised as already having been run.
+                    status.setPeriodicSyncTime(
+                            authority.periodicSyncs.size() - 1,
+                            System.currentTimeMillis());
                 }
             } finally {
                 writeAccountInfoLocked();
                 writeStatusLocked();
             }
         }
-
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
 
-    public void addPeriodicSync(PeriodicSync toAdd, int userId) {
-        updateOrRemovePeriodicSync(toAdd, userId, true /* add */);
+    public void removePeriodicSync(EndPoint info, Bundle extras) {
+        synchronized(mAuthorities) {
+            try {
+                AuthorityInfo authority =
+                        getOrCreateAuthorityLocked(info, -1, false);
+                // Remove any periodic syncs that match the target and extras.
+                SyncStatusInfo status = mSyncStatus.get(authority.ident);
+                boolean changed = false;
+                Iterator<PeriodicSync> iterator = authority.periodicSyncs.iterator();
+                int i = 0;
+                while (iterator.hasNext()) {
+                    PeriodicSync syncInfo = iterator.next();
+                    if (SyncManager.syncExtrasEquals(syncInfo.extras,
+                            extras,
+                            true /* includeSyncSettings */)) {
+                        iterator.remove();
+                        changed = true;
+                        // If we removed an entry from the periodicSyncs array also
+                        // remove the corresponding entry from the status
+                        if (status != null) {
+                            status.removePeriodicSyncTime(i);
+                        } else {
+                            Log.e(TAG, "Tried removing sync status on remove periodic sync but"
+                                    + " did not find it.");
+                        }
+                    } else {
+                        i++;
+                    }
+                }
+                if (!changed) {
+                    return;
+                }
+            } finally {
+                writeAccountInfoLocked();
+                writeStatusLocked();
+            }
+        }
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
 
-    public void removePeriodicSync(PeriodicSync toRemove, int userId) {
-        updateOrRemovePeriodicSync(toRemove, userId, false /* remove */);
-    }
-
-    public List<PeriodicSync> getPeriodicSyncs(Account account, int userId, String providerName) {
-        ArrayList<PeriodicSync> syncs = new ArrayList<PeriodicSync>();
+    /**
+     * @return list of periodic syncs for a target. Never null. If no such syncs exist, returns an
+     * empty list.
+     */
+    public List<PeriodicSync> getPeriodicSyncs(EndPoint info) {
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
-                    "getPeriodicSyncs");
-            if (authority != null) {
-                for (PeriodicSync item : authority.periodicSyncs) {
+            AuthorityInfo authorityInfo = getAuthorityLocked(info, "getPeriodicSyncs");
+            ArrayList<PeriodicSync> syncs = new ArrayList<PeriodicSync>();
+            if (authorityInfo != null) {
+                for (PeriodicSync item : authorityInfo.periodicSyncs) {
                     // Copy and send out. Necessary for thread-safety although it's parceled.
                     syncs.add(new PeriodicSync(item));
                 }
             }
+            return syncs;
         }
-        return syncs;
     }
 
     public void setMasterSyncAutomatically(boolean flag, int userId) {
         synchronized (mAuthorities) {
             Boolean auto = mMasterSyncAutomatically.get(userId);
-            if (auto != null && (boolean) auto == flag) {
+            if (auto != null && auto.equals(flag)) {
                 return;
             }
             mMasterSyncAutomatically.put(userId, flag);
@@ -901,12 +1049,6 @@
         }
     }
 
-    public void removeAuthority(Account account, int userId, String authority) {
-        synchronized (mAuthorities) {
-            removeAuthorityLocked(account, userId, authority, true /* doWrite */);
-        }
-    }
-
     public AuthorityInfo getAuthority(int authorityId) {
         synchronized (mAuthorities) {
             return mAuthorities.get(authorityId);
@@ -914,72 +1056,60 @@
     }
 
     /**
-     * Returns true if there is currently a sync operation for the given
-     * account or authority actively being processed.
+     * Returns true if there is currently a sync operation being actively processed for the given
+     * target.
      */
-    public boolean isSyncActive(Account account, int userId, String authority) {
+    public boolean isSyncActive(EndPoint info) {
         synchronized (mAuthorities) {
-            for (SyncInfo syncInfo : getCurrentSyncs(userId)) {
+            for (SyncInfo syncInfo : getCurrentSyncs(info.userId)) {
                 AuthorityInfo ainfo = getAuthority(syncInfo.authorityId);
-                if (ainfo != null && ainfo.account.equals(account)
-                        && ainfo.authority.equals(authority)
-                        && ainfo.userId == userId) {
+                if (ainfo != null && ainfo.target.matchesSpec(info)) {
                     return true;
                 }
             }
         }
-
         return false;
     }
 
-    public PendingOperation insertIntoPending(PendingOperation op) {
+    public PendingOperation insertIntoPending(SyncOperation op) {
+        PendingOperation pop;
         synchronized (mAuthorities) {
-            if (DEBUG) {
-                Log.v(TAG, "insertIntoPending: account=" + op.account
-                        + " user=" + op.userId
-                        + " auth=" + op.authority
-                        + " src=" + op.syncSource
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "insertIntoPending: authority=" + op.target
                         + " extras=" + op.extras);
             }
-
-            AuthorityInfo authority = getOrCreateAuthorityLocked(op.account, op.userId,
-                    op.authority,
-                    -1 /* desired identifier */,
-                    true /* write accounts to storage */);
+            final EndPoint info = op.target;
+            AuthorityInfo authority =
+                    getOrCreateAuthorityLocked(info,
+                            -1 /* desired identifier */,
+                            true /* write accounts to storage */);
             if (authority == null) {
                 return null;
             }
 
-            op = new PendingOperation(op);
-            op.authorityId = authority.ident;
-            mPendingOperations.add(op);
-            appendPendingOperationLocked(op);
+            pop = new PendingOperation(authority, op.reason, op.syncSource, op.extras,
+                    op.expedited);
+            mPendingOperations.add(pop);
+            appendPendingOperationLocked(pop);
 
             SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
             status.pending = true;
         }
-
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_PENDING);
-        return op;
+        return pop;
     }
 
     /**
      * Remove from list of pending operations. If successful, search through list for matching
-     * authorities. If there are no more pending syncs for the same authority/account/userid,
-     * update the SyncStatusInfo for that authority(authority here is the internal representation
-     * of a 'sync operation'.
-     * @param op
-     * @return
+     * authorities. If there are no more pending syncs for the same target,
+     * update the SyncStatusInfo for that target.
+     * @param op Pending op to delete.
      */
     public boolean deleteFromPending(PendingOperation op) {
         boolean res = false;
         synchronized (mAuthorities) {
-            if (DEBUG) {
-                Log.v(TAG, "deleteFromPending: account=" + op.account
-                    + " user=" + op.userId
-                    + " auth=" + op.authority
-                    + " src=" + op.syncSource
-                    + " extras=" + op.extras);
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "deleteFromPending: account=" + op.toString());
             }
             if (mPendingOperations.remove(op)) {
                 if (mPendingOperations.size() == 0
@@ -989,30 +1119,27 @@
                 } else {
                     mNumPendingFinished++;
                 }
-
-                AuthorityInfo authority = getAuthorityLocked(op.account, op.userId, op.authority,
-                        "deleteFromPending");
+                AuthorityInfo authority = getAuthorityLocked(op.target, "deleteFromPending");
                 if (authority != null) {
-                    if (DEBUG) Log.v(TAG, "removing - " + authority.toString());
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, "removing - " + authority.toString());
+                    }
                     final int N = mPendingOperations.size();
                     boolean morePending = false;
-                    for (int i=0; i<N; i++) {
+                    for (int i = 0; i < N; i++) {
                         PendingOperation cur = mPendingOperations.get(i);
-                        if (cur.account.equals(op.account)
-                                && cur.authority.equals(op.authority)
-                                && cur.userId == op.userId) {
+                        if (cur.equals(op)) {
                             morePending = true;
                             break;
                         }
                     }
 
                     if (!morePending) {
-                        if (DEBUG) Log.v(TAG, "no more pending!");
+                        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "no more pending!");
                         SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
                         status.pending = false;
                     }
                 }
-
                 res = true;
             }
         }
@@ -1047,7 +1174,9 @@
      */
     public void doDatabaseCleanup(Account[] accounts, int userId) {
         synchronized (mAuthorities) {
-            if (DEBUG) Log.v(TAG, "Updating for new accounts...");
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "Updating for new accounts...");
+            }
             SparseArray<AuthorityInfo> removing = new SparseArray<AuthorityInfo>();
             Iterator<AccountInfo> accIt = mAccounts.values().iterator();
             while (accIt.hasNext()) {
@@ -1055,7 +1184,7 @@
                 if (!ArrayUtils.contains(accounts, acc.accountAndUser.account)
                         && acc.accountAndUser.userId == userId) {
                     // This account no longer exists...
-                    if (DEBUG) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
                         Log.v(TAG, "Account removed: " + acc.accountAndUser);
                     }
                     for (AuthorityInfo auth : acc.authorities.values()) {
@@ -1102,25 +1231,25 @@
     public SyncInfo addActiveSync(SyncManager.ActiveSyncContext activeSyncContext) {
         final SyncInfo syncInfo;
         synchronized (mAuthorities) {
-            if (DEBUG) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "setActiveSync: account="
-                    + activeSyncContext.mSyncOperation.account
-                    + " auth=" + activeSyncContext.mSyncOperation.authority
+                    + " auth=" + activeSyncContext.mSyncOperation.target
                     + " src=" + activeSyncContext.mSyncOperation.syncSource
                     + " extras=" + activeSyncContext.mSyncOperation.extras);
             }
-            AuthorityInfo authority = getOrCreateAuthorityLocked(
-                    activeSyncContext.mSyncOperation.account,
-                    activeSyncContext.mSyncOperation.userId,
-                    activeSyncContext.mSyncOperation.authority,
-                    -1 /* assign a new identifier if creating a new authority */,
+            final EndPoint info = activeSyncContext.mSyncOperation.target;
+            AuthorityInfo authorityInfo = getOrCreateAuthorityLocked(
+                    info,
+                    -1 /* assign a new identifier if creating a new target */,
                     true /* write to storage if this results in a change */);
-            syncInfo = new SyncInfo(authority.ident,
-                    authority.account, authority.authority,
+            syncInfo = new SyncInfo(
+                    authorityInfo.ident,
+                    authorityInfo.target.account,
+                    authorityInfo.target.provider,
+                    authorityInfo.target.service,
                     activeSyncContext.mStartTime);
-            getCurrentSyncs(authority.userId).add(syncInfo);
+            getCurrentSyncs(authorityInfo.target.userId).add(syncInfo);
         }
-
         reportActiveChange();
         return syncInfo;
     }
@@ -1130,10 +1259,11 @@
      */
     public void removeActiveSync(SyncInfo syncInfo, int userId) {
         synchronized (mAuthorities) {
-            if (DEBUG) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "removeActiveSync: account=" + syncInfo.account
                         + " user=" + userId
-                        + " auth=" + syncInfo.authority);
+                        + " auth=" + syncInfo.authority
+                        + " service=" + syncInfo.service);
             }
             getCurrentSyncs(userId).remove(syncInfo);
         }
@@ -1149,37 +1279,34 @@
     }
 
     /**
-     * Note that sync has started for the given account and authority.
+     * Note that sync has started for the given operation.
      */
-    public long insertStartSyncEvent(Account accountName, int userId, int reason,
-            String authorityName, long now, int source, boolean initialization, Bundle extras) {
+    public long insertStartSyncEvent(SyncOperation op, long now) {
         long id;
         synchronized (mAuthorities) {
-            if (DEBUG) {
-                Log.v(TAG, "insertStartSyncEvent: account=" + accountName + "user=" + userId
-                    + " auth=" + authorityName + " source=" + source);
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "insertStartSyncEvent: " + op);
             }
-            AuthorityInfo authority = getAuthorityLocked(accountName, userId, authorityName,
-                    "insertStartSyncEvent");
+            AuthorityInfo authority = getAuthorityLocked(op.target, "insertStartSyncEvent");
             if (authority == null) {
                 return -1;
             }
             SyncHistoryItem item = new SyncHistoryItem();
-            item.initialization = initialization;
+            item.initialization = op.isInitialization();
             item.authorityId = authority.ident;
             item.historyId = mNextHistoryId++;
             if (mNextHistoryId < 0) mNextHistoryId = 0;
             item.eventTime = now;
-            item.source = source;
-            item.reason = reason;
-            item.extras = extras;
+            item.source = op.syncSource;
+            item.reason = op.reason;
+            item.extras = op.extras;
             item.event = EVENT_START;
             mSyncHistory.add(0, item);
             while (mSyncHistory.size() > MAX_HISTORY) {
                 mSyncHistory.remove(mSyncHistory.size()-1);
             }
             id = item.historyId;
-            if (DEBUG) Log.v(TAG, "returning historyId " + id);
+            if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "returning historyId " + id);
         }
 
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS);
@@ -1189,7 +1316,7 @@
     public void stopSyncEvent(long historyId, long elapsedTime, String resultMessage,
             long downstreamActivity, long upstreamActivity) {
         synchronized (mAuthorities) {
-            if (DEBUG) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "stopSyncEvent: historyId=" + historyId);
             }
             SyncHistoryItem item = null;
@@ -1346,13 +1473,12 @@
     }
 
     /**
-     * Return a copy of the specified authority with the corresponding sync status
+     * Return a copy of the specified target with the corresponding sync status
      */
-    public Pair<AuthorityInfo, SyncStatusInfo> getCopyOfAuthorityWithSyncStatus(
-            Account account, int userId, String authority) {
+    public Pair<AuthorityInfo, SyncStatusInfo> getCopyOfAuthorityWithSyncStatus(EndPoint info) {
         synchronized (mAuthorities) {
-            AuthorityInfo authorityInfo = getOrCreateAuthorityLocked(account, userId, authority,
-                    -1 /* assign a new identifier if creating a new authority */,
+            AuthorityInfo authorityInfo = getOrCreateAuthorityLocked(info,
+                    -1 /* assign a new identifier if creating a new target */,
                     true /* write to storage if this results in a change */);
             return createCopyPairOfAuthorityWithSyncStatusLocked(authorityInfo);
         }
@@ -1373,26 +1499,24 @@
     }
 
     /**
-     * Returns the status that matches the authority and account.
+     * Returns the status that matches the target.
      *
-     * @param account the account we want to check
-     * @param authority the authority whose row should be selected
-     * @return the SyncStatusInfo for the authority or null if none found.
+     * @param info the endpoint target we are querying status info for.
+     * @return the SyncStatusInfo for the endpoint.
      */
-    public SyncStatusInfo getStatusByAccountAndAuthority(Account account, int userId,
-            String authority) {
-        if (account == null || authority == null) {
-          return null;
+    public SyncStatusInfo getStatusByAuthority(EndPoint info) {
+        if (info.target_provider && (info.account == null || info.provider == null)) {
+            return null;
+        } else if (info.target_service && info.service == null) {
+            return null;
         }
         synchronized (mAuthorities) {
             final int N = mSyncStatus.size();
-            for (int i=0; i<N; i++) {
+            for (int i = 0; i < N; i++) {
                 SyncStatusInfo cur = mSyncStatus.valueAt(i);
                 AuthorityInfo ainfo = mAuthorities.get(cur.authorityId);
-
-                if (ainfo != null && ainfo.authority.equals(authority)
-                        && ainfo.userId == userId
-                        && account.equals(ainfo.account)) {
+                if (ainfo != null
+                        && ainfo.target.matchesSpec(info)) {
                   return cur;
                 }
             }
@@ -1400,25 +1524,20 @@
         }
     }
 
-    /**
-     * Return true if the pending status is true of any matching authorities.
-     */
-    public boolean isSyncPending(Account account, int userId, String authority) {
+    /** Return true if the pending status is true of any matching authorities. */
+    public boolean isSyncPending(EndPoint info) {
         synchronized (mAuthorities) {
             final int N = mSyncStatus.size();
-            for (int i=0; i<N; i++) {
+            for (int i = 0; i < N; i++) {
                 SyncStatusInfo cur = mSyncStatus.valueAt(i);
                 AuthorityInfo ainfo = mAuthorities.get(cur.authorityId);
                 if (ainfo == null) {
                     continue;
                 }
-                if (userId != ainfo.userId) {
+                if (!ainfo.target.matchesSpec(info)) {
                     continue;
                 }
-                if (account != null && !ainfo.account.equals(account)) {
-                    continue;
-                }
-                if (ainfo.authority.equals(authority) && cur.pending) {
+                if (cur.pending) {
                     return true;
                 }
             }
@@ -1474,128 +1593,133 @@
     }
 
     /**
-     * Retrieve an authority, returning null if one does not exist.
+     * Retrieve a target's full info, returning null if one does not exist.
      *
-     * @param accountName The name of the account for the authority.
-     * @param authorityName The name of the authority itself.
+     * @param info info of the target to look up.
      * @param tag If non-null, this will be used in a log message if the
-     * requested authority does not exist.
+     * requested target does not exist.
      */
-    private AuthorityInfo getAuthorityLocked(Account accountName, int userId, String authorityName,
-            String tag) {
-        AccountAndUser au = new AccountAndUser(accountName, userId);
-        AccountInfo accountInfo = mAccounts.get(au);
-        if (accountInfo == null) {
-            if (tag != null) {
-                if (DEBUG) {
-                    Log.v(TAG, tag + ": unknown account " + au);
-                }
+    private AuthorityInfo getAuthorityLocked(EndPoint info, String tag) {
+        if (info.target_service) {
+            SparseArray<AuthorityInfo> aInfo = mServices.get(info.service);
+            AuthorityInfo authority = null;
+            if (aInfo != null) {
+                authority = aInfo.get(info.userId);
             }
+            if (authority == null) {
+                if (tag != null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, tag + " No authority info found for " + info.service + " for"
+                                + " user " + info.userId);
+                    }
+                }
+                return null;
+            }
+            return authority;
+        } else if (info.target_provider){
+            AccountAndUser au = new AccountAndUser(info.account, info.userId);
+            AccountInfo accountInfo = mAccounts.get(au);
+            if (accountInfo == null) {
+                if (tag != null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, tag + ": unknown account " + au);
+                    }
+                }
+                return null;
+            }
+            AuthorityInfo authority = accountInfo.authorities.get(info.provider);
+            if (authority == null) {
+                if (tag != null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, tag + ": unknown provider " + info.provider);
+                    }
+                }
+                return null;
+            }
+            return authority;
+        } else {
+            Log.e(TAG, tag + " Authority : " + info + ", invalid target");
             return null;
         }
-        AuthorityInfo authority = accountInfo.authorities.get(authorityName);
-        if (authority == null) {
-            if (tag != null) {
-                if (DEBUG) {
-                    Log.v(TAG, tag + ": unknown authority " + authorityName);
-                }
-            }
-            return null;
-        }
-
-        return authority;
     }
 
     /**
-     * Retrieve an authority, returning null if one does not exist.
-     *
-     * @param service The service name used for this sync.
-     * @param userId The user for whom this sync is scheduled.
-     * @param tag If non-null, this will be used in a log message if the
-     * requested authority does not exist.
-     */
-    private AuthorityInfo getAuthorityLocked(ComponentName service, int userId, String tag) {
-        AuthorityInfo authority = mServices.get(service).get(userId);
-        if (authority == null) {
-            if (tag != null) {
-                if (DEBUG) {
-                    Log.v(TAG, tag + " No authority info found for " + service + " for user "
-                            + userId);
-                }
-            }
-            return null;
-        }
-        return authority;
-    }
-
-    /**
-     * @param cname identifier for the service.
-     * @param userId for the syncs corresponding to this authority.
-     * @param ident unique identifier for authority. -1 for none.
+     * @param info info identifying target.
+     * @param ident unique identifier for target. -1 for none.
      * @param doWrite if true, update the accounts.xml file on the disk.
-     * @return the authority that corresponds to the provided sync service, creating it if none
+     * @return the authority that corresponds to the provided sync target, creating it if none
      * exists.
      */
-    private AuthorityInfo getOrCreateAuthorityLocked(ComponentName cname, int userId, int ident,
-            boolean doWrite) {
-        SparseArray<AuthorityInfo> aInfo = mServices.get(cname);
-        if (aInfo == null) {
-            aInfo = new SparseArray<AuthorityInfo>();
-            mServices.put(cname, aInfo);
-        }
-        AuthorityInfo authority = aInfo.get(userId);
-        if (authority == null) {
-            if (ident < 0) {
-                ident = mNextAuthorityId;
-                mNextAuthorityId++;
-                doWrite = true;
+    private AuthorityInfo getOrCreateAuthorityLocked(EndPoint info, int ident, boolean doWrite) {
+        AuthorityInfo authority = null;
+        if (info.target_service) {
+            SparseArray<AuthorityInfo> aInfo = mServices.get(info.service);
+            if (aInfo == null) {
+                aInfo = new SparseArray<AuthorityInfo>();
+                mServices.put(info.service, aInfo);
             }
-            if (DEBUG) {
-                Log.v(TAG, "created a new AuthorityInfo for " + cname.getPackageName()
-                        + ", " + cname.getClassName()
-                        + ", user: " + userId);
+            authority = aInfo.get(info.userId);
+            if (authority == null) {
+                authority = createAuthorityLocked(info, ident, doWrite);
+                aInfo.put(info.userId, authority);
             }
-            authority = new AuthorityInfo(cname, userId, ident);
-            aInfo.put(userId, authority);
-            mAuthorities.put(ident, authority);
-            if (doWrite) {
-                writeAccountInfoLocked();
+        } else if (info.target_provider) {
+            AccountAndUser au = new AccountAndUser(info.account, info.userId);
+            AccountInfo account = mAccounts.get(au);
+            if (account == null) {
+                account = new AccountInfo(au);
+                mAccounts.put(au, account);
+            }
+            authority = account.authorities.get(info.provider);
+            if (authority == null) {
+                authority = createAuthorityLocked(info, ident, doWrite);
+                account.authorities.put(info.provider, authority);
             }
         }
         return authority;
     }
 
-    private AuthorityInfo getOrCreateAuthorityLocked(Account accountName, int userId,
-            String authorityName, int ident, boolean doWrite) {
-        AccountAndUser au = new AccountAndUser(accountName, userId);
-        AccountInfo account = mAccounts.get(au);
-        if (account == null) {
-            account = new AccountInfo(au);
-            mAccounts.put(au, account);
+    private AuthorityInfo createAuthorityLocked(EndPoint info, int ident, boolean doWrite) {
+        AuthorityInfo authority;
+        if (ident < 0) {
+            ident = mNextAuthorityId;
+            mNextAuthorityId++;
+            doWrite = true;
         }
-        AuthorityInfo authority = account.authorities.get(authorityName);
-        if (authority == null) {
-            if (ident < 0) {
-                ident = mNextAuthorityId;
-                mNextAuthorityId++;
-                doWrite = true;
-            }
-            if (DEBUG) {
-                Log.v(TAG, "created a new AuthorityInfo for " + accountName
-                        + ", user " + userId
-                        + ", provider " + authorityName);
-            }
-            authority = new AuthorityInfo(accountName, userId, authorityName, ident);
-            account.authorities.put(authorityName, authority);
-            mAuthorities.put(ident, authority);
-            if (doWrite) {
-                writeAccountInfoLocked();
-            }
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "created a new AuthorityInfo for " + info);
         }
-
+        authority = new AuthorityInfo(info, ident);
+        mAuthorities.put(ident, authority);
+        if (doWrite) {
+            writeAccountInfoLocked();
+        }
         return authority;
     }
 
+    public void removeAuthority(EndPoint info) {
+        synchronized (mAuthorities) {
+            if (info.target_provider) {
+                removeAuthorityLocked(info.account, info.userId, info.provider, true /* doWrite */);
+            } else {
+                SparseArray<AuthorityInfo> aInfos = mServices.get(info.service);
+                if (aInfos != null) {
+                    AuthorityInfo authorityInfo = aInfos.get(info.userId);
+                    if (authorityInfo != null) {
+                        mAuthorities.remove(authorityInfo.ident);
+                        aInfos.delete(info.userId);
+                        writeAccountInfoLocked();
+                    }
+                }
+
+            }
+        }
+    }
+
+    /**
+     * Remove an authority associated with a provider. Needs to be a standalone function for
+     * backward compatibility.
+     */
     private void removeAuthorityLocked(Account account, int userId, String authorityName,
             boolean doWrite) {
         AccountInfo accountInfo = mAccounts.get(new AccountAndUser(account, userId));
@@ -1612,10 +1736,9 @@
 
     /**
      * Updates (in a synchronized way) the periodic sync time of the specified
-     * authority id and target periodic sync
+     * target id and target periodic sync
      */
-    public void setPeriodicSyncTime(
-            int authorityId, PeriodicSync targetPeriodicSync, long when) {
+    public void setPeriodicSyncTime(int authorityId, PeriodicSync targetPeriodicSync, long when) {
         boolean found = false;
         final AuthorityInfo authorityInfo;
         synchronized (mAuthorities) {
@@ -1631,7 +1754,7 @@
         }
         if (!found) {
             Log.w(TAG, "Ignoring setPeriodicSyncTime request for a sync that does not exist. " +
-                    "Authority: " + authorityInfo.authority);
+                    "Authority: " + authorityInfo.target);
         }
     }
 
@@ -1692,7 +1815,7 @@
         try {
             fis = mAccountInfoFile.openRead();
             if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                Log.v(TAG, "Reading " + mAccountInfoFile.getBaseFile());
+                Log.v(TAG_FILE, "Reading " + mAccountInfoFile.getBaseFile());
             }
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(fis, null);
@@ -1800,10 +1923,14 @@
 
         ArrayList<AuthorityInfo> authoritiesToRemove = new ArrayList<AuthorityInfo>();
         final int N = mAuthorities.size();
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             AuthorityInfo authority = mAuthorities.valueAt(i);
+            // skip this authority if it doesn't target a provider
+            if (authority.target.target_service) {
+                continue;
+            }
             // skip this authority if it isn't one of the renamed ones
-            final String newAuthorityName = sAuthorityRenames.get(authority.authority);
+            final String newAuthorityName = sAuthorityRenames.get(authority.target.provider);
             if (newAuthorityName == null) {
                 continue;
             }
@@ -1819,20 +1946,26 @@
             }
 
             // if we already have a record of this new authority then don't copy over the settings
-            if (getAuthorityLocked(authority.account, authority.userId, newAuthorityName, "cleanup")
-                    != null) {
+            EndPoint newInfo =
+                    new EndPoint(authority.target.account,
+                            newAuthorityName,
+                            authority.target.userId);
+            if (getAuthorityLocked(newInfo, "cleanup") != null) {
                 continue;
             }
 
-            AuthorityInfo newAuthority = getOrCreateAuthorityLocked(authority.account,
-                    authority.userId, newAuthorityName, -1 /* ident */, false /* doWrite */);
+            AuthorityInfo newAuthority =
+                    getOrCreateAuthorityLocked(newInfo, -1 /* ident */, false /* doWrite */);
             newAuthority.enabled = true;
             writeNeeded = true;
         }
 
         for (AuthorityInfo authorityInfo : authoritiesToRemove) {
-            removeAuthorityLocked(authorityInfo.account, authorityInfo.userId,
-                    authorityInfo.authority, false /* doWrite */);
+            removeAuthorityLocked(
+                    authorityInfo.target.account,
+                    authorityInfo.target.userId,
+                    authorityInfo.target.provider,
+                    false /* doWrite */);
             writeNeeded = true;
         }
 
@@ -1874,30 +2007,37 @@
             String packageName = parser.getAttributeValue(null, "package");
             String className = parser.getAttributeValue(null, "class");
             int userId = user == null ? 0 : Integer.parseInt(user);
-            if (accountType == null) {
+            if (accountType == null && packageName == null) {
                 accountType = "com.google";
                 syncable = "unknown";
             }
             authority = mAuthorities.get(id);
             if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                Log.v(TAG, "Adding authority: account="
-                        + accountName + " auth=" + authorityName
+                Log.v(TAG_FILE, "Adding authority:"
+                        + " account=" + accountName
+                        + " accountType=" + accountType
+                        + " auth=" + authorityName
+                        + " package=" + packageName
+                        + " class=" + className
                         + " user=" + userId
                         + " enabled=" + enabled
                         + " syncable=" + syncable);
             }
             if (authority == null) {
                 if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                    Log.v(TAG, "Creating entry");
+                    Log.v(TAG_FILE, "Creating authority entry");
                 }
-                if (accountName != null && accountType != null) {
-                    authority = getOrCreateAuthorityLocked(
-                            new Account(accountName, accountType), userId, authorityName, id,
-                                false);
+                EndPoint info;
+                if (accountName != null && authorityName != null) {
+                    info = new EndPoint(
+                            new Account(accountName, accountType),
+                            authorityName, userId);
                 } else {
-                    authority = getOrCreateAuthorityLocked(
-                            new ComponentName(packageName, className), userId, id, false);
+                    info = new EndPoint(
+                            new ComponentName(packageName, className),
+                            userId);
                 }
+                authority = getOrCreateAuthorityLocked(info, id, false);
                 // If the version is 0 then we are upgrading from a file format that did not
                 // know about periodic syncs. In that case don't clear the list since we
                 // want the default, which is a daily periodic sync.
@@ -1928,7 +2068,7 @@
     /**
      * Parse a periodic sync from accounts.xml. Sets the bundle to be empty.
      */
-    private PeriodicSync parsePeriodicSync(XmlPullParser parser, AuthorityInfo authority) {
+    private PeriodicSync parsePeriodicSync(XmlPullParser parser, AuthorityInfo authorityInfo) {
         Bundle extras = new Bundle(); // Gets filled in later.
         String periodValue = parser.getAttributeValue(null, "period");
         String flexValue = parser.getAttributeValue(null, "flex");
@@ -1946,17 +2086,31 @@
         try {
             flextime = Long.parseLong(flexValue);
         } catch (NumberFormatException e) {
-            Log.e(TAG, "Error formatting value parsed for periodic sync flex: " + flexValue);
             flextime = calculateDefaultFlexTime(period);
+            Log.e(TAG, "Error formatting value parsed for periodic sync flex: " + flexValue
+                    + ", using default: "
+                    + flextime);
         } catch (NullPointerException expected) {
             flextime = calculateDefaultFlexTime(period);
             Log.d(TAG, "No flex time specified for this sync, using a default. period: "
             + period + " flex: " + flextime);
         }
-        final PeriodicSync periodicSync =
-                new PeriodicSync(authority.account, authority.authority, extras,
+        PeriodicSync periodicSync;
+        if (authorityInfo.target.target_provider) {
+            periodicSync =
+                new PeriodicSync(authorityInfo.target.account,
+                        authorityInfo.target.provider,
+                        extras,
                         period, flextime);
-        authority.periodicSyncs.add(periodicSync);
+        } else {
+            periodicSync =
+                    new PeriodicSync(
+                            authorityInfo.target.service,
+                            extras,
+                            period,
+                            flextime);
+        }
+        authorityInfo.periodicSyncs.add(periodicSync);
         return periodicSync;
     }
 
@@ -1994,7 +2148,7 @@
      */
     private void writeAccountInfoLocked() {
         if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-            Log.v(TAG, "Writing new " + mAccountInfoFile.getBaseFile());
+            Log.v(TAG_FILE, "Writing new " + mAccountInfoFile.getBaseFile());
         }
         FileOutputStream fos = null;
 
@@ -2024,17 +2178,18 @@
             final int N = mAuthorities.size();
             for (int i = 0; i < N; i++) {
                 AuthorityInfo authority = mAuthorities.valueAt(i);
+                EndPoint info = authority.target;
                 out.startTag(null, "authority");
                 out.attribute(null, "id", Integer.toString(authority.ident));
-                out.attribute(null, XML_ATTR_USER, Integer.toString(authority.userId));
+                out.attribute(null, XML_ATTR_USER, Integer.toString(info.userId));
                 out.attribute(null, XML_ATTR_ENABLED, Boolean.toString(authority.enabled));
-                if (authority.service == null) {
-                    out.attribute(null, "account", authority.account.name);
-                    out.attribute(null, "type", authority.account.type);
-                    out.attribute(null, "authority", authority.authority);
+                if (info.service == null) {
+                    out.attribute(null, "account", info.account.name);
+                    out.attribute(null, "type", info.account.type);
+                    out.attribute(null, "authority", info.provider);
                 } else {
-                    out.attribute(null, "package", authority.service.getPackageName());
-                    out.attribute(null, "class", authority.service.getClassName());
+                    out.attribute(null, "package", info.service.getPackageName());
+                    out.attribute(null, "class", info.service.getClassName());
                 }
                 if (authority.syncable < 0) {
                     out.attribute(null, "syncable", "unknown");
@@ -2094,7 +2249,7 @@
 
             // Copy in all of the status information, as well as accounts.
             if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                Log.v(TAG, "Reading legacy sync accounts db");
+                Log.v(TAG_FILE, "Reading legacy sync accounts db");
             }
             SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
             qb.setTables("stats, status");
@@ -2128,9 +2283,13 @@
                     accountType = "com.google";
                 }
                 String authorityName = c.getString(c.getColumnIndex("authority"));
-                AuthorityInfo authority = this.getOrCreateAuthorityLocked(
-                        new Account(accountName, accountType), 0 /* legacy is single-user */,
-                        authorityName, -1, false);
+                AuthorityInfo authority =
+                        this.getOrCreateAuthorityLocked(
+                                new EndPoint(new Account(accountName, accountType),
+                                        authorityName,
+                                        0 /* legacy is single-user */)
+                                , -1,
+                                false);
                 if (authority != null) {
                     int i = mSyncStatus.size();
                     boolean found = false;
@@ -2182,7 +2341,7 @@
                     while (i > 0) {
                         i--;
                         AuthorityInfo authority = mAuthorities.valueAt(i);
-                        if (authority.authority.equals(provider)) {
+                        if (authority.target.provider.equals(provider)) {
                             authority.enabled = value == null || Boolean.parseBoolean(value);
                             authority.syncable = 1;
                         }
@@ -2206,7 +2365,7 @@
      */
     private void readStatusLocked() {
         if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-            Log.v(TAG, "Reading " + mStatusFile.getBaseFile());
+            Log.v(TAG_FILE, "Reading " + mStatusFile.getBaseFile());
         }
         try {
             byte[] data = mStatusFile.readFully();
@@ -2220,8 +2379,7 @@
                     if (mAuthorities.indexOfKey(status.authorityId) >= 0) {
                         status.pending = false;
                         if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                            Log.v(TAG, "Adding status for id "
-                                    + status.authorityId);
+                            Log.v(TAG_FILE, "Adding status for id " + status.authorityId);
                         }
                         mSyncStatus.put(status.authorityId, status);
                     }
@@ -2241,7 +2399,7 @@
      */
     private void writeStatusLocked() {
         if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-            Log.v(TAG, "Writing new " + mStatusFile.getBaseFile());
+            Log.v(TAG_FILE, "Writing new " + mStatusFile.getBaseFile());
         }
 
         // The file is being written, so we don't need to have a scheduled
@@ -2284,6 +2442,9 @@
         }
         try {
             fis = mPendingFile.openRead();
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG_FILE, "Reading " + mPendingFile.getBaseFile());
+            }
             XmlPullParser parser;
             parser = Xml.newPullParser();
             parser.setInput(fis, null);
@@ -2295,12 +2456,11 @@
             }
             if (eventType == XmlPullParser.END_DOCUMENT) return; // Nothing to read.
 
-            String tagName = parser.getName();
             do {
                 PendingOperation pop = null;
                 if (eventType == XmlPullParser.START_TAG) {
                     try {
-                        tagName = parser.getName();
+                        String tagName = parser.getName();
                         if (parser.getDepth() == 1 && "op".equals(tagName)) {
                             // Verify version.
                             String versionString =
@@ -2325,18 +2485,16 @@
                             }
                             if (authority != null) {
                                 pop = new PendingOperation(
-                                        authority.account, authority.userId, reason,
-                                        syncSource, authority.authority, new Bundle(),
-                                        expedited);
+                                        authority, reason, syncSource, new Bundle(), expedited);
                                 pop.flatExtras = null; // No longer used.
                                 mPendingOperations.add(pop);
                                 if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
                                     Log.v(TAG_FILE, "Adding pending op: "
-                                            + pop.authority
+                                            + pop.target
                                             + " src=" + pop.syncSource
                                             + " reason=" + pop.reason
                                             + " expedited=" + pop.expedited);
-                                }
+                                    }
                             } else {
                                 // Skip non-existent authority.
                                 pop = null;
@@ -2371,11 +2529,40 @@
         }
     }
 
+    static private byte[] flattenBundle(Bundle bundle) {
+        byte[] flatData = null;
+        Parcel parcel = Parcel.obtain();
+        try {
+            bundle.writeToParcel(parcel, 0);
+            flatData = parcel.marshall();
+        } finally {
+            parcel.recycle();
+        }
+        return flatData;
+    }
+
+    static private Bundle unflattenBundle(byte[] flatData) {
+        Bundle bundle;
+        Parcel parcel = Parcel.obtain();
+        try {
+            parcel.unmarshall(flatData, 0, flatData.length);
+            parcel.setDataPosition(0);
+            bundle = parcel.readBundle();
+        } catch (RuntimeException e) {
+            // A RuntimeException is thrown if we were unable to parse the parcel.
+            // Create an empty parcel in this case.
+            bundle = new Bundle();
+        } finally {
+            parcel.recycle();
+        }
+        return bundle;
+    }
+
+    private static final String XML_ATTR_VERSION = "version";
     private static final String XML_ATTR_AUTHORITYID = "authority_id";
     private static final String XML_ATTR_SOURCE = "source";
     private static final String XML_ATTR_EXPEDITED = "expedited";
     private static final String XML_ATTR_REASON = "reason";
-    private static final String XML_ATTR_VERSION = "version";
 
     /**
      * Write all currently pending ops to the pending ops file.
@@ -2385,14 +2572,14 @@
         FileOutputStream fos = null;
         try {
             if (N == 0) {
-                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                    Log.v(TAG_FILE, "Truncating " + mPendingFile.getBaseFile());
+                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)){
+                    Log.v(TAG, "Truncating " + mPendingFile.getBaseFile());
                 }
                 mPendingFile.truncate();
                 return;
             }
             if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                Log.v(TAG_FILE, "Writing new " + mPendingFile.getBaseFile());
+                Log.v(TAG, "Writing new " + mPendingFile.getBaseFile());
             }
             fos = mPendingFile.startWrite();
             XmlSerializer out = new FastXmlSerializer();
@@ -2401,9 +2588,9 @@
             for (int i = 0; i < N; i++) {
                 PendingOperation pop = mPendingOperations.get(i);
                 writePendingOperationLocked(pop, out);
-            }
-            out.endDocument();
-            mPendingFile.finishWrite(fos);
+             }
+             out.endDocument();
+             mPendingFile.finishWrite(fos);
         } catch (java.io.IOException e1) {
             Log.w(TAG, "Error writing pending operations", e1);
             if (fos != null) {
@@ -2463,35 +2650,6 @@
         }
     }
 
-    static private byte[] flattenBundle(Bundle bundle) {
-        byte[] flatData = null;
-        Parcel parcel = Parcel.obtain();
-        try {
-            bundle.writeToParcel(parcel, 0);
-            flatData = parcel.marshall();
-        } finally {
-            parcel.recycle();
-        }
-        return flatData;
-    }
-
-    static private Bundle unflattenBundle(byte[] flatData) {
-        Bundle bundle;
-        Parcel parcel = Parcel.obtain();
-        try {
-            parcel.unmarshall(flatData, 0, flatData.length);
-            parcel.setDataPosition(0);
-            bundle = parcel.readBundle();
-        } catch (RuntimeException e) {
-            // A RuntimeException is thrown if we were unable to parse the parcel.
-            // Create an empty parcel in this case.
-            bundle = new Bundle();
-        } finally {
-            parcel.recycle();
-        }
-        return bundle;
-    }
-
     private void extrasToXml(XmlSerializer out, Bundle extras) throws java.io.IOException {
         for (String key : extras.keySet()) {
             out.startTag(null, "extra");
@@ -2524,6 +2682,24 @@
         }
     }
 
+    private void requestSync(AuthorityInfo authorityInfo, int reason, Bundle extras) {
+        if (android.os.Process.myUid() == android.os.Process.SYSTEM_UID
+                && mSyncRequestListener != null) {
+            mSyncRequestListener.onSyncRequest(authorityInfo.target, reason, extras);
+        } else {
+            SyncRequest.Builder req =
+                    new SyncRequest.Builder()
+                            .syncOnce()
+                            .setExtras(extras);
+            if (authorityInfo.target.target_provider) {
+                req.setSyncAdapter(authorityInfo.target.account, authorityInfo.target.provider);
+            } else {
+                req.setSyncAdapter(authorityInfo.target.service);
+            }
+            ContentResolver.requestSync(req.build());
+        }
+    }
+
     private void requestSync(Account account, int userId, int reason, String authority,
             Bundle extras) {
         // If this is happening in the system process, then call the syncrequest listener
@@ -2532,7 +2708,10 @@
         // which will know which userId to apply based on the Binder id.
         if (android.os.Process.myUid() == android.os.Process.SYSTEM_UID
                 && mSyncRequestListener != null) {
-            mSyncRequestListener.onSyncRequest(account, userId, reason, authority, extras);
+            mSyncRequestListener.onSyncRequest(
+                new EndPoint(account, authority, userId),
+                reason,
+                extras);
         } else {
             ContentResolver.requestSync(account, authority, extras);
         }
@@ -2628,10 +2807,8 @@
     public void dumpPendingOperations(StringBuilder sb) {
         sb.append("Pending Ops: ").append(mPendingOperations.size()).append(" operation(s)\n");
         for (PendingOperation pop : mPendingOperations) {
-            sb.append("(" + pop.account)
-                .append(", u" + pop.userId)
-                .append(", " + pop.authority)
-                .append(", " + pop.extras)
+            sb.append("(info: " + pop.target.toString())
+                .append(", extras: " + pop.extras)
                 .append(")\n");
         }
     }
diff --git a/services/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 53b8dc4..36ce3a4 100644
--- a/services/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -34,7 +34,6 @@
 import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.AppGlobals;
-import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -52,15 +51,11 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.Signature;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.net.ProxyProperties;
-import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
@@ -88,7 +83,6 @@
 import android.util.SparseArray;
 import android.util.Xml;
 import android.view.IWindowManager;
-import android.view.WindowManagerPolicy;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -98,14 +92,11 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.security.KeyStore.TrustedCertificateEntry;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.text.DateFormat;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
diff --git a/services/java/com/android/server/display/LocalDisplayAdapter.java b/services/java/com/android/server/display/LocalDisplayAdapter.java
index cb8f3e2..02be477 100644
--- a/services/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/java/com/android/server/display/LocalDisplayAdapter.java
@@ -26,7 +26,6 @@
 import android.view.DisplayEventReceiver;
 import android.view.Surface;
 import android.view.SurfaceControl;
-import android.view.SurfaceControl.PhysicalDisplayInfo;
 
 import java.io.PrintWriter;
 
@@ -166,6 +165,12 @@
                     if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
                         mInfo.rotation = Surface.ROTATION_270;
                     }
+
+                    // For demonstration purposes, allow rotation of the external display
+                    // to follow the built-in display.
+                    if (SystemProperties.getBoolean("persist.demo.hdmirotates", false)) {
+                        mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+                    }
                 }
             }
             return mInfo;
diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/java/com/android/server/display/LogicalDisplay.java
index 7e357c0..c26c438 100644
--- a/services/java/com/android/server/display/LogicalDisplay.java
+++ b/services/java/com/android/server/display/LogicalDisplay.java
@@ -258,8 +258,7 @@
         // The orientation specifies how the physical coordinate system of the display
         // is rotated when the contents of the logical display are rendered.
         int orientation = Surface.ROTATION_0;
-        if (device == mPrimaryDisplayDevice
-                && (displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) {
+        if ((displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) {
             orientation = displayInfo.rotation;
         }
 
diff --git a/services/java/com/android/server/firewall/IntentFirewall.java b/services/java/com/android/server/firewall/IntentFirewall.java
index aaa0b58..6df1dbd 100644
--- a/services/java/com/android/server/firewall/IntentFirewall.java
+++ b/services/java/com/android/server/firewall/IntentFirewall.java
@@ -268,11 +268,13 @@
         }
 
         File[] files = rulesDir.listFiles();
-        for (int i=0; i<files.length; i++) {
-            File file = files[i];
+        if (files != null) {
+            for (int i=0; i<files.length; i++) {
+                File file = files[i];
 
-            if (file.getName().endsWith(".xml")) {
-                readRules(file, resolvers);
+                if (file.getName().endsWith(".xml")) {
+                    readRules(file, resolvers);
+                }
             }
         }
 
diff --git a/services/java/com/android/server/location/ComprehensiveCountryDetector.java b/services/java/com/android/server/location/ComprehensiveCountryDetector.java
index 354858b..6117a9b 100644
--- a/services/java/com/android/server/location/ComprehensiveCountryDetector.java
+++ b/services/java/com/android/server/location/ComprehensiveCountryDetector.java
@@ -26,7 +26,6 @@
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
-import android.util.Log;
 import android.util.Slog;
 
 import java.util.Locale;
diff --git a/services/java/com/android/server/location/GeocoderProxy.java b/services/java/com/android/server/location/GeocoderProxy.java
index 5d4a770..422b94b 100644
--- a/services/java/com/android/server/location/GeocoderProxy.java
+++ b/services/java/com/android/server/location/GeocoderProxy.java
@@ -22,7 +22,6 @@
 import android.location.IGeocodeProvider;
 import android.os.Handler;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.server.ServiceWatcher;
diff --git a/services/java/com/android/server/location/GeofenceProxy.java b/services/java/com/android/server/location/GeofenceProxy.java
index bbc1f47..b886eef 100644
--- a/services/java/com/android/server/location/GeofenceProxy.java
+++ b/services/java/com/android/server/location/GeofenceProxy.java
@@ -32,8 +32,6 @@
 import android.util.Log;
 import com.android.server.ServiceWatcher;
 
-import java.util.List;
-
 /**
  * @hide
  */
diff --git a/services/java/com/android/server/location/GpsXtraDownloader.java b/services/java/com/android/server/location/GpsXtraDownloader.java
index e420073..9dedb35 100644
--- a/services/java/com/android/server/location/GpsXtraDownloader.java
+++ b/services/java/com/android/server/location/GpsXtraDownloader.java
@@ -25,7 +25,6 @@
 import org.apache.http.HttpHost;
 import org.apache.http.HttpResponse;
 import org.apache.http.StatusLine;
-import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.conn.params.ConnRouteParams;
diff --git a/services/java/com/android/server/location/LocationFudger.java b/services/java/com/android/server/location/LocationFudger.java
index 2a68743..ae71fe3 100644
--- a/services/java/com/android/server/location/LocationFudger.java
+++ b/services/java/com/android/server/location/LocationFudger.java
@@ -22,10 +22,7 @@
 import android.content.Context;
 import android.database.ContentObserver;
 import android.location.Location;
-import android.location.LocationManager;
-import android.os.Bundle;
 import android.os.Handler;
-import android.os.Parcelable;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.util.Log;
diff --git a/services/java/com/android/server/location/LocationProviderProxy.java b/services/java/com/android/server/location/LocationProviderProxy.java
index 14db862..5eb06ed 100644
--- a/services/java/com/android/server/location/LocationProviderProxy.java
+++ b/services/java/com/android/server/location/LocationProviderProxy.java
@@ -18,7 +18,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.List;
 
 import android.content.Context;
 import android.location.LocationProvider;
diff --git a/services/java/com/android/server/location/MockProvider.java b/services/java/com/android/server/location/MockProvider.java
index 36c43ff..8578761 100644
--- a/services/java/com/android/server/location/MockProvider.java
+++ b/services/java/com/android/server/location/MockProvider.java
@@ -16,7 +16,6 @@
 
 package com.android.server.location;
 
-import android.location.Criteria;
 import android.location.ILocationManager;
 import android.location.Location;
 import android.location.LocationProvider;
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 5d6adc2..271e9e9 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -464,21 +464,21 @@
             private NetworkStatsCollection mUidTagComplete;
 
             private NetworkStatsCollection getUidComplete() {
-                if (mUidComplete == null) {
-                    synchronized (mStatsLock) {
+                synchronized (mStatsLock) {
+                    if (mUidComplete == null) {
                         mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
                     }
+                    return mUidComplete;
                 }
-                return mUidComplete;
             }
 
             private NetworkStatsCollection getUidTagComplete() {
-                if (mUidTagComplete == null) {
-                    synchronized (mStatsLock) {
+                synchronized (mStatsLock) {
+                    if (mUidTagComplete == null) {
                         mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
                     }
+                    return mUidTagComplete;
                 }
-                return mUidTagComplete;
             }
 
             @Override
diff --git a/services/java/com/android/server/pm/Installer.java b/services/java/com/android/server/pm/Installer.java
index 734d071..0d2b503 100644
--- a/services/java/com/android/server/pm/Installer.java
+++ b/services/java/com/android/server/pm/Installer.java
@@ -265,7 +265,7 @@
         return execute(builder.toString());
     }
 
-    public int createUserData(String name, int uid, int userId) {
+    public int createUserData(String name, int uid, int userId, String seinfo) {
         StringBuilder builder = new StringBuilder("mkuserdata");
         builder.append(' ');
         builder.append(name);
@@ -273,6 +273,8 @@
         builder.append(uid);
         builder.append(' ');
         builder.append(userId);
+        builder.append(' ');
+        builder.append(seinfo != null ? seinfo : "!");
         return execute(builder.toString());
     }
 
diff --git a/services/java/com/android/server/pm/KeySetManager.java b/services/java/com/android/server/pm/KeySetManager.java
index 66dc1d1..1056cd0 100644
--- a/services/java/com/android/server/pm/KeySetManager.java
+++ b/services/java/com/android/server/pm/KeySetManager.java
@@ -20,13 +20,11 @@
 import android.content.pm.PackageParser;
 import android.os.Binder;
 import android.util.Base64;
-import android.util.Log;
 import android.util.LongSparseArray;
 
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.security.PublicKey;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
diff --git a/services/java/com/android/server/pm/PackageKeySetData.java b/services/java/com/android/server/pm/PackageKeySetData.java
index cb60621..ebded28 100644
--- a/services/java/com/android/server/pm/PackageKeySetData.java
+++ b/services/java/com/android/server/pm/PackageKeySetData.java
@@ -18,9 +18,7 @@
 
 import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
-import java.util.Set;
 
 public class PackageKeySetData {
 
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 5450fd0..5761f6c 100755
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -3993,7 +3993,7 @@
         for (int user : users) {
             if (user != 0) {
                 res = mInstaller.createUserData(packageName,
-                        UserHandle.getUid(user, uid), user);
+                        UserHandle.getUid(user, uid), user, seinfo);
                 if (res < 0) {
                     return res;
                 }
diff --git a/services/java/com/android/server/pm/PackageSettingBase.java b/services/java/com/android/server/pm/PackageSettingBase.java
index 7747c8f..2a5698b9 100644
--- a/services/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/java/com/android/server/pm/PackageSettingBase.java
@@ -20,14 +20,11 @@
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
 
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageUserState;
-import android.content.pm.UserInfo;
 import android.util.SparseArray;
 
 import java.io.File;
 import java.util.HashSet;
-import java.util.List;
 
 /**
  * Settings base class for pending and resolved classes.
diff --git a/services/java/com/android/server/pm/SELinuxMMAC.java b/services/java/com/android/server/pm/SELinuxMMAC.java
index 04f43d9..83c5d96 100644
--- a/services/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/java/com/android/server/pm/SELinuxMMAC.java
@@ -26,7 +26,6 @@
 import com.android.internal.util.XmlUtils;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 0079b54..ae72280 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -45,7 +45,6 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ComponentInfo;
-import android.content.pm.KeySet;
 import android.content.pm.PackageCleanItem;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageParser;
@@ -60,7 +59,6 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.util.Log;
-import android.util.LongSparseArray;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.Xml;
@@ -71,7 +69,6 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.security.PublicKey;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -2679,7 +2676,8 @@
             ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
             // Need to create a data directory for all apps under this user.
             installer.createUserData(ps.name,
-                    UserHandle.getUid(userHandle, ps.appId), userHandle);
+                    UserHandle.getUid(userHandle, ps.appId), userHandle,
+                    ps.pkg.applicationInfo.seinfo);
         }
         readDefaultPreferredAppsLPw(service, userHandle);
         writePackageRestrictionsLPr(userHandle);
diff --git a/services/java/com/android/server/print/PrintManagerService.java b/services/java/com/android/server/print/PrintManagerService.java
index 98acc27..a475639 100644
--- a/services/java/com/android/server/print/PrintManagerService.java
+++ b/services/java/com/android/server/print/PrintManagerService.java
@@ -399,7 +399,7 @@
     private void registerBoradcastReceivers() {
         PackageMonitor monitor = new PackageMonitor() {
             @Override
-            public boolean onPackageChanged(String packageName, int uid, String[] components) {
+            public void onPackageModified(String packageName) {
                 synchronized (mLock) {
                     UserState userState = getOrCreateUserStateLocked(getChangingUserId());
                     Iterator<ComponentName> iterator = userState.getEnabledServices().iterator();
@@ -407,11 +407,9 @@
                         ComponentName componentName = iterator.next();
                         if (packageName.equals(componentName.getPackageName())) {
                             userState.updateIfNeededLocked();
-                            return true;
                         }
                     }
                 }
-                return false;
             }
 
             @Override
diff --git a/services/java/com/android/server/print/UserState.java b/services/java/com/android/server/print/UserState.java
index f23a992..43757f9 100644
--- a/services/java/com/android/server/print/UserState.java
+++ b/services/java/com/android/server/print/UserState.java
@@ -657,7 +657,33 @@
             tempPrintServices.add(PrintServiceInfo.create(installedService, mContext));
         }
 
-        if (!tempPrintServices.equals(mInstalledServices)) {
+        boolean someServiceChanged = false;
+
+        if (tempPrintServices.size() != mInstalledServices.size()) {
+            someServiceChanged = true;
+        } else {
+            for (PrintServiceInfo newService: tempPrintServices) {
+                final int oldServiceIndex = mInstalledServices.indexOf(newService);
+                if (oldServiceIndex < 0) {
+                    someServiceChanged = true;
+                    break;
+                }
+                // PrintServiceInfo#equals compares only the id not all members,
+                // so we are also comparing the members coming from meta-data.
+                PrintServiceInfo oldService = mInstalledServices.get(oldServiceIndex);
+                if (!TextUtils.equals(oldService.getAddPrintersActivityName(),
+                            newService.getAddPrintersActivityName())
+                        || !TextUtils.equals(oldService.getAdvancedOptionsActivityName(),
+                                newService.getAdvancedOptionsActivityName())
+                        || !TextUtils.equals(oldService.getSettingsActivityName(),
+                                newService.getSettingsActivityName())) {
+                    someServiceChanged = true;
+                    break;
+                }
+            }
+        }
+
+        if (someServiceChanged) {
             mInstalledServices.clear();
             mInstalledServices.addAll(tempPrintServices);
             return true;
diff --git a/services/java/com/android/server/search/SearchManagerService.java b/services/java/com/android/server/search/SearchManagerService.java
index b5d81d1..486477a 100644
--- a/services/java/com/android/server/search/SearchManagerService.java
+++ b/services/java/com/android/server/search/SearchManagerService.java
@@ -17,7 +17,6 @@
 package com.android.server.search;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.ISearchManager;
 import android.app.SearchManager;
@@ -39,7 +38,6 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.util.Log;
-import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.content.PackageMonitor;
diff --git a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
index 9601e9a..1a68fb3 100644
--- a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
+++ b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.provider.Settings;
-import android.os.FileUtils;
 import android.util.Base64;
 import android.util.EventLog;
 import android.util.Slog;
@@ -30,18 +29,15 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.IOException;
-import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.Signature;
-import java.security.SignatureException;
 
 import libcore.io.IoUtils;
 
diff --git a/services/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java b/services/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
index 5dd30f1..fdc604f 100644
--- a/services/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
+++ b/services/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
@@ -18,8 +18,6 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.os.FileUtils;
-import android.os.SELinux;
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.util.Base64;
@@ -125,25 +123,11 @@
         SystemProperties.set("selinux.reload_policy", "1");
     }
 
-    private void setEnforcingMode(Context context) {
-        String mode = Settings.Global.getString(context.getContentResolver(),
-            Settings.Global.SELINUX_STATUS);
-        if ("1".equals(mode)) {
-            Slog.i(TAG, "Setting enforcing mode");
-            SystemProperties.set("persist.selinux.enforcing", mode);
-        } else if ("0".equals(mode)) {
-            Slog.i(TAG, "Tried to set permissive mode, ignoring");
-        } else {
-            Slog.e(TAG, "Got invalid enforcing mode: " + mode);
-        }
-    }
-
     @Override
     protected void postInstall(Context context, Intent intent) {
         try {
             unpackBundle();
             applyUpdate();
-            setEnforcingMode(context);
         } catch (IllegalArgumentException e) {
             Slog.e(TAG, "SELinux policy update malformed: ", e);
         } catch (IOException e) {
diff --git a/services/java/com/android/server/updates/TZInfoInstallReceiver.java b/services/java/com/android/server/updates/TZInfoInstallReceiver.java
index 83adbdb..2fe68f8 100644
--- a/services/java/com/android/server/updates/TZInfoInstallReceiver.java
+++ b/services/java/com/android/server/updates/TZInfoInstallReceiver.java
@@ -17,7 +17,6 @@
 package com.android.server.updates;
 
 import android.util.Base64;
-import android.util.Slog;
 
 import java.io.IOException;
 
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index f2efde1..4b5c567 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -45,7 +45,6 @@
 import android.os.Messenger;
 import android.os.HandlerThread;
 import android.os.IBinder;
-import android.os.INetworkManagementService;
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.SystemProperties;
@@ -53,7 +52,6 @@
 import android.os.WorkSource;
 import android.os.AsyncTask;
 import android.provider.Settings;
-import android.util.Log;
 import android.util.Slog;
 
 import java.io.FileNotFoundException;
@@ -66,11 +64,8 @@
 import java.net.InetAddress;
 import java.net.Inet4Address;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 
-import java.util.concurrent.atomic.AtomicBoolean;
-
 import com.android.internal.R;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.telephony.TelephonyIntents;
@@ -984,11 +979,6 @@
         mWifiStateMachine.reconnectCommand();
     }
 
-    public void captivePortalCheckComplete() {
-        enforceConnectivityInternalPermission();
-        mWifiStateMachine.captivePortalCheckComplete();
-    }
-
     /**
      * see {@link android.net.wifi.WifiManager#stopWifi}
      *
diff --git a/services/java/com/android/server/wifi/WifiTrafficPoller.java b/services/java/com/android/server/wifi/WifiTrafficPoller.java
index b498550..5678086 100644
--- a/services/java/com/android/server/wifi/WifiTrafficPoller.java
+++ b/services/java/com/android/server/wifi/WifiTrafficPoller.java
@@ -26,7 +26,6 @@
 import android.net.wifi.WifiManager;
 import android.os.Messenger;
 import android.os.RemoteException;
-import android.util.Log;
 import android.os.Handler;
 import android.os.Message;
 
@@ -36,8 +35,6 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import com.android.internal.util.AsyncChannel;
-
 /* Polls for traffic stats and notifies the clients */
 final class WifiTrafficPoller {
     /**
diff --git a/services/java/com/android/server/wm/DimLayer.java b/services/java/com/android/server/wm/DimLayer.java
index 978d5b7..c189ddd 100644
--- a/services/java/com/android/server/wm/DimLayer.java
+++ b/services/java/com/android/server/wm/DimLayer.java
@@ -166,7 +166,7 @@
 
         final int dw, dh;
         final float xPos, yPos;
-        if (!mStack.isFullscreen()) {
+        if (mStack.hasSibling()) {
             dw = mBounds.width();
             dh = mBounds.height();
             xPos = mBounds.left;
diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java
index 4352ece..d358b4c 100644
--- a/services/java/com/android/server/wm/DisplayContent.java
+++ b/services/java/com/android/server/wm/DisplayContent.java
@@ -21,8 +21,10 @@
 import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerService.TAG;
 
+import android.app.ActivityManager.StackBoxInfo;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.os.Debug;
 import android.util.EventLog;
 import android.util.Slog;
 import android.view.Display;
@@ -72,7 +74,6 @@
     private final Display mDisplay;
 
     Rect mBaseDisplayRect = new Rect();
-    Rect mContentRect = new Rect();
 
     // Accessed directly by all users.
     boolean layoutNeeded;
@@ -91,12 +92,11 @@
      */
     final AppTokenList mExitingAppTokens = new AppTokenList();
 
-    /** Array containing all TaskStacks on this display.  Array
+    /** Array containing the home StackBox and possibly one more which would contain apps. Array
      * is stored in display order with the current bottom stack at 0. */
-    private ArrayList<TaskStack> mStacks = new ArrayList<TaskStack>();
+    private ArrayList<StackBox> mStackBoxes = new ArrayList<StackBox>();
 
-    /** A special TaskStack with id==HOME_STACK_ID that moves to the bottom whenever any TaskStack
-     * (except a future lockscreen TaskStack) moves to the top. */
+    /** True when the home StackBox is at the top of mStackBoxes, false otherwise. */
     private TaskStack mHomeStack = null;
 
     /** Detect user tapping outside of current focused stack bounds .*/
@@ -123,6 +123,13 @@
         display.getDisplayInfo(mDisplayInfo);
         isDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY;
         mService = service;
+
+        StackBox newBox = new StackBox(service, this, null);
+        mStackBoxes.add(newBox);
+        TaskStack newStack = new TaskStack(service, HOME_STACK_ID, this);
+        newStack.mStackBox = newBox;
+        newBox.mStack = newStack;
+        mHomeStack = newStack;
     }
 
     int getDisplayId() {
@@ -148,6 +155,10 @@
         return mDisplay.hasAccess(uid);
     }
 
+    boolean homeOnTop() {
+        return mStackBoxes.get(0).mStack != mHomeStack;
+    }
+
     public boolean isPrivate() {
         return (mDisplay.getFlags() & Display.FLAG_PRIVATE) != 0;
     }
@@ -194,18 +205,7 @@
     }
 
     void updateDisplayInfo() {
-        // Save old size.
-        int oldWidth = mDisplayInfo.logicalWidth;
-        int oldHeight = mDisplayInfo.logicalHeight;
         mDisplay.getDisplayInfo(mDisplayInfo);
-
-        for (int i = mStacks.size() - 1; i >= 0; --i) {
-            final TaskStack stack = mStacks.get(i);
-            if (!stack.isFullscreen()) {
-                stack.resizeBounds(oldWidth, oldHeight, mDisplayInfo.logicalWidth,
-                        mDisplayInfo.logicalHeight);
-            }
-        }
     }
 
     void getLogicalDisplayRect(Rect out) {
@@ -227,58 +227,159 @@
         return count;
     }
 
-    /** Refer to {@link WindowManagerService#createStack(int, int)} */
-    TaskStack createStack(int stackId) {
-        if (DEBUG_STACK) Slog.d(TAG, "createStack: stackId=" + stackId);
-        TaskStack newStack = new TaskStack(mService, stackId, this);
+    /** Refer to {@link WindowManagerService#createStack(int, int, int, float)} */
+    TaskStack createStack(int stackId, int relativeStackBoxId, int position, float weight) {
+        TaskStack newStack = null;
+        if (DEBUG_STACK) Slog.d(TAG, "createStack: stackId=" + stackId + " relativeStackBoxId="
+                + relativeStackBoxId + " position=" + position + " weight=" + weight);
         if (stackId == HOME_STACK_ID) {
-            if (mHomeStack != null) {
+            if (mStackBoxes.size() != 1) {
                 throw new IllegalArgumentException("createStack: HOME_STACK_ID (0) not first.");
             }
-            mHomeStack = newStack;
+            newStack = mHomeStack;
+        } else {
+            int stackBoxNdx;
+            for (stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+                final StackBox box = mStackBoxes.get(stackBoxNdx);
+                if (position == StackBox.TASK_STACK_GOES_OVER
+                        || position == StackBox.TASK_STACK_GOES_UNDER) {
+                    // Position indicates a new box is added at top level only.
+                    if (box.contains(relativeStackBoxId)) {
+                        StackBox newBox = new StackBox(mService, this, null);
+                        newStack = new TaskStack(mService, stackId, this);
+                        newStack.mStackBox = newBox;
+                        newBox.mStack = newStack;
+                        final int offset = position == StackBox.TASK_STACK_GOES_OVER ? 1 : 0;
+                        if (DEBUG_STACK) Slog.d(TAG, "createStack: inserting stack at " +
+                                (stackBoxNdx + offset));
+                        mStackBoxes.add(stackBoxNdx + offset, newBox);
+                        break;
+                    }
+                } else {
+                    // Remaining position values indicate a box must be split.
+                    newStack = box.split(stackId, relativeStackBoxId, position, weight);
+                    if (newStack != null) {
+                        break;
+                    }
+                }
+            }
+            if (stackBoxNdx < 0) {
+                throw new IllegalArgumentException("createStack: stackBoxId " + relativeStackBoxId
+                        + " not found.");
+            }
         }
-        mStacks.add(newStack);
-        layoutNeeded = true;
+        if (newStack != null) {
+            layoutNeeded = true;
+        }
+        EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, relativeStackBoxId, position,
+                (int)(weight * 100 + 0.5));
         return newStack;
     }
 
-    void moveStack(TaskStack stack, boolean toTop) {
-        mStacks.remove(stack);
-        mStacks.add(toTop ? mStacks.size() : 0, stack);
-    }
-
-    TaskStack topStack() {
-        return mStacks.get(mStacks.size() - 1);
-    }
-
-    /**
-     * Propagate the new bounds to all child stacks.
-     * @param contentRect The bounds to apply at the top level.
-     */
-    void resize(Rect contentRect) {
-        mContentRect.set(contentRect);
-    }
-
-    boolean getStackBounds(int stackId, Rect bounds) {
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            final TaskStack stack = mStacks.get(stackNdx);
-            if (stackId == stack.mStackId) {
-                bounds.set(stack.mBounds);
+    /** Refer to {@link WindowManagerService#resizeStackBox(int, float)} */
+    boolean resizeStack(int stackBoxId, float weight) {
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            final StackBox box = mStackBoxes.get(stackBoxNdx);
+            if (box.resize(stackBoxId, weight)) {
+                layoutNeeded = true;
                 return true;
             }
         }
         return false;
     }
 
-    int stackIdFromPoint(int x, int y) {
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            final TaskStack stack = mStacks.get(stackNdx);
-            stack.getBounds(mTmpRect);
-            if (mTmpRect.contains(x, y)) {
-                return stack.mStackId;
+    void addStackBox(StackBox box, boolean toTop) {
+        if (mStackBoxes.size() >= 2) {
+            throw new RuntimeException("addStackBox: Too many toplevel StackBoxes!");
+        }
+        mStackBoxes.add(toTop ? mStackBoxes.size() : 0, box);
+    }
+
+    void removeStackBox(StackBox box) {
+        if (DEBUG_STACK) Slog.d(TAG, "removeStackBox: box=" + box);
+        final TaskStack stack = box.mStack;
+        if (stack != null && stack.mStackId == HOME_STACK_ID) {
+            // Never delete the home stack, even if it is empty.
+            if (DEBUG_STACK) Slog.d(TAG, "removeStackBox: Not deleting home stack.");
+            return;
+        }
+        mStackBoxes.remove(box);
+    }
+
+    StackBoxInfo getStackBoxInfo(StackBox box) {
+        StackBoxInfo info = new StackBoxInfo();
+        info.stackBoxId = box.mStackBoxId;
+        info.weight = box.mWeight;
+        info.vertical = box.mVertical;
+        info.bounds = new Rect(box.mBounds);
+        if (box.mStack != null) {
+            info.stackId = box.mStack.mStackId;
+            // ActivityManagerService will fill in the StackInfo.
+        } else {
+            info.stackId = -1;
+            info.children = new StackBoxInfo[2];
+            info.children[0] = getStackBoxInfo(box.mFirst);
+            info.children[1] = getStackBoxInfo(box.mSecond);
+        }
+        return info;
+    }
+
+    ArrayList<StackBoxInfo> getStackBoxInfos() {
+        ArrayList<StackBoxInfo> list = new ArrayList<StackBoxInfo>();
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            list.add(getStackBoxInfo(mStackBoxes.get(stackBoxNdx)));
+        }
+        return list;
+    }
+
+    /**
+     * Move the home StackBox to the top or bottom of mStackBoxes. That is the only place
+     * it is allowed to be. This is a nop if the home StackBox is already in the correct position.
+     * @param toTop Move home to the top of mStackBoxes if true, to the bottom if false.
+     * @return true if a change was made, false otherwise.
+     */
+    boolean moveHomeStackBox(boolean toTop) {
+        if (DEBUG_STACK) Slog.d(TAG, "moveHomeStackBox: toTop=" + toTop + " Callers=" +
+                Debug.getCallers(4));
+        EventLog.writeEvent(EventLogTags.WM_HOME_STACK_MOVED, toTop ? 1 : 0);
+        switch (mStackBoxes.size()) {
+            case 0: throw new RuntimeException("moveHomeStackBox: No home StackBox!");
+            case 1: return false; // Only the home StackBox exists.
+            case 2:
+                if (homeOnTop() ^ toTop) {
+                    mStackBoxes.add(mStackBoxes.remove(0));
+                    return true;
+                }
+                return false;
+            default: throw new RuntimeException("moveHomeStackBox: Too many toplevel StackBoxes!");
+        }
+    }
+
+    /**
+     * Propagate the new bounds to all child stack boxes, applying weights as we move down.
+     * @param contentRect The bounds to apply at the top level.
+     */
+    boolean setStackBoxSize(Rect contentRect) {
+        boolean change = false;
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            change |= mStackBoxes.get(stackBoxNdx).setStackBoxSizes(contentRect, true);
+        }
+        return change;
+    }
+
+    Rect getStackBounds(int stackId) {
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            Rect bounds = mStackBoxes.get(stackBoxNdx).getStackBounds(stackId);
+            if (bounds != null) {
+                return bounds;
             }
         }
-        return -1;
+        return null;
+    }
+
+    int stackIdFromPoint(int x, int y) {
+        StackBox topBox = mStackBoxes.get(mStackBoxes.size() - 1);
+        return topBox.stackIdFromPoint(x, y);
     }
 
     void setTouchExcludeRegion(TaskStack focusedStack) {
@@ -307,48 +408,48 @@
             }
         }
 
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            mStacks.get(stackNdx).switchUser(newUserId);
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            mStackBoxes.get(stackBoxNdx).switchUserStacks(newUserId);
         }
     }
 
     void resetAnimationBackgroundAnimator() {
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            mStacks.get(stackNdx).resetAnimationBackgroundAnimator();
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            mStackBoxes.get(stackBoxNdx).resetAnimationBackgroundAnimator();
         }
     }
 
     boolean animateDimLayers() {
         boolean result = false;
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            result |= mStacks.get(stackNdx).animateDimLayers();
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            result |= mStackBoxes.get(stackBoxNdx).animateDimLayers();
         }
         return result;
     }
 
     void resetDimming() {
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            mStacks.get(stackNdx).resetDimmingTag();
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            mStackBoxes.get(stackBoxNdx).resetDimming();
         }
     }
 
     boolean isDimming() {
         boolean result = false;
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            result |= mStacks.get(stackNdx).isDimming();
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            result |= mStackBoxes.get(stackBoxNdx).isDimming();
         }
         return result;
     }
 
     void stopDimmingIfNeeded() {
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            mStacks.get(stackNdx).stopDimmingIfNeeded();
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            mStackBoxes.get(stackBoxNdx).stopDimmingIfNeeded();
         }
     }
 
     void close() {
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            mStacks.get(stackNdx).close();
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            mStackBoxes.get(stackBoxNdx).close();
         }
     }
 
@@ -376,10 +477,9 @@
             pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
             pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
             pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded);
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            final TaskStack stack = mStacks.get(stackNdx);
-            pw.print(prefix); pw.print("mStacks[" + stackNdx + "]"); pw.println(stack.mStackId);
-            stack.dump(prefix + "  ", pw);
+        for (int boxNdx = 0; boxNdx < mStackBoxes.size(); ++boxNdx) {
+            pw.print(prefix); pw.print("StackBox #"); pw.println(boxNdx);
+            mStackBoxes.get(boxNdx).dump(prefix + "  ", pw);
         }
         int ndx = numTokens();
         if (ndx > 0) {
diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java
index a737939..edc7c93 100644
--- a/services/java/com/android/server/wm/DragState.java
+++ b/services/java/com/android/server/wm/DragState.java
@@ -33,7 +33,6 @@
 import android.view.Display;
 import android.view.DragEvent;
 import android.view.InputChannel;
-import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.WindowManager;
diff --git a/services/java/com/android/server/wm/FakeWindowImpl.java b/services/java/com/android/server/wm/FakeWindowImpl.java
index 5a3471b..c18ea01 100644
--- a/services/java/com/android/server/wm/FakeWindowImpl.java
+++ b/services/java/com/android/server/wm/FakeWindowImpl.java
@@ -21,11 +21,9 @@
 
 import android.os.Looper;
 import android.os.Process;
-import android.util.Slog;
 import android.view.Display;
 import android.view.InputChannel;
 import android.view.InputEventReceiver;
-import android.view.InputQueue;
 import android.view.WindowManagerPolicy;
 
 public final class FakeWindowImpl implements WindowManagerPolicy.FakeWindow {
diff --git a/services/java/com/android/server/wm/FocusedStackFrame.java b/services/java/com/android/server/wm/FocusedStackFrame.java
index f1f5fe8..cc48b86 100644
--- a/services/java/com/android/server/wm/FocusedStackFrame.java
+++ b/services/java/com/android/server/wm/FocusedStackFrame.java
@@ -41,7 +41,7 @@
     private final SurfaceControl mSurfaceControl;
     private final Surface mSurface = new Surface();
     private final Rect mLastBounds = new Rect();
-    final Rect mBounds = new Rect();
+    private final Rect mBounds = new Rect();
     private final Rect mTmpDrawRect = new Rect();
 
     public FocusedStackFrame(Display display, SurfaceSession session) {
@@ -131,9 +131,9 @@
         }
     }
 
-    public void setBounds(TaskStack stack) {
-        stack.getBounds(mBounds);
-        if (false && DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + mBounds);
+    public void setBounds(Rect bounds) {
+        if (false && DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + bounds);
+        mBounds.set(bounds);
     }
 
     public void setLayer(int layer) {
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index 803b9ac..3d2ec45 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -58,8 +58,6 @@
     private final Object mInputDevicesReadyMonitor = new Object();
     private boolean mInputDevicesReady;
 
-    Rect mTmpRect = new Rect();
-
     public InputMonitor(WindowManagerService service) {
         mService = service;
     }
@@ -177,8 +175,7 @@
         if (modal && child.mAppToken != null) {
             // Limit the outer touch to the activity stack region.
             flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-            child.getStackBounds(mTmpRect);
-            inputWindowHandle.touchableRegion.set(mTmpRect);
+            inputWindowHandle.touchableRegion.set(child.getStackBounds());
         } else {
             // Not modal or full screen modal
             child.getTouchableRegion(inputWindowHandle.touchableRegion);
diff --git a/services/java/com/android/server/wm/KeyguardDisableHandler.java b/services/java/com/android/server/wm/KeyguardDisableHandler.java
index 859df51..c1420a8 100644
--- a/services/java/com/android/server/wm/KeyguardDisableHandler.java
+++ b/services/java/com/android/server/wm/KeyguardDisableHandler.java
@@ -24,7 +24,6 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.TokenWatcher;
-import android.os.UserHandle;
 import android.util.Log;
 import android.util.Pair;
 import android.view.WindowManagerPolicy;
diff --git a/services/java/com/android/server/wm/StackBox.java b/services/java/com/android/server/wm/StackBox.java
new file mode 100644
index 0000000..d351925
--- /dev/null
+++ b/services/java/com/android/server/wm/StackBox.java
@@ -0,0 +1,414 @@
+/*
+ * 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.server.wm;
+
+import android.graphics.Rect;
+import android.util.Slog;
+
+import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
+import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
+import static com.android.server.wm.WindowManagerService.TAG;
+
+import java.io.PrintWriter;
+
+public class StackBox {
+    /** Used with {@link WindowManagerService#createStack}. Dependent on Configuration LTR/RTL. */
+    public static final int TASK_STACK_GOES_BEFORE = 0;
+    /** Used with {@link WindowManagerService#createStack}. Dependent on Configuration LTR/RTL. */
+    public static final int TASK_STACK_GOES_AFTER = 1;
+    /** Used with {@link WindowManagerService#createStack}. Horizontal to left of. */
+    public static final int TASK_STACK_TO_LEFT_OF = 2;
+    /** Used with {@link WindowManagerService#createStack}. Horizontal to right of. */
+    public static final int TASK_STACK_TO_RIGHT_OF = 3;
+    /** Used with {@link WindowManagerService#createStack}. Vertical: lower t/b Rect values. */
+    public static final int TASK_STACK_GOES_ABOVE = 4;
+    /** Used with {@link WindowManagerService#createStack}. Vertical: higher t/b Rect values. */
+    public static final int TASK_STACK_GOES_BELOW = 5;
+    /** Used with {@link WindowManagerService#createStack}. Put on a higher layer on display. */
+    public static final int TASK_STACK_GOES_OVER = 6;
+    /** Used with {@link WindowManagerService#createStack}. Put on a lower layer on display. */
+    public static final int TASK_STACK_GOES_UNDER = 7;
+
+    static int sCurrentBoxId = 0;
+
+    /** Unique id for this box */
+    final int mStackBoxId;
+
+    /** The service */
+    final WindowManagerService mService;
+
+    /** The display this box sits in. */
+    final DisplayContent mDisplayContent;
+
+    /** Non-null indicates this is mFirst or mSecond of a parent StackBox. Null indicates this
+     * is this entire size of mDisplayContent. */
+    StackBox mParent;
+
+    /** First child, this is null exactly when mStack is non-null. */
+    StackBox mFirst;
+
+    /** Second child, this is null exactly when mStack is non-null. */
+    StackBox mSecond;
+
+    /** Stack of Tasks, this is null exactly when mFirst and mSecond are non-null. */
+    TaskStack mStack;
+
+    /** Content limits relative to the DisplayContent this sits in. */
+    Rect mBounds = new Rect();
+
+    /** Relative orientation of mFirst and mSecond. */
+    boolean mVertical;
+
+    /** Fraction of mBounds to devote to mFirst, remainder goes to mSecond */
+    float mWeight;
+
+    /** Dirty flag. Something inside this or some descendant of this has changed. */
+    boolean layoutNeeded;
+
+    /** True if this StackBox sits below the Status Bar. */
+    boolean mUnderStatusBar;
+
+    /** Used to keep from reallocating a temporary Rect for propagating bounds to child boxes */
+    Rect mTmpRect = new Rect();
+
+    StackBox(WindowManagerService service, DisplayContent displayContent, StackBox parent) {
+        synchronized (StackBox.class) {
+            mStackBoxId = sCurrentBoxId++;
+        }
+
+        mService = service;
+        mDisplayContent = displayContent;
+        mParent = parent;
+    }
+
+    /** Propagate #layoutNeeded bottom up. */
+    void makeDirty() {
+        layoutNeeded = true;
+        if (mParent != null) {
+            mParent.makeDirty();
+        }
+    }
+
+    /**
+     * Determine if a particular StackBox is this one or a descendant of this one.
+     * @param stackBoxId The StackBox being searched for.
+     * @return true if the specified StackBox matches this or one of its descendants.
+     */
+    boolean contains(int stackBoxId) {
+        return mStackBoxId == stackBoxId ||
+                (mStack == null &&  (mFirst.contains(stackBoxId) || mSecond.contains(stackBoxId)));
+    }
+
+    /**
+     * Return the stackId of the stack that intersects the passed point.
+     * @param x coordinate of point.
+     * @param y coordinate of point.
+     * @return -1 if point is outside of mBounds, otherwise the stackId of the containing stack.
+     */
+    int stackIdFromPoint(int x, int y) {
+        if (!mBounds.contains(x, y)) {
+            return -1;
+        }
+        if (mStack != null) {
+            return mStack.mStackId;
+        }
+        int stackId = mFirst.stackIdFromPoint(x, y);
+        if (stackId >= 0) {
+            return stackId;
+        }
+        return mSecond.stackIdFromPoint(x, y);
+    }
+
+    /** Determine if this StackBox is the first child or second child.
+     * @return true if this is the first child.
+     */
+    boolean isFirstChild() {
+        return mParent != null && mParent.mFirst == this;
+    }
+
+    /** Returns the bounds of the specified TaskStack if it is contained in this StackBox.
+     * @param stackId the TaskStack to find the bounds of.
+     * @return a new Rect with the bounds of stackId if it is within this StackBox, null otherwise.
+     */
+    Rect getStackBounds(int stackId) {
+        if (mStack != null) {
+            return mStack.mStackId == stackId ? new Rect(mBounds) : null;
+        }
+        Rect bounds = mFirst.getStackBounds(stackId);
+        if (bounds != null) {
+            return bounds;
+        }
+        return mSecond.getStackBounds(stackId);
+    }
+
+    /**
+     * Create a new TaskStack relative to a specified one by splitting the StackBox containing
+     * the specified TaskStack into two children. The size and position each of the new StackBoxes
+     * is determined by the passed parameters.
+     * @param stackId The id of the new TaskStack to create.
+     * @param relativeStackBoxId The id of the StackBox to place the new TaskStack next to.
+     * @param position One of the static TASK_STACK_GOES_xxx positions defined in this class.
+     * @param weight The percentage size of the parent StackBox to devote to the new TaskStack.
+     * @return The new TaskStack.
+     */
+    TaskStack split(int stackId, int relativeStackBoxId, int position, float weight) {
+        if (mStackBoxId != relativeStackBoxId) {
+            // This is not the targeted StackBox.
+            if (mStack != null) {
+                return null;
+            }
+            // Propagate the split to see if the targeted StackBox is in either sub box.
+            TaskStack stack = mFirst.split(stackId, relativeStackBoxId, position, weight);
+            if (stack != null) {
+                return stack;
+            }
+            return mSecond.split(stackId, relativeStackBoxId, position, weight);
+        }
+
+        // Found it!
+        TaskStack stack = new TaskStack(mService, stackId, mDisplayContent);
+        TaskStack firstStack;
+        TaskStack secondStack;
+        if (position == TASK_STACK_GOES_BEFORE) {
+            // TODO: Test Configuration here for LTR/RTL.
+            position = TASK_STACK_TO_LEFT_OF;
+        } else if (position == TASK_STACK_GOES_AFTER) {
+            // TODO: Test Configuration here for LTR/RTL.
+            position = TASK_STACK_TO_RIGHT_OF;
+        }
+        switch (position) {
+            default:
+            case TASK_STACK_TO_LEFT_OF:
+            case TASK_STACK_TO_RIGHT_OF:
+                mVertical = false;
+                if (position == TASK_STACK_TO_LEFT_OF) {
+                    mWeight = weight;
+                    firstStack = stack;
+                    secondStack = mStack;
+                } else {
+                    mWeight = 1.0f - weight;
+                    firstStack = mStack;
+                    secondStack = stack;
+                }
+                break;
+            case TASK_STACK_GOES_ABOVE:
+            case TASK_STACK_GOES_BELOW:
+                mVertical = true;
+                if (position == TASK_STACK_GOES_ABOVE) {
+                    mWeight = weight;
+                    firstStack = stack;
+                    secondStack = mStack;
+                } else {
+                    mWeight = 1.0f - weight;
+                    firstStack = mStack;
+                    secondStack = stack;
+                }
+                break;
+        }
+
+        mFirst = new StackBox(mService, mDisplayContent, this);
+        firstStack.mStackBox = mFirst;
+        mFirst.mStack = firstStack;
+
+        mSecond = new StackBox(mService, mDisplayContent, this);
+        secondStack.mStackBox = mSecond;
+        mSecond.mStack = secondStack;
+
+        mStack = null;
+        return stack;
+    }
+
+    /** Return the stackId of the first mFirst StackBox with a non-null mStack */
+    int getStackId() {
+        if (mStack != null) {
+            return mStack.mStackId;
+        }
+        return mFirst.getStackId();
+    }
+
+    /** Remove this box and propagate its sibling's content up to their parent.
+     * @return The first stackId of the resulting StackBox. */
+    int remove() {
+        mDisplayContent.layoutNeeded = true;
+
+        if (mParent == null) {
+            // This is the top-plane stack.
+            if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: removing top plane.");
+            mDisplayContent.removeStackBox(this);
+            return HOME_STACK_ID;
+        }
+
+        StackBox sibling = isFirstChild() ? mParent.mSecond : mParent.mFirst;
+        StackBox grandparent = mParent.mParent;
+        sibling.mParent = grandparent;
+        if (grandparent == null) {
+            // mParent is a top-plane stack. Now sibling will be.
+            if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: grandparent null");
+            mDisplayContent.removeStackBox(mParent);
+            mDisplayContent.addStackBox(sibling, true);
+        } else {
+            if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: grandparent getting sibling");
+            if (mParent.isFirstChild()) {
+                grandparent.mFirst = sibling;
+            } else {
+                grandparent.mSecond = sibling;
+            }
+        }
+        return sibling.getStackId();
+    }
+
+    boolean resize(int stackBoxId, float weight) {
+        if (mStackBoxId != stackBoxId) {
+            return mStack == null &&
+                    (mFirst.resize(stackBoxId, weight) || mSecond.resize(stackBoxId, weight));
+        }
+        // Don't change weight on topmost stack.
+        if (mParent != null) {
+            mParent.mWeight = isFirstChild() ? weight : 1.0f - weight;
+        }
+        return true;
+    }
+
+    /** If this is a terminal StackBox (contains a TaskStack) set the bounds.
+     * @param bounds The rectangle to set the bounds to.
+     * @param underStatusBar True if the StackBox is directly below the Status Bar.
+     * @return True if the bounds changed, false otherwise. */
+    boolean setStackBoxSizes(Rect bounds, boolean underStatusBar) {
+        boolean change = false;
+        if (mUnderStatusBar != underStatusBar) {
+            change = true;
+            mUnderStatusBar = underStatusBar;
+        }
+        if (mStack != null) {
+            change |= !mBounds.equals(bounds);
+            if (change) {
+                mBounds.set(bounds);
+                mStack.setBounds(bounds, underStatusBar);
+            }
+        } else {
+            mTmpRect.set(bounds);
+            if (mVertical) {
+                final int height = bounds.height();
+                int firstHeight = (int)(height * mWeight);
+                mTmpRect.bottom = bounds.top + firstHeight;
+                change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar);
+                mTmpRect.top = mTmpRect.bottom;
+                mTmpRect.bottom = bounds.top + height;
+                change |= mSecond.setStackBoxSizes(mTmpRect, false);
+            } else {
+                final int width = bounds.width();
+                int firstWidth = (int)(width * mWeight);
+                mTmpRect.right = bounds.left + firstWidth;
+                change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar);
+                mTmpRect.left = mTmpRect.right;
+                mTmpRect.right = bounds.left + width;
+                change |= mSecond.setStackBoxSizes(mTmpRect, underStatusBar);
+            }
+        }
+        return change;
+    }
+
+    void resetAnimationBackgroundAnimator() {
+        if (mStack != null) {
+            mStack.resetAnimationBackgroundAnimator();
+            return;
+        }
+        mFirst.resetAnimationBackgroundAnimator();
+        mSecond.resetAnimationBackgroundAnimator();
+    }
+
+    boolean animateDimLayers() {
+        if (mStack != null) {
+            return mStack.animateDimLayers();
+        }
+        boolean result = mFirst.animateDimLayers();
+        result |= mSecond.animateDimLayers();
+        return result;
+    }
+
+    void resetDimming() {
+        if (mStack != null) {
+            mStack.resetDimmingTag();
+            return;
+        }
+        mFirst.resetDimming();
+        mSecond.resetDimming();
+    }
+
+    boolean isDimming() {
+        if (mStack != null) {
+            return mStack.isDimming();
+        }
+        boolean result = mFirst.isDimming();
+        result |= mSecond.isDimming();
+        return result;
+    }
+
+    void stopDimmingIfNeeded() {
+        if (mStack != null) {
+            mStack.stopDimmingIfNeeded();
+            return;
+        }
+        mFirst.stopDimmingIfNeeded();
+        mSecond.stopDimmingIfNeeded();
+    }
+
+    void switchUserStacks(int userId) {
+        if (mStack != null) {
+            mStack.switchUser(userId);
+            return;
+        }
+        mFirst.switchUserStacks(userId);
+        mSecond.switchUserStacks(userId);
+    }
+
+    void close() {
+        if (mStack != null) {
+            mStack.mDimLayer.mDimSurface.destroy();
+            mStack.mAnimationBackgroundSurface.mDimSurface.destroy();
+            return;
+        }
+        mFirst.close();
+        mSecond.close();
+    }
+
+    public void dump(String prefix, PrintWriter pw) {
+        pw.print(prefix); pw.print("mParent="); pw.println(mParent);
+        pw.print(prefix); pw.print("mBounds="); pw.print(mBounds.toShortString());
+            pw.print(" mVertical="); pw.print(mVertical);
+            pw.print(" layoutNeeded="); pw.println(layoutNeeded);
+        if (mFirst != null) {
+            pw.print(prefix); pw.print("mFirst="); pw.println(System.identityHashCode(mFirst));
+            mFirst.dump(prefix + "  ", pw);
+            pw.print(prefix); pw.print("mSecond="); pw.println(System.identityHashCode(mSecond));
+            mSecond.dump(prefix + "  ", pw);
+        } else {
+            pw.print(prefix); pw.print("mStack="); pw.println(mStack);
+            mStack.dump(prefix + "  ", pw);
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (mStack != null) {
+            return "Box{" + hashCode() + " stack=" + mStack.mStackId + "}";
+        }
+        return "Box{" + hashCode() + " parent=" + System.identityHashCode(mParent)
+                + " first=" + System.identityHashCode(mFirst)
+                + " second=" + System.identityHashCode(mSecond) + "}";
+    }
+}
diff --git a/services/java/com/android/server/wm/Task.java b/services/java/com/android/server/wm/Task.java
index 13fdbc8..a1704a6 100644
--- a/services/java/com/android/server/wm/Task.java
+++ b/services/java/com/android/server/wm/Task.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import android.util.EventLog;
-import com.android.server.EventLogTags;
 
 class Task {
 //    private final String TAG = "TaskGroup";
diff --git a/services/java/com/android/server/wm/TaskStack.java b/services/java/com/android/server/wm/TaskStack.java
index df1d108..cb29df4 100644
--- a/services/java/com/android/server/wm/TaskStack.java
+++ b/services/java/com/android/server/wm/TaskStack.java
@@ -26,6 +26,8 @@
 import android.util.TypedValue;
 import com.android.server.EventLogTags;
 
+import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
@@ -47,9 +49,8 @@
      * mTaskHistory in the ActivityStack with the same mStackId */
     private final ArrayList<Task> mTasks = new ArrayList<Task>();
 
-    /** Content limits relative to the DisplayContent this sits in. Empty indicates fullscreen,
-     * Nonempty is size of this TaskStack but is also used to scale if DisplayContent changes. */
-    Rect mBounds = new Rect();
+    /** The StackBox this sits in. */
+    StackBox mStackBox;
 
     /** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */
     final DimLayer mDimLayer;
@@ -73,9 +74,6 @@
         mDisplayContent = displayContent;
         mDimLayer = new DimLayer(service, this);
         mAnimationBackgroundSurface = new DimLayer(service, this);
-        // TODO: remove bounds from log, they are always 0.
-        EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, mBounds.left, mBounds.top,
-                mBounds.right, mBounds.bottom);
     }
 
     DisplayContent getDisplayContent() {
@@ -86,64 +84,12 @@
         return mTasks;
     }
 
-    private void resizeWindows() {
-        final boolean underStatusBar = mBounds.top == 0;
-
-        final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
-        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
-            final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
-            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
-                final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
-                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-                    final WindowState win = windows.get(winNdx);
-                    if (!resizingWindows.contains(win)) {
-                        if (WindowManagerService.DEBUG_RESIZE) Slog.d(TAG,
-                                "setBounds: Resizing " + win);
-                        resizingWindows.add(win);
-                    }
-                    win.mUnderStatusBar = underStatusBar;
-                }
-            }
-        }
+    boolean isHomeStack() {
+        return mStackId == HOME_STACK_ID;
     }
 
-    boolean setBounds(Rect bounds) {
-        if (mBounds.equals(bounds)) {
-            return false;
-        }
-
-        mDimLayer.setBounds(bounds);
-        mAnimationBackgroundSurface.setBounds(bounds);
-        mBounds.set(bounds);
-
-        resizeWindows();
-        return true;
-    }
-
-    void getBounds(Rect out) {
-        if (mBounds.isEmpty()) {
-            mDisplayContent.getLogicalDisplayRect(out);
-        } else {
-            out.set(mBounds);
-        }
-        out.intersect(mDisplayContent.mContentRect);
-    }
-
-    boolean isFullscreen() {
-        return mBounds.isEmpty();
-    }
-
-    void resizeBounds(float oldWidth, float oldHeight, float newWidth, float newHeight) {
-        if (oldWidth == newWidth && oldHeight == newHeight) {
-            return;
-        }
-        float widthScale = newWidth / oldWidth;
-        float heightScale = newHeight / oldHeight;
-        mBounds.left = (int)(mBounds.left * widthScale + 0.5);
-        mBounds.top = (int)(mBounds.top * heightScale + 0.5);
-        mBounds.right = (int)(mBounds.right * widthScale + 0.5);
-        mBounds.bottom = (int)(mBounds.bottom * heightScale + 0.5);
-        resizeWindows();
+    boolean hasSibling() {
+        return mStackBox.mParent != null;
     }
 
     /**
@@ -151,7 +97,9 @@
      * @param task The task to add.
      * @param toTop Whether to add it to the top or bottom.
      */
-    void addTask(Task task, boolean toTop) {
+    boolean addTask(Task task, boolean toTop) {
+        mStackBox.makeDirty();
+
         int stackNdx;
         if (!toTop) {
             stackNdx = 0;
@@ -174,20 +122,20 @@
 
         task.mStack = this;
         mDisplayContent.addTask(task, toTop);
-        mDisplayContent.moveStack(this, true);
+        return mDisplayContent.moveHomeStackBox(mStackId == HOME_STACK_ID);
     }
 
-    void moveTaskToTop(Task task) {
+    boolean moveTaskToTop(Task task) {
         if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToTop: task=" + task + " Callers="
                 + Debug.getCallers(6));
         mTasks.remove(task);
-        addTask(task, true);
+        return addTask(task, true);
     }
 
-    void moveTaskToBottom(Task task) {
+    boolean moveTaskToBottom(Task task) {
         if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToBottom: task=" + task);
         mTasks.remove(task);
-        addTask(task, false);
+        return addTask(task, false);
     }
 
     /**
@@ -197,6 +145,7 @@
      */
     void removeTask(Task task) {
         if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task);
+        mStackBox.makeDirty();
         mTasks.remove(task);
         mDisplayContent.removeTask(task);
     }
@@ -205,7 +154,7 @@
         mAnimationBackgroundSurface.destroySurface();
         mDimLayer.destroySurface();
         EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
-        return mDisplayContent.topStack().mStackId;
+        return mStackBox.remove();
     }
 
     void resetAnimationBackgroundAnimator() {
@@ -310,6 +259,28 @@
         }
     }
 
+    void setBounds(Rect bounds, boolean underStatusBar) {
+        mDimLayer.setBounds(bounds);
+        mAnimationBackgroundSurface.setBounds(bounds);
+
+        final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
+        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
+                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+                    final WindowState win = windows.get(winNdx);
+                    if (!resizingWindows.contains(win)) {
+                        if (WindowManagerService.DEBUG_RESIZE) Slog.d(TAG,
+                                "setBounds: Resizing " + win);
+                        resizingWindows.add(win);
+                    }
+                    win.mUnderStatusBar = underStatusBar;
+                }
+            }
+        }
+    }
+
     void switchUser(int userId) {
         int top = mTasks.size();
         for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
@@ -322,11 +293,6 @@
         }
     }
 
-    void close() {
-        mDimLayer.mDimSurface.destroy();
-        mAnimationBackgroundSurface.mDimSurface.destroy();
-    }
-
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
         for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 2ec84f3..2072671 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -45,6 +45,7 @@
 import com.android.server.power.ShutdownThread;
 
 import android.Manifest;
+import android.app.ActivityManager.StackBoxInfo;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.StatusBarManager;
@@ -255,9 +256,6 @@
     /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
     static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
 
-    /** Amount of time (in milliseconds) to delay before declaring a starting window leaked. */
-    static final int STARTING_WINDOW_TIMEOUT_DURATION = 10000;
-
     /**
      * If true, the window manager will do its own custom freezing and general
      * management of the screen during rotation.
@@ -2267,8 +2265,6 @@
                 token.appWindowToken.startingWindow = win;
                 if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken
                         + " startingWindow=" + win);
-                Message m = mH.obtainMessage(H.REMOVE_STARTING_TIMEOUT, token.appWindowToken);
-                mH.sendMessageDelayed(m, STARTING_WINDOW_TIMEOUT_DURATION);
             }
 
             boolean imMayMove = true;
@@ -2371,7 +2367,6 @@
     public void removeWindowLocked(Session session, WindowState win) {
         if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
             if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "Starting window removed " + win);
-            removeStartingWindowTimeout(win.mAppToken);
         }
 
         if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && win==mCurrentFocus) Slog.v(
@@ -2515,7 +2510,6 @@
         if (atoken != null) {
             if (atoken.startingWindow == win) {
                 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win);
-                removeStartingWindowTimeout(atoken);
                 atoken.startingWindow = null;
             } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
                 // If this is the last window and we had requested a starting
@@ -3774,8 +3768,10 @@
             if (stack == null) {
                 mFocusedStackFrame.setVisibility(false);
             } else {
-                mFocusedStackFrame.setBounds(stack);
-                final boolean multipleStacks = !stack.isFullscreen();
+                final StackBox box = stack.mStackBox;
+                final Rect bounds = box.mBounds;
+                final boolean multipleStacks = box.mParent != null;
+                mFocusedStackFrame.setBounds(bounds);
                 mFocusedStackFrame.setVisibility(multipleStacks);
             }
         } finally {
@@ -3836,22 +3832,22 @@
                     + " " + mAppTransition
                     + " alwaysKeepCurrent=" + alwaysKeepCurrent
                     + " Callers=" + Debug.getCallers(3));
-            if (okToDisplay()) {
-                if (!mAppTransition.isTransitionSet() || mAppTransition.isTransitionNone()) {
+            if (!mAppTransition.isTransitionSet() || mAppTransition.isTransitionNone()) {
+                mAppTransition.setAppTransition(transit);
+            } else if (!alwaysKeepCurrent) {
+                if (transit == AppTransition.TRANSIT_TASK_OPEN
+                        && mAppTransition.isTransitionEqual(
+                                AppTransition.TRANSIT_TASK_CLOSE)) {
+                    // Opening a new task always supersedes a close for the anim.
                     mAppTransition.setAppTransition(transit);
-                } else if (!alwaysKeepCurrent) {
-                    if (transit == AppTransition.TRANSIT_TASK_OPEN
-                            && mAppTransition.isTransitionEqual(
-                                    AppTransition.TRANSIT_TASK_CLOSE)) {
-                        // Opening a new task always supersedes a close for the anim.
-                        mAppTransition.setAppTransition(transit);
-                    } else if (transit == AppTransition.TRANSIT_ACTIVITY_OPEN
-                            && mAppTransition.isTransitionEqual(
-                                AppTransition.TRANSIT_ACTIVITY_CLOSE)) {
-                        // Opening a new activity always supersedes a close for the anim.
-                        mAppTransition.setAppTransition(transit);
-                    }
+                } else if (transit == AppTransition.TRANSIT_ACTIVITY_OPEN
+                        && mAppTransition.isTransitionEqual(
+                            AppTransition.TRANSIT_ACTIVITY_CLOSE)) {
+                    // Opening a new activity always supersedes a close for the anim.
+                    mAppTransition.setAppTransition(transit);
                 }
+            }
+            if (okToDisplay()) {
                 mAppTransition.prepare();
                 mStartingIconInTransition = false;
                 mSkipAppTransitionAnimation = false;
@@ -3983,7 +3979,6 @@
                         if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
                             Slog.v(TAG, "Removing starting window: " + startingWindow);
                         }
-                        removeStartingWindowTimeout(ttoken);
                         startingWindow.getWindowList().remove(startingWindow);
                         mWindowsChanged = true;
                         if (DEBUG_ADD_REMOVE) Slog.v(TAG,
@@ -4130,6 +4125,15 @@
         }
     }
 
+    public void removeAppStartingWindow(IBinder token) {
+        synchronized (mWindowMap) {
+            AppWindowToken wtoken = mTokenMap.get(token).appWindowToken;
+            if (wtoken.startingWindow != null) {
+                scheduleRemoveStartingWindow(wtoken);
+            }
+        }
+    }
+
     @Override
     public void setAppWillBeHidden(IBinder token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
@@ -4547,21 +4551,11 @@
         scheduleRemoveStartingWindow(startingToken);
     }
 
-    void removeStartingWindowTimeout(AppWindowToken wtoken) {
-        if (wtoken != null) {
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, Debug.getCallers(1) +
-                    ": Remove starting window timeout " + wtoken + (wtoken != null ?
-                    " startingWindow=" + wtoken.startingWindow : ""));
-            mH.removeMessages(H.REMOVE_STARTING_TIMEOUT, wtoken);
-        }
-    }
-
     void scheduleRemoveStartingWindow(AppWindowToken wtoken) {
         if (wtoken != null && wtoken.startingWindow != null) {
             if (DEBUG_STARTING_WINDOW) Slog.v(TAG, Debug.getCallers(1) +
                     ": Schedule remove starting " + wtoken + (wtoken != null ?
                     " startingWindow=" + wtoken.startingWindow : ""));
-            removeStartingWindowTimeout(wtoken);
             Message m = mH.obtainMessage(H.REMOVE_STARTING, wtoken);
             mH.sendMessage(m);
         }
@@ -4782,12 +4776,10 @@
                 }
                 final TaskStack stack = task.mStack;
                 final DisplayContent displayContent = task.getDisplayContent();
-                displayContent.moveStack(stack, true);
-                final TaskStack homeStack = displayContent.getHomeStack();
-                if (homeStack != stack) {
-                    // When a non-home stack moves to the top, the home stack moves to the
-                    // bottom.
-                    displayContent.moveStack(homeStack, false);
+                final boolean isHomeStackTask = stack.isHomeStack();
+                if (isHomeStackTask != displayContent.homeOnTop()) {
+                    // First move the stack itself.
+                    displayContent.moveHomeStackBox(isHomeStackTask);
                 }
                 stack.moveTaskToTop(task);
             }
@@ -4818,19 +4810,36 @@
     /**
      * Create a new TaskStack and place it next to an existing stack.
      * @param stackId The unique identifier of the new stack.
+     * @param relativeStackBoxId The existing stack that this stack goes before or after.
+     * @param position One of:
+     *      {@link StackBox#TASK_STACK_GOES_BEFORE}
+     *      {@link StackBox#TASK_STACK_GOES_AFTER}
+     *      {@link StackBox#TASK_STACK_GOES_ABOVE}
+     *      {@link StackBox#TASK_STACK_GOES_BELOW}
+     *      {@link StackBox#TASK_STACK_GOES_UNDER}
+     *      {@link StackBox#TASK_STACK_GOES_OVER}
+     * @param weight Relative weight for determining how big to make the new TaskStack.
      */
-    public void createStack(int stackId, int displayId) {
+    public void createStack(int stackId, int relativeStackBoxId, int position, float weight) {
         synchronized (mWindowMap) {
+            if (position <= StackBox.TASK_STACK_GOES_BELOW &&
+                    (weight < STACK_WEIGHT_MIN || weight > STACK_WEIGHT_MAX)) {
+                throw new IllegalArgumentException(
+                        "createStack: weight must be between " + STACK_WEIGHT_MIN + " and " +
+                        STACK_WEIGHT_MAX + ", weight=" + weight);
+            }
             final int numDisplays = mDisplayContents.size();
             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
                 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
-                if (displayContent.getDisplayId() == displayId) {
-                    TaskStack stack = displayContent.createStack(stackId);
+                TaskStack stack = displayContent.createStack(stackId, relativeStackBoxId, position,
+                        weight);
+                if (stack != null) {
                     mStackIdToStack.put(stackId, stack);
                     performLayoutAndPlaceSurfacesLocked();
                     return;
                 }
             }
+            Slog.e(TAG, "createStack: Unable to find relativeStackBoxId=" + relativeStackBoxId);
         }
     }
 
@@ -4877,27 +4886,40 @@
         }
     }
 
-    public void resizeStack(int stackId, Rect bounds) {
+    public void resizeStackBox(int stackBoxId, float weight) {
+        if (weight < STACK_WEIGHT_MIN || weight > STACK_WEIGHT_MAX) {
+            throw new IllegalArgumentException(
+                    "resizeStack: weight must be between " + STACK_WEIGHT_MIN + " and " +
+                    STACK_WEIGHT_MAX + ", weight=" + weight);
+        }
         synchronized (mWindowMap) {
-            final TaskStack stack = mStackIdToStack.get(stackId);
-            if (stack == null) {
-                throw new IllegalArgumentException("resizeStack: stackId " + stackId
-                        + " not found.");
+            final int numDisplays = mDisplayContents.size();
+            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+                if (mDisplayContents.valueAt(displayNdx).resizeStack(stackBoxId, weight)) {
+                    performLayoutAndPlaceSurfacesLocked();
+                    return;
+                }
             }
-            if (stack.setBounds(bounds)) {
-                stack.getDisplayContent().layoutNeeded = true;
-                performLayoutAndPlaceSurfacesLocked();
-            }
+        }
+        throw new IllegalArgumentException("resizeStack: stackBoxId " + stackBoxId
+                + " not found.");
+    }
+
+    public ArrayList<StackBoxInfo> getStackBoxInfos() {
+        synchronized(mWindowMap) {
+            return getDefaultDisplayContentLocked().getStackBoxInfos();
         }
     }
 
-    public void getStackBounds(int stackId, Rect bounds) {
-        final TaskStack stack = mStackIdToStack.get(stackId);
-        if (stack != null) {
-            stack.getBounds(bounds);
-            return;
+    public Rect getStackBounds(int stackId) {
+        final int numDisplays = mDisplayContents.size();
+        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+            Rect bounds = mDisplayContents.valueAt(displayNdx).getStackBounds(stackId);
+            if (bounds != null) {
+                return bounds;
+            }
         }
-        bounds.setEmpty();
+        return null;
     }
 
     // -------------------------------------------------------------
@@ -5554,14 +5576,13 @@
                                 continue;
                             }
                             appWin = ws;
-                            ws.getStackBounds(stackBounds);
+                            stackBounds.set(ws.getStackBounds());
                         }
                     }
 
                     // We keep on including windows until we go past a full-screen
                     // window.
-                    boolean fullscreen = ws.isFullscreen(dw, dh);
-                    including = !ws.mIsImWindow && !fullscreen;
+                    including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
 
                     final WindowStateAnimator winAnim = ws.mWinAnimator;
                     if (maxLayer < winAnim.mSurfaceLayer) {
@@ -5587,11 +5608,6 @@
                             ws.isDisplayedLw()) {
                         screenshotReady = true;
                     }
-
-                    if (fullscreen) {
-                        // No point in continuing down through windows.
-                        break;
-                    }
                 }
 
                 if (appToken != null && appWin == null) {
@@ -7038,8 +7054,6 @@
         public static final int TAP_OUTSIDE_STACK = 31;
         public static final int NOTIFY_ACTIVITY_DRAWN = 32;
 
-        public static final int REMOVE_STARTING_TIMEOUT = 33;
-
         @Override
         public void handleMessage(Message msg) {
             if (DEBUG_WINDOW_TRACE) {
@@ -7138,7 +7152,6 @@
                                             "Aborted starting " + wtoken
                                             + ": removed=" + wtoken.removed
                                             + " startingData=" + wtoken.startingData);
-                                    removeStartingWindowTimeout(wtoken);
                                     wtoken.startingWindow = null;
                                     wtoken.startingData = null;
                                     abort = true;
@@ -7163,11 +7176,6 @@
                     }
                 } break;
 
-                case REMOVE_STARTING_TIMEOUT: {
-                    final AppWindowToken wtoken = (AppWindowToken)msg.obj;
-                    Slog.e(TAG, "Starting window " + wtoken + " timed out");
-                    // Fall through.
-                }
                 case REMOVE_STARTING: {
                     final AppWindowToken wtoken = (AppWindowToken)msg.obj;
                     IBinder token = null;
@@ -8189,7 +8197,7 @@
         }
 
         mPolicy.getContentRectLw(mTmpContentRect);
-        displayContent.resize(mTmpContentRect);
+        displayContent.setStackBoxSize(mTmpContentRect);
 
         int seq = mLayoutSeq+1;
         if (seq < 0) seq = 0;
@@ -10141,6 +10149,12 @@
         }
     }
 
+    public int getInputMethodWindowVisibleHeight() {
+        synchronized (mWindowMap) {
+            return mPolicy.getInputMethodWindowVisibleHeightLw();
+        }
+    }
+
     @Override
     public boolean hasNavigationBar() {
         return mPolicy.hasNavigationBar();
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index e6c1e98..4d53cea 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -463,8 +463,8 @@
         mHaveFrame = true;
 
         TaskStack stack = mAppToken != null ? getStack() : null;
-        if (stack != null && !stack.isFullscreen()) {
-            getStackBounds(stack, mContainingFrame);
+        if (stack != null && stack.hasSibling()) {
+            mContainingFrame.set(getStackBounds(stack));
             if (mUnderStatusBar) {
                 mContainingFrame.top = pf.top;
             }
@@ -723,16 +723,15 @@
         return mDisplayContent.getHomeStack();
     }
 
-    void getStackBounds(Rect bounds) {
-        getStackBounds(getStack(), bounds);
+    Rect getStackBounds() {
+        return getStackBounds(getStack());
     }
 
-    private void getStackBounds(TaskStack stack, Rect bounds) {
+    private Rect getStackBounds(TaskStack stack) {
         if (stack != null) {
-            stack.getBounds(bounds);
-            return;
+            return stack.mStackBox.mBounds;
         }
-        bounds.set(mFrame);
+        return mFrame;
     }
 
     public long getInputDispatchingTimeoutNanos() {
diff --git a/services/tests/servicestests/src/com/android/server/EntropyMixerTest.java b/services/tests/servicestests/src/com/android/server/EntropyMixerTest.java
index 58d6dae..50e7a03 100644
--- a/services/tests/servicestests/src/com/android/server/EntropyMixerTest.java
+++ b/services/tests/servicestests/src/com/android/server/EntropyMixerTest.java
@@ -34,7 +34,7 @@
         assertEquals(0, FileUtils.readTextFile(file, 0, null).length());
 
         // The constructor has the side effect of writing to file
-        new EntropyMixer(getContext(), "/dev/null", file.getCanonicalPath());
+        new EntropyMixer(getContext(), "/dev/null", file.getCanonicalPath(), "/dev/null");
 
         assertTrue(FileUtils.readTextFile(file, 0, null).length() > 0);
     }
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
index 56dd7c4..a78e7b6 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import android.content.Context;
+import android.net.LinkAddress;
 import android.net.LocalSocket;
 import android.net.LocalServerSocket;
 import android.os.Binder;
@@ -157,18 +158,64 @@
          * IP address changes.
          */
         sendMessage("614 Address updated fe80::1/64 wlan0 128 253");
-        expectSoon(observer).addressUpdated("fe80::1/64", "wlan0", 128, 253);
+        expectSoon(observer).addressUpdated(
+                new LinkAddress("fe80::1/64"), "wlan0", 128, 253);
 
-        // There is no "added".
+        // There is no "added", so we take this as "removed".
         sendMessage("614 Address added fe80::1/64 wlan0 128 253");
-        expectSoon(observer).addressRemoved("fe80::1/64", "wlan0", 128, 253);
+        expectSoon(observer).addressRemoved(
+                new LinkAddress("fe80::1/64"), "wlan0", 128, 253);
 
         sendMessage("614 Address removed 2001:db8::1/64 wlan0 1 0");
-        expectSoon(observer).addressRemoved("2001:db8::1/64", "wlan0", 1, 0);
+        expectSoon(observer).addressRemoved(
+                new LinkAddress("2001:db8::1/64"), "wlan0", 1, 0);
 
-        sendMessage("666 Address added 2001:db8::1/64 wlan0 1 0");
+        sendMessage("614 Address removed 2001:db8::1/64 wlan0 1");
+        // Not enough arguments.
+
+        sendMessage("666 Address removed 2001:db8::1/64 wlan0 1 0");
         // Invalid code.
 
+
+        /**
+         * DNS information broadcasts.
+         */
+        sendMessage("615 DnsInfo servers rmnet_usb0 3600 2001:db8::1");
+        expectSoon(observer).interfaceDnsServerInfo("rmnet_usb0", 3600,
+                new String[]{"2001:db8::1"});
+
+        sendMessage("615 DnsInfo servers wlan0 14400 2001:db8::1,2001:db8::2");
+        expectSoon(observer).interfaceDnsServerInfo("wlan0", 14400,
+                new String[]{"2001:db8::1", "2001:db8::2"});
+
+        // We don't check for negative lifetimes, only for parse errors.
+        sendMessage("615 DnsInfo servers wlan0 -3600 ::1");
+        expectSoon(observer).interfaceDnsServerInfo("wlan0", -3600,
+                new String[]{"::1"});
+
+        sendMessage("615 DnsInfo servers wlan0 SIXHUNDRED ::1");
+        // Non-numeric lifetime.
+
+        sendMessage("615 DnsInfo servers wlan0 2001:db8::1");
+        // Missing lifetime.
+
+        sendMessage("615 DnsInfo servers wlan0 3600");
+        // No servers.
+
+        sendMessage("615 DnsInfo servers 3600 wlan0 2001:db8::1,2001:db8::2");
+        // Non-numeric lifetime.
+
+        sendMessage("615 DnsInfo wlan0 7200 2001:db8::1,2001:db8::2");
+        // Invalid tokens.
+
+        sendMessage("666 DnsInfo servers wlan0 5400 2001:db8::1");
+        // Invalid code.
+
+        // No syntax checking on the addresses.
+        sendMessage("615 DnsInfo servers wlan0 600 ,::,,foo,::1,");
+        expectSoon(observer).interfaceDnsServerInfo("wlan0", 600,
+                new String[]{"", "::", "", "foo", "::1"});
+
         // Make sure nothing else was called.
         verifyNoMoreInteractions(observer);
     }
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
index f870e4c..70fd810 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
@@ -17,6 +17,7 @@
 package com.android.server.content;
 
 import android.accounts.Account;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.ContextWrapper;
@@ -32,22 +33,34 @@
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.server.content.SyncStorageEngine.EndPoint;
+
 import com.android.internal.os.AtomicFile;
 
 import java.io.File;
 import java.io.FileOutputStream;
 import java.util.List;
 
+import com.android.server.content.SyncStorageEngine.EndPoint;
+
 public class SyncStorageEngineTest extends AndroidTestCase {
 
     protected Account account1;
+    protected Account account2;
+    protected ComponentName syncService1;
     protected String authority1 = "testprovider";
     protected Bundle defaultBundle;
     protected final int DEFAULT_USER = 0;
-    
+
+    /* Some default poll frequencies. */
+    final long dayPoll = (60 * 60 * 24);
+    final long dayFuzz = 60;
+    final long thousandSecs = 1000;
+    final long thousandSecsFuzz = 100;
+
     MockContentResolver mockResolver;
     SyncStorageEngine engine;
-    
+
     private File getSyncDir() {
         return new File(new File(getContext().getFilesDir(), "system"), "sync");
     }
@@ -55,6 +68,8 @@
     @Override
     public void setUp() {
         account1 = new Account("a@example.com", "example.type");
+        account2 = new Account("b@example.com", "example.type");
+        syncService1 = new ComponentName("com.example", "SyncService");
         // Default bundle.
         defaultBundle = new Bundle();
         defaultBundle.putInt("int_key", 0);
@@ -80,11 +95,13 @@
 
         SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
                 new TestContext(mockResolver, getContext()));
-
         long time0 = 1000;
-        long historyId = engine.insertStartSyncEvent(
-                account, 0, SyncOperation.REASON_PERIODIC, authority, time0,
-                SyncStorageEngine.SOURCE_LOCAL, false /* initialization */, null /* extras */);
+        SyncOperation op = new SyncOperation(account, 0,
+                SyncOperation.REASON_PERIODIC,
+                SyncStorageEngine.SOURCE_LOCAL,
+                authority,
+                Bundle.EMPTY, time0, 0 /* flex*/, 0, 0, true);
+        long historyId = engine.insertStartSyncEvent(op, time0);
         long time1 = time0 + SyncStorageEngine.MILLIS_IN_4WEEKS * 2;
         engine.stopSyncEvent(historyId, time1 - time0, "yay", 0, 0);
     }
@@ -93,28 +110,100 @@
      * Test persistence of pending operations.
      */
     @MediumTest
-    public void testPending() throws Exception {
-        SyncStorageEngine.PendingOperation pop =
-                new SyncStorageEngine.PendingOperation(account1, DEFAULT_USER,
-                        SyncOperation.REASON_PERIODIC, SyncStorageEngine.SOURCE_LOCAL,
-                        authority1, defaultBundle, false);
-        
-        engine.insertIntoPending(pop);
+    public void testAppendPending() throws Exception {
+        SyncOperation sop = new SyncOperation(account1,
+                DEFAULT_USER,
+                SyncOperation.REASON_PERIODIC,
+                SyncStorageEngine.SOURCE_LOCAL, authority1, Bundle.EMPTY,
+                0 /* runtime */, 0 /* flex */, 0 /* backoff */, 0 /* delayuntil */,
+                true /* expedited */);
+        engine.insertIntoPending(sop);
+
         // Force engine to read from disk.
         engine.clearAndReadState();
 
-        assert(engine.getPendingOperationCount() == 1);
+        assertTrue(engine.getPendingOperationCount() == 1);
         List<SyncStorageEngine.PendingOperation> pops = engine.getPendingOperations();
         SyncStorageEngine.PendingOperation popRetrieved = pops.get(0);
-        assertEquals(pop.account, popRetrieved.account);
-        assertEquals(pop.reason, popRetrieved.reason);
-        assertEquals(pop.userId, popRetrieved.userId);
-        assertEquals(pop.syncSource, popRetrieved.syncSource);
-        assertEquals(pop.authority, popRetrieved.authority);
-        assertEquals(pop.expedited, popRetrieved.expedited);
-        assertEquals(pop.serviceName, popRetrieved.serviceName);
-        assert(android.content.PeriodicSync.syncExtrasEquals(pop.extras, popRetrieved.extras));
+        assertEquals(sop.target.account, popRetrieved.target.account);
+        assertEquals(sop.target.provider, popRetrieved.target.provider);
+        assertEquals(sop.target.service, popRetrieved.target.service);
+        assertEquals(sop.target.userId, popRetrieved.target.userId);
+        assertEquals(sop.reason, popRetrieved.reason);
+        assertEquals(sop.syncSource, popRetrieved.syncSource);
+        assertEquals(sop.expedited, popRetrieved.expedited);
+        assert(android.content.PeriodicSync.syncExtrasEquals(sop.extras, popRetrieved.extras));
+    }
 
+    /**
+     * Verify {@link com.android.server.content.SyncStorageEngine#writePendingOperationsLocked()}
+     */
+    public void testWritePendingOperationsLocked() throws Exception {
+        SyncOperation sop = new SyncOperation(account1,
+                DEFAULT_USER,
+                SyncOperation.REASON_IS_SYNCABLE,
+                SyncStorageEngine.SOURCE_LOCAL, authority1, Bundle.EMPTY,
+                1000L /* runtime */, 57L /* flex */, 0 /* backoff */, 0 /* delayuntil */,
+                true /* expedited */);
+        SyncOperation sop1 = new SyncOperation(account2,
+                DEFAULT_USER,
+                SyncOperation.REASON_PERIODIC,
+                SyncStorageEngine.SOURCE_LOCAL, authority1, defaultBundle,
+                0 /* runtime */, 0 /* flex */, 20L /* backoff */, 100L /* delayuntil */,
+                false /* expedited */);
+        SyncOperation deleted = new SyncOperation(account2,
+                DEFAULT_USER,
+                SyncOperation.REASON_SYNC_AUTO,
+                SyncStorageEngine.SOURCE_LOCAL, authority1, Bundle.EMPTY,
+                0 /* runtime */, 0 /* flex */, 20L /* backoff */, 100L /* delayuntil */,
+                false /* expedited */);
+        engine.insertIntoPending(sop);
+        engine.insertIntoPending(sop1);
+        engine.insertIntoPending(deleted);
+
+        SyncStorageEngine.PendingOperation popDeleted = engine.getPendingOperations().get(2);
+        // Free verifying, going to delete it anyway.
+        assertEquals(deleted.target.account, popDeleted.target.account);
+        assertEquals(deleted.target.provider, popDeleted.target.provider);
+        assertEquals(deleted.target.service, popDeleted.target.service);
+        assertEquals(deleted.target.userId, popDeleted.target.userId);
+        assertEquals(deleted.reason, popDeleted.reason);
+        assertEquals(deleted.syncSource, popDeleted.syncSource);
+        assertEquals(deleted.expedited, popDeleted.expedited);
+        assert(android.content.PeriodicSync.syncExtrasEquals(deleted.extras, popDeleted.extras));
+        // Delete one to force write-all
+        engine.deleteFromPending(popDeleted);
+        assertEquals("Delete of pending op failed.", 2, engine.getPendingOperationCount());
+        // If there's dirty pending data (which there is because we deleted a pending op) this
+        // re-writes the entire file.
+        engine.writeAllState();
+
+        engine.clearAndReadState();
+
+        // Validate state read back out.
+        assertEquals("Delete of pending op failed.", 2, engine.getPendingOperationCount());
+
+        List<SyncStorageEngine.PendingOperation> pops = engine.getPendingOperations();
+
+        SyncStorageEngine.PendingOperation popRetrieved = pops.get(0);
+        assertEquals(sop.target.account, popRetrieved.target.account);
+        assertEquals(sop.target.provider, popRetrieved.target.provider);
+        assertEquals(sop.target.service, popRetrieved.target.service);
+        assertEquals(sop.target.userId, popRetrieved.target.userId);
+        assertEquals(sop.reason, popRetrieved.reason);
+        assertEquals(sop.syncSource, popRetrieved.syncSource);
+        assertEquals(sop.expedited, popRetrieved.expedited);
+        assert(android.content.PeriodicSync.syncExtrasEquals(sop.extras, popRetrieved.extras));
+
+        popRetrieved = pops.get(1);
+        assertEquals(sop1.target.account, popRetrieved.target.account);
+        assertEquals(sop1.target.provider, popRetrieved.target.provider);
+        assertEquals(sop1.target.service, popRetrieved.target.service);
+        assertEquals(sop1.target.userId, popRetrieved.target.userId);
+        assertEquals(sop1.reason, popRetrieved.reason);
+        assertEquals(sop1.syncSource, popRetrieved.syncSource);
+        assertEquals(sop1.expedited, popRetrieved.expedited);
+        assert(android.content.PeriodicSync.syncExtrasEquals(sop1.extras, popRetrieved.extras));
     }
 
     /**
@@ -134,42 +223,44 @@
         final int period2 = 1000;
 
         PeriodicSync sync1 = new PeriodicSync(account1, authority, extras1, period1);
+        EndPoint end1 = new EndPoint(account1, authority, 0);
+
         PeriodicSync sync2 = new PeriodicSync(account1, authority, extras2, period1);
         PeriodicSync sync3 = new PeriodicSync(account1, authority, extras2, period2);
         PeriodicSync sync4 = new PeriodicSync(account2, authority, extras2, period2);
 
-        
+
 
         removePeriodicSyncs(engine, account1, 0, authority);
         removePeriodicSyncs(engine, account2, 0, authority);
         removePeriodicSyncs(engine, account1, 1, authority);
 
         // this should add two distinct periodic syncs for account1 and one for account2
-        engine.addPeriodicSync(sync1, 0);
-        engine.addPeriodicSync(sync2, 0);
-        engine.addPeriodicSync(sync3, 0);
-        engine.addPeriodicSync(sync4, 0);
+        engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 0), period1, 0, extras1);
+        engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 0), period1, 0, extras2);
+        engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 0), period2, 0, extras2);
+        engine.updateOrAddPeriodicSync(new EndPoint(account2, authority, 0), period2, 0, extras2);
         // add a second user
-        engine.addPeriodicSync(sync2, 1);
+        engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 1), period1, 0, extras2);
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(new EndPoint(account1, authority, 0));
 
         assertEquals(2, syncs.size());
 
         assertEquals(sync1, syncs.get(0));
         assertEquals(sync3, syncs.get(1));
 
-        engine.removePeriodicSync(sync1, 0);
+        engine.removePeriodicSync(new EndPoint(account1, authority, 0), extras1);
 
-        syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        syncs = engine.getPeriodicSyncs(new EndPoint(account1, authority, 0));
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account2, 0, authority);
+        syncs = engine.getPeriodicSyncs(new EndPoint(account2, authority, 0));
         assertEquals(1, syncs.size());
         assertEquals(sync4, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(sync2.account, 1, sync2.authority);
+        syncs = engine.getPeriodicSyncs(new EndPoint(sync2.account, sync2.authority, 1));
         assertEquals(1, syncs.size());
         assertEquals(sync2, syncs.get(0));
     }
@@ -190,12 +281,19 @@
         final int period2 = 1000;
         final int flex1 = 10;
         final int flex2 = 100;
+        EndPoint point1 = new EndPoint(account1, authority, 0);
+        EndPoint point2 = new EndPoint(account2, authority, 0);
+        EndPoint point1User2 = new EndPoint(account1, authority, 1);
 
         PeriodicSync sync1 = new PeriodicSync(account1, authority, extras1, period1, flex1);
         PeriodicSync sync2 = new PeriodicSync(account1, authority, extras2, period1, flex1);
         PeriodicSync sync3 = new PeriodicSync(account1, authority, extras2, period2, flex2);
         PeriodicSync sync4 = new PeriodicSync(account2, authority, extras2, period2, flex2);
 
+        EndPoint target1 = new EndPoint(account1, authority, 0);
+        EndPoint target2 = new EndPoint(account2, authority, 0);
+        EndPoint target1UserB = new EndPoint(account1, authority, 1);
+
         MockContentResolver mockResolver = new MockContentResolver();
 
         SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
@@ -206,40 +304,42 @@
         removePeriodicSyncs(engine, account1, 1, authority);
 
         // This should add two distinct periodic syncs for account1 and one for account2
-        engine.addPeriodicSync(sync1, 0);
-        engine.addPeriodicSync(sync2, 0);
-        engine.addPeriodicSync(sync3, 0); // Should edit sync2 and update the period.
-        engine.addPeriodicSync(sync4, 0);
-        // add a second user
-        engine.addPeriodicSync(sync2, 1);
+        engine.updateOrAddPeriodicSync(target1, period1, flex1, extras1);
+        engine.updateOrAddPeriodicSync(target1, period1, flex1, extras2);
+        // Edit existing sync and update the period and flex.
+        engine.updateOrAddPeriodicSync(target1, period2, flex2, extras2);
+        engine.updateOrAddPeriodicSync(target2, period2, flex2, extras2);
+        // add a target for a second user.
+        engine.updateOrAddPeriodicSync(target1UserB, period1, flex1, extras2);
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1);
 
         assertEquals(2, syncs.size());
 
         assertEquals(sync1, syncs.get(0));
         assertEquals(sync3, syncs.get(1));
 
-        engine.removePeriodicSync(sync1, 0);
+        engine.removePeriodicSync(target1, extras1);
 
-        syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account2, 0, authority);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync4, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(sync2.account, 1, sync2.authority);
+        syncs = engine.getPeriodicSyncs(target1UserB);
         assertEquals(1, syncs.size());
         assertEquals(sync2, syncs.get(0));
     }
 
     private void removePeriodicSyncs(SyncStorageEngine engine, Account account, int userId, String authority) {
-        engine.setIsSyncable(account, userId, authority, engine.getIsSyncable(account, 0, authority));
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, userId, authority);
+        EndPoint target = new EndPoint(account, authority, userId);
+        engine.setIsSyncable(account, userId, authority, engine.getIsSyncable(account, userId, authority));
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target);
         for (PeriodicSync sync : syncs) {
-            engine.removePeriodicSync(sync, userId);
+            engine.removePeriodicSync(target, sync.extras);
         }
     }
 
@@ -264,16 +364,19 @@
         final int flex1 = 10;
         final int flex2 = 100;
 
+        EndPoint point1 = new EndPoint(account1, authority1, 0);
+        EndPoint point2 = new EndPoint(account1, authority2, 0);
+        EndPoint point3 = new EndPoint(account2, authority1, 0);
+
         PeriodicSync sync1 = new PeriodicSync(account1, authority1, extras1, period1, flex1);
         PeriodicSync sync2 = new PeriodicSync(account1, authority1, extras2, period1, flex1);
         PeriodicSync sync3 = new PeriodicSync(account1, authority2, extras1, period1, flex1);
         PeriodicSync sync4 = new PeriodicSync(account1, authority2, extras2, period2, flex2);
         PeriodicSync sync5 = new PeriodicSync(account2, authority1, extras1, period1, flex1);
 
-        MockContentResolver mockResolver = new MockContentResolver();
-
-        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
-                new TestContext(mockResolver, getContext()));
+        EndPoint target1 = new EndPoint(account1, authority1, 0);
+        EndPoint target2 = new EndPoint(account1, authority2, 0);
+        EndPoint target3 = new EndPoint(account2, authority1, 0);
 
         removePeriodicSyncs(engine, account1, 0, authority1);
         removePeriodicSyncs(engine, account2, 0, authority1);
@@ -294,26 +397,26 @@
         engine.setIsSyncable(account2, 0, authority2, 0);
         engine.setSyncAutomatically(account2, 0, authority2, true);
 
-        engine.addPeriodicSync(sync1, 0);
-        engine.addPeriodicSync(sync2, 0);
-        engine.addPeriodicSync(sync3, 0);
-        engine.addPeriodicSync(sync4, 0);
-        engine.addPeriodicSync(sync5, 0);
+        engine.updateOrAddPeriodicSync(target1, period1, flex1, extras1);
+        engine.updateOrAddPeriodicSync(target1, period1, flex1, extras2);
+        engine.updateOrAddPeriodicSync(target2, period1, flex1, extras1);
+        engine.updateOrAddPeriodicSync(target2, period2, flex2, extras2);
+        engine.updateOrAddPeriodicSync(target3, period1, flex1, extras1);
 
         engine.writeAllState();
         engine.clearAndReadState();
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, 0, authority1);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1);
         assertEquals(2, syncs.size());
         assertEquals(sync1, syncs.get(0));
         assertEquals(sync2, syncs.get(1));
 
-        syncs = engine.getPeriodicSyncs(account1, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(2, syncs.size());
         assertEquals(sync3, syncs.get(0));
         assertEquals(sync4, syncs.get(1));
 
-        syncs = engine.getPeriodicSyncs(account2, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync5, syncs.get(0));
 
@@ -328,6 +431,50 @@
         assertEquals(0, engine.getIsSyncable(account2, 0, authority2));
     }
 
+    @SmallTest
+    public void testComponentParsing() throws Exception {
+
+        byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<accounts version=\"2\" >\n"
+                + "<authority id=\"0\" user=\"0\" package=\"" + syncService1.getPackageName() + "\""
+                + " class=\"" + syncService1.getClassName() + "\" syncable=\"true\">"
+                + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>"
+                + "\n</authority>"
+                + "</accounts>").getBytes();
+
+        File syncDir = getSyncDir();
+        syncDir.mkdirs();
+        AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
+        FileOutputStream fos = accountInfoFile.startWrite();
+        fos.write(accountsFileData);
+        accountInfoFile.finishWrite(fos);
+
+        engine.clearAndReadState();
+
+        SyncStorageEngine.AuthorityInfo aInfo = engine.getAuthority(0);
+        assertNotNull(aInfo);
+
+        // Test service component read
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(
+                new SyncStorageEngine.EndPoint(syncService1, 0));
+        assertEquals(1, syncs.size());
+        assertEquals(true, engine.getIsTargetServiceActive(syncService1, 0));
+    }
+
+    @SmallTest
+    public void testComponentSettings() throws Exception {
+        EndPoint target1 = new EndPoint(syncService1, 0);
+        engine.updateOrAddPeriodicSync(target1, dayPoll, dayFuzz, Bundle.EMPTY);
+        
+        engine.setIsTargetServiceActive(target1.service, 0, true);
+        boolean active = engine.getIsTargetServiceActive(target1.service, 0);
+        assert(active);
+
+        engine.setIsTargetServiceActive(target1.service, 1, false);
+        active = engine.getIsTargetServiceActive(target1.service, 1);
+        assert(!active);
+    }
+
     @MediumTest
     /**
      * V2 introduces flex time as well as service components.
@@ -339,20 +486,20 @@
         final String authority2 = "auth2";
         final String authority3 = "auth3";
 
-        final long dayPoll = (60 * 60 * 24);
-        final long dayFuzz = 60;
-        final long thousandSecs = 1000;
-        final long thousandSecsFuzz = 100;
-        final Bundle extras = new Bundle();
-        PeriodicSync sync1 = new PeriodicSync(account, authority1, extras, dayPoll, dayFuzz);
-        PeriodicSync sync2 = new PeriodicSync(account, authority2, extras, dayPoll, dayFuzz);
-        PeriodicSync sync3 = new PeriodicSync(account, authority3, extras, dayPoll, dayFuzz);
-        PeriodicSync sync1s = new PeriodicSync(account, authority1, extras, thousandSecs, thousandSecsFuzz);
-        PeriodicSync sync2s = new PeriodicSync(account, authority2, extras, thousandSecs, thousandSecsFuzz);
-        PeriodicSync sync3s = new PeriodicSync(account, authority3, extras, thousandSecs, thousandSecsFuzz);
-        MockContentResolver mockResolver = new MockContentResolver();
+        EndPoint target1 = new EndPoint(account, authority1, 0);
+        EndPoint target2 = new EndPoint(account, authority2, 0);
+        EndPoint target3 = new EndPoint(account, authority3, 0);
+        EndPoint target4 = new EndPoint(account, authority3, 1);
 
-        final TestContext testContext = new TestContext(mockResolver, getContext());
+        PeriodicSync sync1 = new PeriodicSync(account, authority1, Bundle.EMPTY, dayPoll, dayFuzz);
+        PeriodicSync sync2 = new PeriodicSync(account, authority2, Bundle.EMPTY, dayPoll, dayFuzz);
+        PeriodicSync sync3 = new PeriodicSync(account, authority3, Bundle.EMPTY, dayPoll, dayFuzz);
+        PeriodicSync sync1s = new PeriodicSync(account, authority1, Bundle.EMPTY, thousandSecs,
+                thousandSecsFuzz);
+        PeriodicSync sync2s = new PeriodicSync(account, authority2, Bundle.EMPTY, thousandSecs,
+                thousandSecsFuzz);
+        PeriodicSync sync3s = new PeriodicSync(account, authority3, Bundle.EMPTY, thousandSecs,
+                thousandSecsFuzz);
 
         byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
                 + "<accounts version=\"2\" >\n"
@@ -378,21 +525,22 @@
         fos.write(accountsFileData);
         accountInfoFile.finishWrite(fos);
 
-        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
+        engine.clearAndReadState();
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1);
         assertEquals("Got incorrect # of syncs", 1, syncs.size());
         assertEquals(sync1, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync2, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 1, authority3);
+        syncs = engine.getPeriodicSyncs(target4);
+
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
@@ -411,13 +559,13 @@
 
         engine.clearAndReadState();
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(0, syncs.size());
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(0, syncs.size());
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(0, syncs.size());
 
         accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
@@ -440,15 +588,15 @@
 
         engine.clearAndReadState();
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(1, syncs.size());
         assertEquals(sync1s, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync2s, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync3s, syncs.get(0));
     }
@@ -460,6 +608,12 @@
         final String authority2 = "auth2";
         final String authority3 = "auth3";
         final Bundle extras = new Bundle();
+
+        EndPoint target1 = new EndPoint(account, authority1, 0);
+        EndPoint target2 = new EndPoint(account, authority2, 0);
+        EndPoint target3 = new EndPoint(account, authority3, 0);
+        EndPoint target4 = new EndPoint(account, authority3, 1);
+
         PeriodicSync sync1 = new PeriodicSync(account, authority1, extras, (long) (60 * 60 * 24));
         PeriodicSync sync2 = new PeriodicSync(account, authority2, extras, (long) (60 * 60 * 24));
         PeriodicSync sync3 = new PeriodicSync(account, authority3, extras, (long) (60 * 60 * 24));
@@ -488,19 +642,20 @@
 
         SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1);
         assertEquals(1, syncs.size());
         assertEquals("expected sync1: " + sync1.toString() + " == sync 2" + syncs.get(0).toString(), sync1, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync2, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
+        syncs = engine.getPeriodicSyncs(target4);
 
-        syncs = engine.getPeriodicSyncs(account, 1, authority3);
+
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
@@ -518,13 +673,13 @@
 
         engine.clearAndReadState();
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(0, syncs.size());
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(0, syncs.size());
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(0, syncs.size());
 
         accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
@@ -547,15 +702,15 @@
 
         engine.clearAndReadState();
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(1, syncs.size());
         assertEquals(sync1s, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync2s, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync3s, syncs.get(0));
     }
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index 42c2aff..f9a222f 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -19,9 +19,6 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.provider.Settings;
-
 
 import android.telephony.cdma.CdmaCellLocation;
 import android.telephony.gsm.GsmCellLocation;
diff --git a/telephony/java/android/telephony/CellSignalStrength.java b/telephony/java/android/telephony/CellSignalStrength.java
index 3b470fc..9c23f78 100644
--- a/telephony/java/android/telephony/CellSignalStrength.java
+++ b/telephony/java/android/telephony/CellSignalStrength.java
@@ -16,9 +16,6 @@
 
 package android.telephony;
 
-import android.os.Parcel;
-import android.os.Parcelable;
-
 /**
  * Abstract base class for cell phone signal strength related information.
  */
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index ff77fc0..022bf12 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -23,7 +23,6 @@
 import android.telephony.SignalStrength;
 import android.telephony.CellLocation;
 import android.telephony.CellInfo;
-import android.telephony.Rlog;
 
 import com.android.internal.telephony.IPhoneStateListener;
 
diff --git a/telephony/java/android/telephony/Rlog.java b/telephony/java/android/telephony/Rlog.java
index 9ac7bda..2a7f7af 100644
--- a/telephony/java/android/telephony/Rlog.java
+++ b/telephony/java/android/telephony/Rlog.java
@@ -16,13 +16,8 @@
 
 package android.telephony;
 
-import com.android.internal.os.RuntimeInit;
-
 import android.util.Log;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
 /**
  * A class to log strings to the RADIO LOG.
  *
diff --git a/telephony/java/android/telephony/ThirdPartyCallListener.java b/telephony/java/android/telephony/ThirdPartyCallListener.java
new file mode 100644
index 0000000..00265f8
--- /dev/null
+++ b/telephony/java/android/telephony/ThirdPartyCallListener.java
@@ -0,0 +1,82 @@
+/*
+ * 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.telephony;
+
+import android.os.RemoteException;
+
+import com.android.internal.telephony.IThirdPartyCallListener;
+
+/**
+ * Interface provided to {@link android.telephony.ThirdPartyCallService}. The service can use this
+ * to notify the listener of changes to the call state.
+ */
+public class ThirdPartyCallListener {
+    private final IThirdPartyCallListener mListener;
+
+    // Call end reason. TODO: rename this to DisconnectCause once they are public.
+    public static final int CALL_END_NORMAL = 1;
+    public static final int CALL_END_INCOMING_MISSED = 2;
+    public static final int CALL_END_OTHER = 3;
+
+    public ThirdPartyCallListener(IThirdPartyCallListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("Invalid listener");
+        }
+        mListener = listener;
+    }
+
+    /**
+     * Called by the service when a call provider is available to perform the outgoing or incoming
+     * call.
+     */
+    public void onCallProviderAttached(ThirdPartyCallProvider callProvider) {
+        try {
+            mListener.onCallProviderAttached(callProvider.getCallback());
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Notifies the listener that ringing has started for this call.
+     */
+    public void onRingingStarted() {
+        try {
+            mListener.onRingingStarted();
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Notifies the listener that the call has been successfully established.
+     */
+    public void onCallEstablished() {
+        try {
+            mListener.onCallEstablished();
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Notifies the listener that the call has ended.
+     */
+    public void onCallEnded(int reason) {
+        try {
+            mListener.onCallEnded(reason);
+        } catch (RemoteException e) {
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ThirdPartyCallProvider.java b/telephony/java/android/telephony/ThirdPartyCallProvider.java
new file mode 100644
index 0000000..bd8a1ea
--- /dev/null
+++ b/telephony/java/android/telephony/ThirdPartyCallProvider.java
@@ -0,0 +1,107 @@
+/*
+ * 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.telephony;
+
+import android.os.Handler;
+import android.os.Message;
+
+import com.android.internal.telephony.IThirdPartyCallProvider;
+
+/**
+ * Interface sent to {@link android.telephony.ThirdPartyCallListener#onCallProviderAttached
+ * onCallProviderAttached}. This is used to control an outgoing or an incoming call.
+ */
+public class ThirdPartyCallProvider {
+    private static final int MSG_MUTE = 1;
+    private static final int MSG_HANGUP = 2;
+    private static final int MSG_INCOMING_CALL_ACCEPT = 3;
+    private static final int MSG_SEND_DTMF = 4;
+
+    /**
+     * Mutes or unmutes the call.
+     */
+    public void mute(boolean shouldMute) {
+        // default implementation empty
+    }
+
+    /**
+     * Ends the current call. If this is an unanswered incoming call then the call is rejected.
+     */
+    public void hangup() {
+        // default implementation empty
+    }
+
+   /**
+     * Accepts the incoming call.
+     */
+    public void incomingCallAccept() {
+        // default implementation empty
+    }
+
+    /**
+     * Sends the given DTMF code. The code can be '0'-'9', 'A'-'D', '#', or '*'.
+     */
+    public void sendDtmf(char c) {
+        // default implementation empty
+    }
+
+    IThirdPartyCallProvider getCallback() {
+        return mCallback;
+    }
+
+    private final IThirdPartyCallProvider mCallback = new IThirdPartyCallProvider.Stub() {
+        @Override
+        public void mute(boolean shouldMute) {
+            Message.obtain(mHandler, MSG_MUTE, shouldMute ? 1 : 0, 0).sendToTarget();
+        }
+
+        @Override
+        public void hangup() {
+            Message.obtain(mHandler, MSG_HANGUP).sendToTarget();
+        }
+
+        @Override
+        public void incomingCallAccept() {
+            Message.obtain(mHandler, MSG_INCOMING_CALL_ACCEPT).sendToTarget();
+        }
+
+        @Override
+        public void sendDtmf(char c) {
+            Message.obtain(mHandler, MSG_SEND_DTMF, (int) c, 0).sendToTarget();
+        }
+    };
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_MUTE:
+                    mute(msg.arg1 != 0);
+                    break;
+                case MSG_HANGUP:
+                    hangup();
+                    break;
+                case MSG_INCOMING_CALL_ACCEPT:
+                    incomingCallAccept();
+                    break;
+                case MSG_SEND_DTMF:
+                    sendDtmf((char) msg.arg1);
+                    break;
+            }
+        }
+    };
+}
diff --git a/telephony/java/android/telephony/ThirdPartyCallService.java b/telephony/java/android/telephony/ThirdPartyCallService.java
new file mode 100644
index 0000000..6eddb43
--- /dev/null
+++ b/telephony/java/android/telephony/ThirdPartyCallService.java
@@ -0,0 +1,94 @@
+/*
+ * 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.telephony;
+
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.util.Pair;
+
+import com.android.internal.telephony.IThirdPartyCallListener;
+import com.android.internal.telephony.IThirdPartyCallService;
+
+/**
+ * Interface provided by a service to start outgoing calls and attach to incoming calls.
+ */
+public class ThirdPartyCallService {
+    private static final int MSG_OUTGOING_CALL_INITIATE = 1;
+    private static final int MSG_INCOMING_CALL_ATTACH = 2;
+
+    /**
+     * Call to start a new outgoing call.
+     */
+    public void outgoingCallInitiate(ThirdPartyCallListener listener, String number) {
+        // default implementation empty
+    }
+
+    /**
+     * Call to attach to an incoming call.
+     */
+    public void incomingCallAttach(ThirdPartyCallListener listener, String callId) {
+        // default implementation empty
+    }
+
+    /**
+     * Returns an IBinder instance that can returned from the service's onBind function.
+     */
+    public IBinder getBinder() {
+        return mCallback;
+    }
+
+    private final IThirdPartyCallService.Stub mCallback = new IThirdPartyCallService.Stub() {
+        @Override
+        public void outgoingCallInitiate(IThirdPartyCallListener listener, String number) {
+            Rlog.w("ThirdPartyPhone", "ThirdPartyCallService.IThirdPartyCallService.out");
+            Message.obtain(mHandler, MSG_OUTGOING_CALL_INITIATE,
+                    Pair.create(listener, number)).sendToTarget();
+        }
+
+        @Override
+        public void incomingCallAttach(IThirdPartyCallListener listener, String callId) {
+            Rlog.w("ThirdPartyPhone", "ThirdPartyCallService.IThirdPartyCallService.in");
+            Message.obtain(mHandler, MSG_INCOMING_CALL_ATTACH,
+                    Pair.create(listener, callId)).sendToTarget();
+        }
+    };
+
+    private final Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            Rlog.w("ThirdPartyPhone", "ThirdPartyCallService.handleMessage: " + msg.what);
+            switch (msg.what) {
+                case MSG_OUTGOING_CALL_INITIATE: {
+                    Rlog.w("ThirdPartyPhone", "ThirdPartyCallService.handleMessage out");
+                    Pair<IThirdPartyCallListener, String> pair =
+                            (Pair<IThirdPartyCallListener, String>) msg.obj;
+                    ThirdPartyCallListener listener = new ThirdPartyCallListener(pair.first);
+                    outgoingCallInitiate(listener, pair.second);
+                    break;
+                }
+                case MSG_INCOMING_CALL_ATTACH: {
+                    Rlog.w("ThirdPartyPhone", "ThirdPartyCallService.handleMessage in");
+                    Pair<IThirdPartyCallListener, String> pair =
+                            (Pair<IThirdPartyCallListener, String>) msg.obj;
+                    ThirdPartyCallListener listener = new ThirdPartyCallListener(pair.first);
+                    incomingCallAttach(listener, pair.second);
+                    break;
+                }
+            }
+        }
+    };
+}
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index c63be91..74f73b5 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -24,7 +24,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.SystemProperties;
 import android.provider.ContactsContract.CommonDataKinds.SipAddress;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.PhoneLookup;
diff --git a/telephony/java/com/android/internal/telephony/IThirdPartyCallListener.aidl b/telephony/java/com/android/internal/telephony/IThirdPartyCallListener.aidl
new file mode 100644
index 0000000..bcf2d81
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IThirdPartyCallListener.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import com.android.internal.telephony.IThirdPartyCallProvider;
+
+/**
+ * Interface provided to ThirdPartyCallService. The service can use this to notify the listener of
+ * changes to the call state.
+ */
+oneway interface IThirdPartyCallListener {
+    /**
+     * Called by the service when a call provider is available to perform the outgoing or incoming
+     * call.
+     */
+    void onCallProviderAttached(IThirdPartyCallProvider callProvider);
+
+    /**
+     * Notifies the listener that ringing has started for this call.
+     */
+    void onRingingStarted();
+
+    /**
+     * Notifies the listener that the call has been successfully established.
+     */
+    void onCallEstablished();
+
+    /**
+     * Notifies the listener that the call has ended.
+     */
+    void onCallEnded(int reason);
+}
diff --git a/telephony/java/com/android/internal/telephony/IThirdPartyCallProvider.aidl b/telephony/java/com/android/internal/telephony/IThirdPartyCallProvider.aidl
new file mode 100644
index 0000000..a9d67a4
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IThirdPartyCallProvider.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import com.android.internal.telephony.IThirdPartyCallListener;
+
+/**
+ * Interface sent to ThirdPartyCallListener.onCallProviderAttached. This is used to control an
+ * outgoing or incoming call.
+ */
+oneway interface IThirdPartyCallProvider {
+    /**
+     * Mutes or unmutes the call.
+     */
+    void mute(boolean shouldMute);
+
+    /**
+     * Ends the current call. If this is an unanswered incoming call then the call is rejected (for
+     * example, a notification is sent to a server that the user declined the call).
+     */
+    void hangup();
+
+    /**
+     * Accepts the incoming call.
+     */
+    void incomingCallAccept();
+
+    /**
+     * Sends the given DTMF code. The code can be '0'-'9', 'A'-'D', '#', or '*'.
+     */
+    void sendDtmf(char c);
+}
diff --git a/telephony/java/com/android/internal/telephony/IThirdPartyCallService.aidl b/telephony/java/com/android/internal/telephony/IThirdPartyCallService.aidl
new file mode 100644
index 0000000..c9ee4ed
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IThirdPartyCallService.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import com.android.internal.telephony.IThirdPartyCallListener;
+
+/**
+ * Interface provided by a service to start outgoing calls and attach to incoming calls.
+ */
+oneway interface IThirdPartyCallService {
+    /**
+     * Call to start a new outgoing call.
+     */
+    void outgoingCallInitiate(IThirdPartyCallListener listener, String number);
+
+    /**
+     * Call to attach to an incoming call.
+     */
+    void incomingCallAttach(IThirdPartyCallListener listener, String callId);
+}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 821a11c..8e445d9 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -55,6 +55,8 @@
     int ILLEGAL_SIM_OR_ME = 15;               /* network selection failure due
                                                  to wrong SIM/ME and no
                                                  retries needed */
+    int MISSING_RESOURCE = 16;                /* no logical channel available */
+    int NO_SUCH_ELEMENT = 17;                 /* application not found on SIM */
 
     /* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
     int NETWORK_MODE_WCDMA_PREF     = 0; /* GSM/WCDMA (WCDMA preferred) */
@@ -265,6 +267,10 @@
     int RIL_REQUEST_SET_INITIAL_ATTACH_APN = 111;
     int RIL_REQUEST_IMS_REGISTRATION_STATE = 112;
     int RIL_REQUEST_IMS_SEND_SMS = 113;
+    int RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC = 114;
+    int RIL_REQUEST_SIM_OPEN_CHANNEL = 115;
+    int RIL_REQUEST_SIM_CLOSE_CHANNEL = 116;
+    int RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL = 117;
     int RIL_UNSOL_RESPONSE_BASE = 1000;
     int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
     int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
diff --git a/test-runner/src/android/test/ActivityInstrumentationTestCase.java b/test-runner/src/android/test/ActivityInstrumentationTestCase.java
index d12ff6f..a59ee35 100644
--- a/test-runner/src/android/test/ActivityInstrumentationTestCase.java
+++ b/test-runner/src/android/test/ActivityInstrumentationTestCase.java
@@ -18,8 +18,6 @@
 
 import android.app.Activity;
 
-import java.lang.reflect.Field;
-
 /**
  * This class provides functional testing of a single activity.  The activity under test will
  * be created using the system infrastructure (by calling InstrumentationTestCase.launchActivity())
diff --git a/test-runner/src/android/test/ApplicationTestCase.java b/test-runner/src/android/test/ApplicationTestCase.java
index ae5fa4d..f093181 100644
--- a/test-runner/src/android/test/ApplicationTestCase.java
+++ b/test-runner/src/android/test/ApplicationTestCase.java
@@ -16,8 +16,6 @@
 
 package android.test;
 
-import java.lang.reflect.Field;
-
 import android.app.Application;
 import android.app.Instrumentation;
 import android.content.Context;
diff --git a/test-runner/src/android/test/InstrumentationUtils.java b/test-runner/src/android/test/InstrumentationUtils.java
index 4c59097..1a7002a 100644
--- a/test-runner/src/android/test/InstrumentationUtils.java
+++ b/test-runner/src/android/test/InstrumentationUtils.java
@@ -16,8 +16,6 @@
 
 package android.test;
 
-import java.lang.reflect.Field;
-
 /**
  * 
  * The InstrumentationUtils class has all the utility functions needed for
diff --git a/test-runner/src/android/test/IsolatedContext.java b/test-runner/src/android/test/IsolatedContext.java
index bc00f68..f971b5d 100644
--- a/test-runner/src/android/test/IsolatedContext.java
+++ b/test-runner/src/android/test/IsolatedContext.java
@@ -39,8 +39,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
 import java.util.List;
 
 
diff --git a/test-runner/src/android/test/LaunchPerformanceBase.java b/test-runner/src/android/test/LaunchPerformanceBase.java
index c324446..d423e62 100644
--- a/test-runner/src/android/test/LaunchPerformanceBase.java
+++ b/test-runner/src/android/test/LaunchPerformanceBase.java
@@ -19,13 +19,6 @@
 import android.app.Instrumentation;
 import android.content.Intent;
 import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.Debug;
-import android.os.Process;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-
-import java.util.ArrayList;
 
 
 /**
diff --git a/test-runner/src/android/test/MoreAsserts.java b/test-runner/src/android/test/MoreAsserts.java
index 83cc420..fb0faba 100644
--- a/test-runner/src/android/test/MoreAsserts.java
+++ b/test-runner/src/android/test/MoreAsserts.java
@@ -16,7 +16,6 @@
 
 package android.test;
 
-import com.google.android.collect.Lists;
 import junit.framework.Assert;
 
 import java.util.Arrays;
diff --git a/test-runner/src/android/test/ServiceTestCase.java b/test-runner/src/android/test/ServiceTestCase.java
index d8ced38..ba20c09 100644
--- a/test-runner/src/android/test/ServiceTestCase.java
+++ b/test-runner/src/android/test/ServiceTestCase.java
@@ -18,14 +18,11 @@
 
 import android.app.Application;
 import android.app.Service;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.os.IBinder;
-import android.os.RemoteException;
 import android.test.mock.MockApplication;
 
-import java.lang.reflect.Field;
 import java.util.Random;
 
 /**
@@ -263,6 +260,7 @@
         }
         if (mServiceCreated) {
             mService.onDestroy();
+            mServiceCreated = false;
         }
     }
 
diff --git a/test-runner/src/android/test/SingleLaunchActivityTestCase.java b/test-runner/src/android/test/SingleLaunchActivityTestCase.java
index 79c554a..72c93ce 100644
--- a/test-runner/src/android/test/SingleLaunchActivityTestCase.java
+++ b/test-runner/src/android/test/SingleLaunchActivityTestCase.java
@@ -17,8 +17,6 @@
 package android.test;
 
 import android.app.Activity;
-import android.view.IWindowManager;
-import android.os.ServiceManager;
 
 /**
  * If you would like to test a single activity with an
diff --git a/test-runner/src/android/test/mock/MockCursor.java b/test-runner/src/android/test/mock/MockCursor.java
index 5b8a4f4..a37c6eb 100644
--- a/test-runner/src/android/test/mock/MockCursor.java
+++ b/test-runner/src/android/test/mock/MockCursor.java
@@ -24,8 +24,6 @@
 import android.net.Uri;
 import android.os.Bundle;
 
-import java.util.Map;
-
 /**
  * <P>
  * A mock {@link android.database.Cursor} class that isolates the test code from real
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 661bd41..ff5c935 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -40,13 +40,10 @@
 import android.content.pm.ServiceInfo;
 import android.content.pm.VerificationParams;
 import android.content.pm.VerifierDeviceIdentity;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
-import android.os.Binder;
-import android.os.RemoteException;
 import android.os.UserHandle;
 
 import java.util.List;
diff --git a/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java b/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java
index 28f7216..8c89489 100644
--- a/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java
+++ b/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java
@@ -29,8 +29,6 @@
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
 
-import java.lang.reflect.InvocationTargetException;
-import java.util.Enumeration;
 import java.util.List;
 import java.util.Set;
 import java.util.HashSet;
diff --git a/test-runner/src/junit/runner/LoadingTestCollector.java b/test-runner/src/junit/runner/LoadingTestCollector.java
index 489d9d6..9101900 100644
--- a/test-runner/src/junit/runner/LoadingTestCollector.java
+++ b/test-runner/src/junit/runner/LoadingTestCollector.java
@@ -1,7 +1,6 @@
 package junit.runner;
 
 import java.lang.reflect.*;
-import junit.runner.*;
 import junit.framework.*;
 
 /**
diff --git a/test-runner/src/junit/runner/Sorter.java b/test-runner/src/junit/runner/Sorter.java
index 7731f66..8d9341d 100644
--- a/test-runner/src/junit/runner/Sorter.java
+++ b/test-runner/src/junit/runner/Sorter.java
@@ -2,8 +2,6 @@
 
 import java.util.*;
 
-import junit.runner.*;
-
 /**
  * A custom quick sort with support to customize the swap behaviour.
  * NOTICE: We can't use the the sorting support from the JDK 1.2 collection
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java
index 2b5e674..ea08a6a 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java
@@ -22,11 +22,25 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.FrameLayout;
 import android.widget.GridLayout;
-import android.widget.*;
+import android.widget.Space;
+import android.widget.TextView;
 
-import static android.text.InputType.*;
-import static android.widget.GridLayout.*;
+import static android.text.InputType.TYPE_CLASS_TEXT;
+import static android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+import static android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
+import static android.widget.GridLayout.ALIGN_BOUNDS;
+import static android.widget.GridLayout.BASELINE;
+import static android.widget.GridLayout.CENTER;
+import static android.widget.GridLayout.FILL;
+import static android.widget.GridLayout.LEFT;
+import static android.widget.GridLayout.RIGHT;
+import static android.widget.GridLayout.START;
+import static android.widget.GridLayout.Spec;
+import static android.widget.GridLayout.spec;
 
 public class BiDiTestGridLayoutCodeLtr extends Fragment {
 
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java
index 3a03c6c..fc3a92c 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java
@@ -22,11 +22,25 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.FrameLayout;
 import android.widget.GridLayout;
-import android.widget.*;
+import android.widget.Space;
+import android.widget.TextView;
 
-import static android.text.InputType.*;
-import static android.widget.GridLayout.*;
+import static android.text.InputType.TYPE_CLASS_TEXT;
+import static android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+import static android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
+import static android.widget.GridLayout.ALIGN_BOUNDS;
+import static android.widget.GridLayout.BASELINE;
+import static android.widget.GridLayout.CENTER;
+import static android.widget.GridLayout.FILL;
+import static android.widget.GridLayout.LEFT;
+import static android.widget.GridLayout.RIGHT;
+import static android.widget.GridLayout.START;
+import static android.widget.GridLayout.Spec;
+import static android.widget.GridLayout.spec;
 
 public class BiDiTestGridLayoutCodeRtl extends Fragment {
 
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java b/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java
index 4d3a843..196a5c1 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java
@@ -24,7 +24,13 @@
 import android.view.ViewGroup;
 import android.widget.Button;
 
-import static android.view.Gravity.*;
+import static android.view.Gravity.BOTTOM;
+import static android.view.Gravity.CENTER;
+import static android.view.Gravity.FILL;
+import static android.view.Gravity.LEFT;
+import static android.view.Gravity.NO_GRAVITY;
+import static android.view.Gravity.RIGHT;
+import static android.view.Gravity.TOP;
 
 public abstract class AbstractLayoutTest extends Activity {
 
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java b/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java
index b1c4486..5559707 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java
@@ -20,15 +20,25 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.GridLayout;
+import android.widget.GridLayout.Alignment;
+import android.widget.GridLayout.LayoutParams;
 import android.widget.TextView;
 
-import static android.widget.GridLayout.*;
+import static android.widget.GridLayout.BASELINE;
+import static android.widget.GridLayout.BOTTOM;
+import static android.widget.GridLayout.CENTER;
+import static android.widget.GridLayout.FILL;
+import static android.widget.GridLayout.LEFT;
+import static android.widget.GridLayout.RIGHT;
+import static android.widget.GridLayout.TOP;
+import static android.widget.GridLayout.spec;
 
-public class AlignmentTest  extends Activity {
+public class AlignmentTest extends Activity {
 
     public static final String[] HORIZONTAL_NAMES = {"LEFT", "center", "east", "fill"};
     public static final Alignment[] HORIZONTAL_ALIGNMENTS = {LEFT, CENTER, RIGHT, FILL};
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java b/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java
index 4ce449a..8047c5f1 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java
@@ -21,7 +21,10 @@
 import android.view.ViewGroup;
 import android.widget.GridLayout;
 
-import static android.widget.GridLayout.*;
+import static android.widget.GridLayout.Spec;
+import static android.widget.GridLayout.UNDEFINED;
+import static android.widget.GridLayout.VERTICAL;
+import static android.widget.GridLayout.spec;
 
 public class GridLayoutTest extends AbstractLayoutTest {
     public ViewGroup create(Context context) {
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java b/tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java
index c7f4665..dc5b12c 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java
@@ -20,9 +20,9 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
 
-import static android.widget.LinearLayout.*;
-import static android.widget.LinearLayout.LayoutParams.*;
+import static android.widget.LinearLayout.LayoutParams.WRAP_CONTENT;
 
 public class LinearLayoutTest extends AbstractLayoutTest {
     public ViewGroup create(Context context) {
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 1bb0db0..6f774f8 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -706,6 +706,15 @@
         </activity>
 
         <activity
+                android:name="ColorFiltersMutateActivity"
+                android:label="ColorFilters/Mutate Filters">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.android.test.hwui.TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity
                 android:name="LinesActivity"
                 android:label="Draw/Lines">
             <intent-filter>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java
new file mode 100644
index 0000000..808b5d3
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java
@@ -0,0 +1,180 @@
+/*
+ * 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.test.hwui;
+
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.LightingColorFilter;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.os.Bundle;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ColorFiltersMutateActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final BitmapsView view = new BitmapsView(this);
+        setContentView(view);
+    }
+
+    static class BitmapsView extends View {
+        private final Bitmap mBitmap1;
+        private final Bitmap mBitmap2;
+        private final Paint mColorMatrixPaint;
+        private final Paint mLightingPaint;
+        private final Paint mBlendPaint;
+
+        private float mSaturation = 0.0f;
+        private int mLightAdd = 0;
+        private int mLightMul = 0;
+        private int mPorterDuffColor = 0;
+
+        BitmapsView(Context c) {
+            super(c);
+
+            mBitmap1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
+            mBitmap2 = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset2);
+
+            mColorMatrixPaint = new Paint();
+            final ColorMatrix colorMatrix = new ColorMatrix();
+            colorMatrix.setSaturation(0);
+            mColorMatrixPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
+
+            mLightingPaint = new Paint();
+            mLightingPaint.setColorFilter(new LightingColorFilter(0, 0));
+
+            mBlendPaint = new Paint();
+            mBlendPaint.setColorFilter(new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_OVER));
+
+            ObjectAnimator sat = ObjectAnimator.ofFloat(this, "saturation", 1.0f);
+            sat.setDuration(1000);
+            sat.setRepeatCount(ObjectAnimator.INFINITE);
+            sat.setRepeatMode(ObjectAnimator.REVERSE);
+            sat.start();
+
+            ObjectAnimator light = ObjectAnimator.ofInt(this, "lightAdd", 0x00101030);
+            light.setEvaluator(new ArgbEvaluator());
+            light.setDuration(1000);
+            light.setRepeatCount(ObjectAnimator.INFINITE);
+            light.setRepeatMode(ObjectAnimator.REVERSE);
+            light.start();
+
+            ObjectAnimator mult = ObjectAnimator.ofInt(this, "lightMul", 0x0060ffff);
+            mult.setEvaluator(new ArgbEvaluator());
+            mult.setDuration(1000);
+            mult.setRepeatCount(ObjectAnimator.INFINITE);
+            mult.setRepeatMode(ObjectAnimator.REVERSE);
+            mult.start();
+
+            ObjectAnimator color = ObjectAnimator.ofInt(this, "porterDuffColor", 0x7f990040);
+            color.setEvaluator(new ArgbEvaluator());
+            color.setDuration(1000);
+            color.setRepeatCount(ObjectAnimator.INFINITE);
+            color.setRepeatMode(ObjectAnimator.REVERSE);
+            color.start();
+        }
+
+        public int getPorterDuffColor() {
+            return mPorterDuffColor;
+        }
+
+        public void setPorterDuffColor(int porterDuffColor) {
+            mPorterDuffColor = porterDuffColor;
+            final PorterDuffColorFilter filter =
+                    (PorterDuffColorFilter) mBlendPaint.getColorFilter();
+            filter.setColor(mPorterDuffColor);
+            invalidate();
+        }
+
+        public int getLightAdd() {
+            return mLightAdd;
+        }
+
+        public void setLightAdd(int lightAdd) {
+            mLightAdd = lightAdd;
+            final LightingColorFilter filter =
+                    (LightingColorFilter) mLightingPaint.getColorFilter();
+            filter.setColorAdd(lightAdd);
+            invalidate();
+        }
+
+        public int getLightMul() {
+            return mLightAdd;
+        }
+
+        public void setLightMul(int lightMul) {
+            mLightMul = lightMul;
+            final LightingColorFilter filter =
+                    (LightingColorFilter) mLightingPaint.getColorFilter();
+            filter.setColorMultiply(lightMul);
+            invalidate();
+        }
+
+        public void setSaturation(float saturation) {
+            mSaturation = saturation;
+            final ColorMatrixColorFilter filter =
+                    (ColorMatrixColorFilter) mColorMatrixPaint.getColorFilter();
+            final ColorMatrix m = filter.getColorMatrix();
+            m.setSaturation(saturation);
+            filter.setColorMatrix(m);
+            invalidate();
+        }
+
+        public float getSaturation() {
+            return mSaturation;
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+
+            canvas.drawARGB(255, 255, 255, 255);
+
+            canvas.save();
+            canvas.translate(120.0f, 50.0f);
+            canvas.drawBitmap(mBitmap1, 0.0f, 0.0f, mColorMatrixPaint);
+
+            canvas.translate(0.0f, 50.0f + mBitmap1.getHeight());
+            canvas.drawBitmap(mBitmap1, 0.0f, 0.0f, mLightingPaint);
+
+            canvas.translate(0.0f, 50.0f + mBitmap1.getHeight());
+            canvas.drawBitmap(mBitmap1, 0.0f, 0.0f, mBlendPaint);
+            canvas.restore();
+
+            canvas.save();
+            canvas.translate(120.0f + mBitmap1.getWidth() + 120.0f, 50.0f);
+            canvas.drawBitmap(mBitmap2, 0.0f, 0.0f, mColorMatrixPaint);
+
+            canvas.translate(0.0f, 50.0f + mBitmap2.getHeight());
+            canvas.drawBitmap(mBitmap2, 0.0f, 0.0f, mLightingPaint);
+
+            canvas.translate(0.0f, 50.0f + mBitmap2.getHeight());
+            canvas.drawBitmap(mBitmap2, 0.0f, 0.0f, mBlendPaint);
+            canvas.restore();
+        }
+    }
+}
diff --git a/tests/TileBenchmark/Android.mk b/tests/TileBenchmark/Android.mk
index 5851113..9a057af 100644
--- a/tests/TileBenchmark/Android.mk
+++ b/tests/TileBenchmark/Android.mk
@@ -17,7 +17,7 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES :=
 
 LOCAL_PACKAGE_NAME := TileBenchmark
 
@@ -25,4 +25,4 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-include $(BUILD_PACKAGE)
\ No newline at end of file
+include $(BUILD_PACKAGE)
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
deleted file mode 100644
index d8e113a..0000000
--- a/tools/aapt/AaptAssets.cpp
+++ /dev/null
@@ -1,2726 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-
-#include "AaptAssets.h"
-#include "ResourceFilter.h"
-#include "Main.h"
-
-#include <utils/misc.h>
-#include <utils/SortedVector.h>
-
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-
-static const char* kDefaultLocale = "default";
-static const char* kWildcardName = "any";
-static const char* kAssetDir = "assets";
-static const char* kResourceDir = "res";
-static const char* kValuesDir = "values";
-static const char* kMipmapDir = "mipmap";
-static const char* kInvalidChars = "/\\:";
-static const size_t kMaxAssetFileName = 100;
-
-static const String8 kResString(kResourceDir);
-
-/*
- * Names of asset files must meet the following criteria:
- *
- *  - the filename length must be less than kMaxAssetFileName bytes long
- *    (and can't be empty)
- *  - all characters must be 7-bit printable ASCII
- *  - none of { '/' '\\' ':' }
- *
- * Pass in just the filename, not the full path.
- */
-static bool validateFileName(const char* fileName)
-{
-    const char* cp = fileName;
-    size_t len = 0;
-
-    while (*cp != '\0') {
-        if ((*cp & 0x80) != 0)
-            return false;           // reject high ASCII
-        if (*cp < 0x20 || *cp >= 0x7f)
-            return false;           // reject control chars and 0x7f
-        if (strchr(kInvalidChars, *cp) != NULL)
-            return false;           // reject path sep chars
-        cp++;
-        len++;
-    }
-
-    if (len < 1 || len > kMaxAssetFileName)
-        return false;               // reject empty or too long
-
-    return true;
-}
-
-// The default to use if no other ignore pattern is defined.
-const char * const gDefaultIgnoreAssets =
-    "!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~";
-// The ignore pattern that can be passed via --ignore-assets in Main.cpp
-const char * gUserIgnoreAssets = NULL;
-
-static bool isHidden(const char *root, const char *path)
-{
-    // Patterns syntax:
-    // - Delimiter is :
-    // - Entry can start with the flag ! to avoid printing a warning
-    //   about the file being ignored.
-    // - Entry can have the flag "<dir>" to match only directories
-    //   or <file> to match only files. Default is to match both.
-    // - Entry can be a simplified glob "<prefix>*" or "*<suffix>"
-    //   where prefix/suffix must have at least 1 character (so that
-    //   we don't match a '*' catch-all pattern.)
-    // - The special filenames "." and ".." are always ignored.
-    // - Otherwise the full string is matched.
-    // - match is not case-sensitive.
-
-    if (strcmp(path, ".") == 0 || strcmp(path, "..") == 0) {
-        return true;
-    }
-
-    const char *delim = ":";
-    const char *p = gUserIgnoreAssets;
-    if (!p || !p[0]) {
-        p = getenv("ANDROID_AAPT_IGNORE");
-    }
-    if (!p || !p[0]) {
-        p = gDefaultIgnoreAssets;
-    }
-    char *patterns = strdup(p);
-
-    bool ignore = false;
-    bool chatty = true;
-    char *matchedPattern = NULL;
-
-    String8 fullPath(root);
-    fullPath.appendPath(path);
-    FileType type = getFileType(fullPath);
-
-    int plen = strlen(path);
-
-    // Note: we don't have strtok_r under mingw.
-    for(char *token = strtok(patterns, delim);
-            !ignore && token != NULL;
-            token = strtok(NULL, delim)) {
-        chatty = token[0] != '!';
-        if (!chatty) token++; // skip !
-        if (strncasecmp(token, "<dir>" , 5) == 0) {
-            if (type != kFileTypeDirectory) continue;
-            token += 5;
-        }
-        if (strncasecmp(token, "<file>", 6) == 0) {
-            if (type != kFileTypeRegular) continue;
-            token += 6;
-        }
-
-        matchedPattern = token;
-        int n = strlen(token);
-
-        if (token[0] == '*') {
-            // Match *suffix
-            token++;
-            n--;
-            if (n <= plen) {
-                ignore = strncasecmp(token, path + plen - n, n) == 0;
-            }
-        } else if (n > 1 && token[n - 1] == '*') {
-            // Match prefix*
-            ignore = strncasecmp(token, path, n - 1) == 0;
-        } else {
-            ignore = strcasecmp(token, path) == 0;
-        }
-    }
-
-    if (ignore && chatty) {
-        fprintf(stderr, "    (skipping %s '%s' due to ANDROID_AAPT_IGNORE pattern '%s')\n",
-                type == kFileTypeDirectory ? "dir" : "file",
-                path,
-                matchedPattern ? matchedPattern : "");
-    }
-
-    free(patterns);
-    return ignore;
-}
-
-// =========================================================================
-// =========================================================================
-// =========================================================================
-
-status_t
-AaptGroupEntry::parseNamePart(const String8& part, int* axis, uint32_t* value)
-{
-    ResTable_config config;
-
-    // IMSI - MCC
-    if (getMccName(part.string(), &config)) {
-        *axis = AXIS_MCC;
-        *value = config.mcc;
-        return 0;
-    }
-
-    // IMSI - MNC
-    if (getMncName(part.string(), &config)) {
-        *axis = AXIS_MNC;
-        *value = config.mnc;
-        return 0;
-    }
-
-    // locale - language
-    if (part.length() == 2 && isalpha(part[0]) && isalpha(part[1])) {
-        *axis = AXIS_LANGUAGE;
-        *value = part[1] << 8 | part[0];
-        return 0;
-    }
-
-    // locale - language_REGION
-    if (part.length() == 5 && isalpha(part[0]) && isalpha(part[1])
-            && part[2] == '_' && isalpha(part[3]) && isalpha(part[4])) {
-        *axis = AXIS_LANGUAGE;
-        *value = (part[4] << 24) | (part[3] << 16) | (part[1] << 8) | (part[0]);
-        return 0;
-    }
-
-    // layout direction
-    if (getLayoutDirectionName(part.string(), &config)) {
-        *axis = AXIS_LAYOUTDIR;
-        *value = (config.screenLayout&ResTable_config::MASK_LAYOUTDIR);
-        return 0;
-    }
-
-    // smallest screen dp width
-    if (getSmallestScreenWidthDpName(part.string(), &config)) {
-        *axis = AXIS_SMALLESTSCREENWIDTHDP;
-        *value = config.smallestScreenWidthDp;
-        return 0;
-    }
-
-    // screen dp width
-    if (getScreenWidthDpName(part.string(), &config)) {
-        *axis = AXIS_SCREENWIDTHDP;
-        *value = config.screenWidthDp;
-        return 0;
-    }
-
-    // screen dp height
-    if (getScreenHeightDpName(part.string(), &config)) {
-        *axis = AXIS_SCREENHEIGHTDP;
-        *value = config.screenHeightDp;
-        return 0;
-    }
-
-    // screen layout size
-    if (getScreenLayoutSizeName(part.string(), &config)) {
-        *axis = AXIS_SCREENLAYOUTSIZE;
-        *value = (config.screenLayout&ResTable_config::MASK_SCREENSIZE);
-        return 0;
-    }
-
-    // screen layout long
-    if (getScreenLayoutLongName(part.string(), &config)) {
-        *axis = AXIS_SCREENLAYOUTLONG;
-        *value = (config.screenLayout&ResTable_config::MASK_SCREENLONG);
-        return 0;
-    }
-
-    // orientation
-    if (getOrientationName(part.string(), &config)) {
-        *axis = AXIS_ORIENTATION;
-        *value = config.orientation;
-        return 0;
-    }
-
-    // ui mode type
-    if (getUiModeTypeName(part.string(), &config)) {
-        *axis = AXIS_UIMODETYPE;
-        *value = (config.uiMode&ResTable_config::MASK_UI_MODE_TYPE);
-        return 0;
-    }
-
-    // ui mode night
-    if (getUiModeNightName(part.string(), &config)) {
-        *axis = AXIS_UIMODENIGHT;
-        *value = (config.uiMode&ResTable_config::MASK_UI_MODE_NIGHT);
-        return 0;
-    }
-
-    // density
-    if (getDensityName(part.string(), &config)) {
-        *axis = AXIS_DENSITY;
-        *value = config.density;
-        return 0;
-    }
-
-    // touchscreen
-    if (getTouchscreenName(part.string(), &config)) {
-        *axis = AXIS_TOUCHSCREEN;
-        *value = config.touchscreen;
-        return 0;
-    }
-
-    // keyboard hidden
-    if (getKeysHiddenName(part.string(), &config)) {
-        *axis = AXIS_KEYSHIDDEN;
-        *value = config.inputFlags;
-        return 0;
-    }
-
-    // keyboard
-    if (getKeyboardName(part.string(), &config)) {
-        *axis = AXIS_KEYBOARD;
-        *value = config.keyboard;
-        return 0;
-    }
-
-    // navigation hidden
-    if (getNavHiddenName(part.string(), &config)) {
-        *axis = AXIS_NAVHIDDEN;
-        *value = config.inputFlags;
-        return 0;
-    }
-
-    // navigation
-    if (getNavigationName(part.string(), &config)) {
-        *axis = AXIS_NAVIGATION;
-        *value = config.navigation;
-        return 0;
-    }
-
-    // screen size
-    if (getScreenSizeName(part.string(), &config)) {
-        *axis = AXIS_SCREENSIZE;
-        *value = config.screenSize;
-        return 0;
-    }
-
-    // version
-    if (getVersionName(part.string(), &config)) {
-        *axis = AXIS_VERSION;
-        *value = config.version;
-        return 0;
-    }
-
-    return 1;
-}
-
-uint32_t
-AaptGroupEntry::getConfigValueForAxis(const ResTable_config& config, int axis)
-{
-    switch (axis) {
-        case AXIS_MCC:
-            return config.mcc;
-        case AXIS_MNC:
-            return config.mnc;
-        case AXIS_LANGUAGE:
-            return (((uint32_t)config.country[1]) << 24) | (((uint32_t)config.country[0]) << 16)
-                | (((uint32_t)config.language[1]) << 8) | (config.language[0]);
-        case AXIS_LAYOUTDIR:
-            return config.screenLayout&ResTable_config::MASK_LAYOUTDIR;
-        case AXIS_SCREENLAYOUTSIZE:
-            return config.screenLayout&ResTable_config::MASK_SCREENSIZE;
-        case AXIS_ORIENTATION:
-            return config.orientation;
-        case AXIS_UIMODETYPE:
-            return (config.uiMode&ResTable_config::MASK_UI_MODE_TYPE);
-        case AXIS_UIMODENIGHT:
-            return (config.uiMode&ResTable_config::MASK_UI_MODE_NIGHT);
-        case AXIS_DENSITY:
-            return config.density;
-        case AXIS_TOUCHSCREEN:
-            return config.touchscreen;
-        case AXIS_KEYSHIDDEN:
-            return config.inputFlags;
-        case AXIS_KEYBOARD:
-            return config.keyboard;
-        case AXIS_NAVIGATION:
-            return config.navigation;
-        case AXIS_SCREENSIZE:
-            return config.screenSize;
-        case AXIS_SMALLESTSCREENWIDTHDP:
-            return config.smallestScreenWidthDp;
-        case AXIS_SCREENWIDTHDP:
-            return config.screenWidthDp;
-        case AXIS_SCREENHEIGHTDP:
-            return config.screenHeightDp;
-        case AXIS_VERSION:
-            return config.version;
-    }
-    return 0;
-}
-
-bool
-AaptGroupEntry::configSameExcept(const ResTable_config& config,
-        const ResTable_config& otherConfig, int axis)
-{
-    for (int i=AXIS_START; i<=AXIS_END; i++) {
-        if (i == axis) {
-            continue;
-        }
-        if (getConfigValueForAxis(config, i) != getConfigValueForAxis(otherConfig, i)) {
-            return false;
-        }
-    }
-    return true;
-}
-
-bool
-AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
-{
-    mParamsChanged = true;
-
-    Vector<String8> parts;
-
-    String8 mcc, mnc, loc, layoutsize, layoutlong, orient, den;
-    String8 touch, key, keysHidden, nav, navHidden, size, layoutDir, vers;
-    String8 uiModeType, uiModeNight, smallestwidthdp, widthdp, heightdp;
-
-    const char *p = dir;
-    const char *q;
-    while (NULL != (q = strchr(p, '-'))) {
-        String8 val(p, q-p);
-        val.toLower();
-        parts.add(val);
-        //printf("part: %s\n", parts[parts.size()-1].string());
-        p = q+1;
-    }
-    String8 val(p);
-    val.toLower();
-    parts.add(val);
-    //printf("part: %s\n", parts[parts.size()-1].string());
-
-    const int N = parts.size();
-    int index = 0;
-    String8 part = parts[index];
-
-    // resource type
-    if (!isValidResourceType(part)) {
-        return false;
-    }
-    *resType = part;
-
-    index++;
-    if (index == N) {
-        goto success;
-    }
-    part = parts[index];
-
-    // imsi - mcc
-    if (getMccName(part.string())) {
-        mcc = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not mcc: %s\n", part.string());
-    }
-
-    // imsi - mnc
-    if (getMncName(part.string())) {
-        mnc = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not mcc: %s\n", part.string());
-    }
-
-    // locale - language
-    if (part.length() == 2 && isalpha(part[0]) && isalpha(part[1])) {
-        loc = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not language: %s\n", part.string());
-    }
-
-    // locale - region
-    if (loc.length() > 0
-            && part.length() == 3 && part[0] == 'r' && part[0] && part[1]) {
-        loc += "-";
-        part.toUpper();
-        loc += part.string() + 1;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not region: %s\n", part.string());
-    }
-
-    if (getLayoutDirectionName(part.string())) {
-        layoutDir = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not layout direction: %s\n", part.string());
-    }
-
-    if (getSmallestScreenWidthDpName(part.string())) {
-        smallestwidthdp = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not smallest screen width dp: %s\n", part.string());
-    }
-
-    if (getScreenWidthDpName(part.string())) {
-        widthdp = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not screen width dp: %s\n", part.string());
-    }
-
-    if (getScreenHeightDpName(part.string())) {
-        heightdp = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not screen height dp: %s\n", part.string());
-    }
-
-    if (getScreenLayoutSizeName(part.string())) {
-        layoutsize = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not screen layout size: %s\n", part.string());
-    }
-
-    if (getScreenLayoutLongName(part.string())) {
-        layoutlong = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not screen layout long: %s\n", part.string());
-    }
-
-    // orientation
-    if (getOrientationName(part.string())) {
-        orient = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not orientation: %s\n", part.string());
-    }
-
-    // ui mode type
-    if (getUiModeTypeName(part.string())) {
-        uiModeType = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not ui mode type: %s\n", part.string());
-    }
-
-    // ui mode night
-    if (getUiModeNightName(part.string())) {
-        uiModeNight = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not ui mode night: %s\n", part.string());
-    }
-
-    // density
-    if (getDensityName(part.string())) {
-        den = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not density: %s\n", part.string());
-    }
-
-    // touchscreen
-    if (getTouchscreenName(part.string())) {
-        touch = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not touchscreen: %s\n", part.string());
-    }
-
-    // keyboard hidden
-    if (getKeysHiddenName(part.string())) {
-        keysHidden = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not keysHidden: %s\n", part.string());
-    }
-
-    // keyboard
-    if (getKeyboardName(part.string())) {
-        key = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not keyboard: %s\n", part.string());
-    }
-
-    // navigation hidden
-    if (getNavHiddenName(part.string())) {
-        navHidden = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not navHidden: %s\n", part.string());
-    }
-
-    if (getNavigationName(part.string())) {
-        nav = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not navigation: %s\n", part.string());
-    }
-
-    if (getScreenSizeName(part.string())) {
-        size = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not screen size: %s\n", part.string());
-    }
-
-    if (getVersionName(part.string())) {
-        vers = part;
-
-        index++;
-        if (index == N) {
-            goto success;
-        }
-        part = parts[index];
-    } else {
-        //printf("not version: %s\n", part.string());
-    }
-
-    // if there are extra parts, it doesn't match
-    return false;
-
-success:
-    this->mcc = mcc;
-    this->mnc = mnc;
-    this->locale = loc;
-    this->screenLayoutSize = layoutsize;
-    this->screenLayoutLong = layoutlong;
-    this->smallestScreenWidthDp = smallestwidthdp;
-    this->screenWidthDp = widthdp;
-    this->screenHeightDp = heightdp;
-    this->orientation = orient;
-    this->uiModeType = uiModeType;
-    this->uiModeNight = uiModeNight;
-    this->density = den;
-    this->touchscreen = touch;
-    this->keysHidden = keysHidden;
-    this->keyboard = key;
-    this->navHidden = navHidden;
-    this->navigation = nav;
-    this->screenSize = size;
-    this->layoutDirection = layoutDir;
-    this->version = vers;
-
-    // what is this anyway?
-    this->vendor = "";
-
-    return true;
-}
-
-String8
-AaptGroupEntry::toString() const
-{
-    String8 s = this->mcc;
-    s += ",";
-    s += this->mnc;
-    s += ",";
-    s += this->locale;
-    s += ",";
-    s += layoutDirection;
-    s += ",";
-    s += smallestScreenWidthDp;
-    s += ",";
-    s += screenWidthDp;
-    s += ",";
-    s += screenHeightDp;
-    s += ",";
-    s += screenLayoutSize;
-    s += ",";
-    s += screenLayoutLong;
-    s += ",";
-    s += this->orientation;
-    s += ",";
-    s += uiModeType;
-    s += ",";
-    s += uiModeNight;
-    s += ",";
-    s += density;
-    s += ",";
-    s += touchscreen;
-    s += ",";
-    s += keysHidden;
-    s += ",";
-    s += keyboard;
-    s += ",";
-    s += navHidden;
-    s += ",";
-    s += navigation;
-    s += ",";
-    s += screenSize;
-    s += ",";
-    s += version;
-    return s;
-}
-
-String8
-AaptGroupEntry::toDirName(const String8& resType) const
-{
-    String8 s = resType;
-    if (this->mcc != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += mcc;
-    }
-    if (this->mnc != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += mnc;
-    }
-    if (this->locale != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += locale;
-    }
-    if (this->layoutDirection != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += layoutDirection;
-    }
-    if (this->smallestScreenWidthDp != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += smallestScreenWidthDp;
-    }
-    if (this->screenWidthDp != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += screenWidthDp;
-    }
-    if (this->screenHeightDp != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += screenHeightDp;
-    }
-    if (this->screenLayoutSize != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += screenLayoutSize;
-    }
-    if (this->screenLayoutLong != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += screenLayoutLong;
-    }
-    if (this->orientation != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += orientation;
-    }
-    if (this->uiModeType != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += uiModeType;
-    }
-    if (this->uiModeNight != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += uiModeNight;
-    }
-    if (this->density != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += density;
-    }
-    if (this->touchscreen != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += touchscreen;
-    }
-    if (this->keysHidden != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += keysHidden;
-    }
-    if (this->keyboard != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += keyboard;
-    }
-    if (this->navHidden != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += navHidden;
-    }
-    if (this->navigation != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += navigation;
-    }
-    if (this->screenSize != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += screenSize;
-    }
-    if (this->version != "") {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += version;
-    }
-
-    return s;
-}
-
-bool AaptGroupEntry::getMccName(const char* name,
-                                    ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->mcc = 0;
-        return true;
-    }
-    const char* c = name;
-    if (tolower(*c) != 'm') return false;
-    c++;
-    if (tolower(*c) != 'c') return false;
-    c++;
-    if (tolower(*c) != 'c') return false;
-    c++;
-
-    const char* val = c;
-
-    while (*c >= '0' && *c <= '9') {
-        c++;
-    }
-    if (*c != 0) return false;
-    if (c-val != 3) return false;
-
-    int d = atoi(val);
-    if (d != 0) {
-        if (out) out->mcc = d;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getMncName(const char* name,
-                                    ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->mcc = 0;
-        return true;
-    }
-    const char* c = name;
-    if (tolower(*c) != 'm') return false;
-    c++;
-    if (tolower(*c) != 'n') return false;
-    c++;
-    if (tolower(*c) != 'c') return false;
-    c++;
-
-    const char* val = c;
-
-    while (*c >= '0' && *c <= '9') {
-        c++;
-    }
-    if (*c != 0) return false;
-    if (c-val == 0 || c-val > 3) return false;
-
-    if (out) {
-        out->mnc = atoi(val);
-        if (out->mnc == 0) {
-            out->mnc = ACONFIGURATION_MNC_ZERO;
-        }
-    }
-
-    return true;
-}
-
-/*
- * Does this directory name fit the pattern of a locale dir ("en-rUS" or
- * "default")?
- *
- * TODO: Should insist that the first two letters are lower case, and the
- * second two are upper.
- */
-bool AaptGroupEntry::getLocaleName(const char* fileName,
-                                   ResTable_config* out)
-{
-    if (strcmp(fileName, kWildcardName) == 0
-            || strcmp(fileName, kDefaultLocale) == 0) {
-        if (out) {
-            out->language[0] = 0;
-            out->language[1] = 0;
-            out->country[0] = 0;
-            out->country[1] = 0;
-        }
-        return true;
-    }
-
-    if (strlen(fileName) == 2 && isalpha(fileName[0]) && isalpha(fileName[1])) {
-        if (out) {
-            out->language[0] = fileName[0];
-            out->language[1] = fileName[1];
-            out->country[0] = 0;
-            out->country[1] = 0;
-        }
-        return true;
-    }
-
-    if (strlen(fileName) == 5 &&
-        isalpha(fileName[0]) &&
-        isalpha(fileName[1]) &&
-        fileName[2] == '-' &&
-        isalpha(fileName[3]) &&
-        isalpha(fileName[4])) {
-        if (out) {
-            out->language[0] = fileName[0];
-            out->language[1] = fileName[1];
-            out->country[0] = fileName[3];
-            out->country[1] = fileName[4];
-        }
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getLayoutDirectionName(const char* name, ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->screenLayout =
-                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
-                | ResTable_config::LAYOUTDIR_ANY;
-        return true;
-    } else if (strcmp(name, "ldltr") == 0) {
-        if (out) out->screenLayout =
-                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
-                | ResTable_config::LAYOUTDIR_LTR;
-        return true;
-    } else if (strcmp(name, "ldrtl") == 0) {
-        if (out) out->screenLayout =
-                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
-                | ResTable_config::LAYOUTDIR_RTL;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getScreenLayoutSizeName(const char* name,
-                                     ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->screenLayout =
-                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
-                | ResTable_config::SCREENSIZE_ANY;
-        return true;
-    } else if (strcmp(name, "small") == 0) {
-        if (out) out->screenLayout =
-                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
-                | ResTable_config::SCREENSIZE_SMALL;
-        return true;
-    } else if (strcmp(name, "normal") == 0) {
-        if (out) out->screenLayout =
-                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
-                | ResTable_config::SCREENSIZE_NORMAL;
-        return true;
-    } else if (strcmp(name, "large") == 0) {
-        if (out) out->screenLayout =
-                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
-                | ResTable_config::SCREENSIZE_LARGE;
-        return true;
-    } else if (strcmp(name, "xlarge") == 0) {
-        if (out) out->screenLayout =
-                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
-                | ResTable_config::SCREENSIZE_XLARGE;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getScreenLayoutLongName(const char* name,
-                                     ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->screenLayout =
-                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
-                | ResTable_config::SCREENLONG_ANY;
-        return true;
-    } else if (strcmp(name, "long") == 0) {
-        if (out) out->screenLayout =
-                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
-                | ResTable_config::SCREENLONG_YES;
-        return true;
-    } else if (strcmp(name, "notlong") == 0) {
-        if (out) out->screenLayout =
-                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
-                | ResTable_config::SCREENLONG_NO;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getOrientationName(const char* name,
-                                        ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->orientation = out->ORIENTATION_ANY;
-        return true;
-    } else if (strcmp(name, "port") == 0) {
-        if (out) out->orientation = out->ORIENTATION_PORT;
-        return true;
-    } else if (strcmp(name, "land") == 0) {
-        if (out) out->orientation = out->ORIENTATION_LAND;
-        return true;
-    } else if (strcmp(name, "square") == 0) {
-        if (out) out->orientation = out->ORIENTATION_SQUARE;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getUiModeTypeName(const char* name,
-                                       ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->uiMode =
-                (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
-                | ResTable_config::UI_MODE_TYPE_ANY;
-        return true;
-    } else if (strcmp(name, "desk") == 0) {
-      if (out) out->uiMode =
-              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
-              | ResTable_config::UI_MODE_TYPE_DESK;
-        return true;
-    } else if (strcmp(name, "car") == 0) {
-      if (out) out->uiMode =
-              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
-              | ResTable_config::UI_MODE_TYPE_CAR;
-        return true;
-    } else if (strcmp(name, "television") == 0) {
-      if (out) out->uiMode =
-              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
-              | ResTable_config::UI_MODE_TYPE_TELEVISION;
-        return true;
-    } else if (strcmp(name, "appliance") == 0) {
-      if (out) out->uiMode =
-              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
-              | ResTable_config::UI_MODE_TYPE_APPLIANCE;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getUiModeNightName(const char* name,
-                                          ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->uiMode =
-                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
-                | ResTable_config::UI_MODE_NIGHT_ANY;
-        return true;
-    } else if (strcmp(name, "night") == 0) {
-        if (out) out->uiMode =
-                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
-                | ResTable_config::UI_MODE_NIGHT_YES;
-        return true;
-    } else if (strcmp(name, "notnight") == 0) {
-      if (out) out->uiMode =
-              (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
-              | ResTable_config::UI_MODE_NIGHT_NO;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getDensityName(const char* name,
-                                    ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->density = ResTable_config::DENSITY_DEFAULT;
-        return true;
-    }
-    
-    if (strcmp(name, "nodpi") == 0) {
-        if (out) out->density = ResTable_config::DENSITY_NONE;
-        return true;
-    }
-    
-    if (strcmp(name, "ldpi") == 0) {
-        if (out) out->density = ResTable_config::DENSITY_LOW;
-        return true;
-    }
-    
-    if (strcmp(name, "mdpi") == 0) {
-        if (out) out->density = ResTable_config::DENSITY_MEDIUM;
-        return true;
-    }
-    
-    if (strcmp(name, "tvdpi") == 0) {
-        if (out) out->density = ResTable_config::DENSITY_TV;
-        return true;
-    }
-    
-    if (strcmp(name, "hdpi") == 0) {
-        if (out) out->density = ResTable_config::DENSITY_HIGH;
-        return true;
-    }
-
-    if (strcmp(name, "xhdpi") == 0) {
-        if (out) out->density = ResTable_config::DENSITY_XHIGH;
-        return true;
-    }
-
-    if (strcmp(name, "xxhdpi") == 0) {
-        if (out) out->density = ResTable_config::DENSITY_XXHIGH;
-        return true;
-    }
-
-    if (strcmp(name, "xxxhdpi") == 0) {
-        if (out) out->density = ResTable_config::DENSITY_XXXHIGH;
-        return true;
-    }
-
-    char* c = (char*)name;
-    while (*c >= '0' && *c <= '9') {
-        c++;
-    }
-
-    // check that we have 'dpi' after the last digit.
-    if (toupper(c[0]) != 'D' ||
-            toupper(c[1]) != 'P' ||
-            toupper(c[2]) != 'I' ||
-            c[3] != 0) {
-        return false;
-    }
-
-    // temporarily replace the first letter with \0 to
-    // use atoi.
-    char tmp = c[0];
-    c[0] = '\0';
-
-    int d = atoi(name);
-    c[0] = tmp;
-
-    if (d != 0) {
-        if (out) out->density = d;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getTouchscreenName(const char* name,
-                                        ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->touchscreen = out->TOUCHSCREEN_ANY;
-        return true;
-    } else if (strcmp(name, "notouch") == 0) {
-        if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;
-        return true;
-    } else if (strcmp(name, "stylus") == 0) {
-        if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;
-        return true;
-    } else if (strcmp(name, "finger") == 0) {
-        if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getKeysHiddenName(const char* name,
-                                       ResTable_config* out)
-{
-    uint8_t mask = 0;
-    uint8_t value = 0;
-    if (strcmp(name, kWildcardName) == 0) {
-        mask = ResTable_config::MASK_KEYSHIDDEN;
-        value = ResTable_config::KEYSHIDDEN_ANY;
-    } else if (strcmp(name, "keysexposed") == 0) {
-        mask = ResTable_config::MASK_KEYSHIDDEN;
-        value = ResTable_config::KEYSHIDDEN_NO;
-    } else if (strcmp(name, "keyshidden") == 0) {
-        mask = ResTable_config::MASK_KEYSHIDDEN;
-        value = ResTable_config::KEYSHIDDEN_YES;
-    } else if (strcmp(name, "keyssoft") == 0) {
-        mask = ResTable_config::MASK_KEYSHIDDEN;
-        value = ResTable_config::KEYSHIDDEN_SOFT;
-    }
-
-    if (mask != 0) {
-        if (out) out->inputFlags = (out->inputFlags&~mask) | value;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getKeyboardName(const char* name,
-                                        ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->keyboard = out->KEYBOARD_ANY;
-        return true;
-    } else if (strcmp(name, "nokeys") == 0) {
-        if (out) out->keyboard = out->KEYBOARD_NOKEYS;
-        return true;
-    } else if (strcmp(name, "qwerty") == 0) {
-        if (out) out->keyboard = out->KEYBOARD_QWERTY;
-        return true;
-    } else if (strcmp(name, "12key") == 0) {
-        if (out) out->keyboard = out->KEYBOARD_12KEY;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getNavHiddenName(const char* name,
-                                       ResTable_config* out)
-{
-    uint8_t mask = 0;
-    uint8_t value = 0;
-    if (strcmp(name, kWildcardName) == 0) {
-        mask = ResTable_config::MASK_NAVHIDDEN;
-        value = ResTable_config::NAVHIDDEN_ANY;
-    } else if (strcmp(name, "navexposed") == 0) {
-        mask = ResTable_config::MASK_NAVHIDDEN;
-        value = ResTable_config::NAVHIDDEN_NO;
-    } else if (strcmp(name, "navhidden") == 0) {
-        mask = ResTable_config::MASK_NAVHIDDEN;
-        value = ResTable_config::NAVHIDDEN_YES;
-    }
-
-    if (mask != 0) {
-        if (out) out->inputFlags = (out->inputFlags&~mask) | value;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getNavigationName(const char* name,
-                                     ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->navigation = out->NAVIGATION_ANY;
-        return true;
-    } else if (strcmp(name, "nonav") == 0) {
-        if (out) out->navigation = out->NAVIGATION_NONAV;
-        return true;
-    } else if (strcmp(name, "dpad") == 0) {
-        if (out) out->navigation = out->NAVIGATION_DPAD;
-        return true;
-    } else if (strcmp(name, "trackball") == 0) {
-        if (out) out->navigation = out->NAVIGATION_TRACKBALL;
-        return true;
-    } else if (strcmp(name, "wheel") == 0) {
-        if (out) out->navigation = out->NAVIGATION_WHEEL;
-        return true;
-    }
-
-    return false;
-}
-
-bool AaptGroupEntry::getScreenSizeName(const char* name, ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) {
-            out->screenWidth = out->SCREENWIDTH_ANY;
-            out->screenHeight = out->SCREENHEIGHT_ANY;
-        }
-        return true;
-    }
-
-    const char* x = name;
-    while (*x >= '0' && *x <= '9') x++;
-    if (x == name || *x != 'x') return false;
-    String8 xName(name, x-name);
-    x++;
-
-    const char* y = x;
-    while (*y >= '0' && *y <= '9') y++;
-    if (y == name || *y != 0) return false;
-    String8 yName(x, y-x);
-
-    uint16_t w = (uint16_t)atoi(xName.string());
-    uint16_t h = (uint16_t)atoi(yName.string());
-    if (w < h) {
-        return false;
-    }
-
-    if (out) {
-        out->screenWidth = w;
-        out->screenHeight = h;
-    }
-
-    return true;
-}
-
-bool AaptGroupEntry::getSmallestScreenWidthDpName(const char* name, ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) {
-            out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;
-        }
-        return true;
-    }
-
-    if (*name != 's') return false;
-    name++;
-    if (*name != 'w') return false;
-    name++;
-    const char* x = name;
-    while (*x >= '0' && *x <= '9') x++;
-    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
-    String8 xName(name, x-name);
-
-    if (out) {
-        out->smallestScreenWidthDp = (uint16_t)atoi(xName.string());
-    }
-
-    return true;
-}
-
-bool AaptGroupEntry::getScreenWidthDpName(const char* name, ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) {
-            out->screenWidthDp = out->SCREENWIDTH_ANY;
-        }
-        return true;
-    }
-
-    if (*name != 'w') return false;
-    name++;
-    const char* x = name;
-    while (*x >= '0' && *x <= '9') x++;
-    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
-    String8 xName(name, x-name);
-
-    if (out) {
-        out->screenWidthDp = (uint16_t)atoi(xName.string());
-    }
-
-    return true;
-}
-
-bool AaptGroupEntry::getScreenHeightDpName(const char* name, ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) {
-            out->screenHeightDp = out->SCREENWIDTH_ANY;
-        }
-        return true;
-    }
-
-    if (*name != 'h') return false;
-    name++;
-    const char* x = name;
-    while (*x >= '0' && *x <= '9') x++;
-    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
-    String8 xName(name, x-name);
-
-    if (out) {
-        out->screenHeightDp = (uint16_t)atoi(xName.string());
-    }
-
-    return true;
-}
-
-bool AaptGroupEntry::getVersionName(const char* name, ResTable_config* out)
-{
-    if (strcmp(name, kWildcardName) == 0) {
-        if (out) {
-            out->sdkVersion = out->SDKVERSION_ANY;
-            out->minorVersion = out->MINORVERSION_ANY;
-        }
-        return true;
-    }
-
-    if (*name != 'v') {
-        return false;
-    }
-
-    name++;
-    const char* s = name;
-    while (*s >= '0' && *s <= '9') s++;
-    if (s == name || *s != 0) return false;
-    String8 sdkName(name, s-name);
-
-    if (out) {
-        out->sdkVersion = (uint16_t)atoi(sdkName.string());
-        out->minorVersion = 0;
-    }
-
-    return true;
-}
-
-int AaptGroupEntry::compare(const AaptGroupEntry& o) const
-{
-    int v = mcc.compare(o.mcc);
-    if (v == 0) v = mnc.compare(o.mnc);
-    if (v == 0) v = locale.compare(o.locale);
-    if (v == 0) v = layoutDirection.compare(o.layoutDirection);
-    if (v == 0) v = vendor.compare(o.vendor);
-    if (v == 0) v = smallestScreenWidthDp.compare(o.smallestScreenWidthDp);
-    if (v == 0) v = screenWidthDp.compare(o.screenWidthDp);
-    if (v == 0) v = screenHeightDp.compare(o.screenHeightDp);
-    if (v == 0) v = screenLayoutSize.compare(o.screenLayoutSize);
-    if (v == 0) v = screenLayoutLong.compare(o.screenLayoutLong);
-    if (v == 0) v = orientation.compare(o.orientation);
-    if (v == 0) v = uiModeType.compare(o.uiModeType);
-    if (v == 0) v = uiModeNight.compare(o.uiModeNight);
-    if (v == 0) v = density.compare(o.density);
-    if (v == 0) v = touchscreen.compare(o.touchscreen);
-    if (v == 0) v = keysHidden.compare(o.keysHidden);
-    if (v == 0) v = keyboard.compare(o.keyboard);
-    if (v == 0) v = navHidden.compare(o.navHidden);
-    if (v == 0) v = navigation.compare(o.navigation);
-    if (v == 0) v = screenSize.compare(o.screenSize);
-    if (v == 0) v = version.compare(o.version);
-    return v;
-}
-
-const ResTable_config& AaptGroupEntry::toParams() const
-{
-    if (!mParamsChanged) {
-        return mParams;
-    }
-
-    mParamsChanged = false;
-    ResTable_config& params(mParams);
-    memset(&params, 0, sizeof(params));
-    getMccName(mcc.string(), &params);
-    getMncName(mnc.string(), &params);
-    getLocaleName(locale.string(), &params);
-    getLayoutDirectionName(layoutDirection.string(), &params);
-    getSmallestScreenWidthDpName(smallestScreenWidthDp.string(), &params);
-    getScreenWidthDpName(screenWidthDp.string(), &params);
-    getScreenHeightDpName(screenHeightDp.string(), &params);
-    getScreenLayoutSizeName(screenLayoutSize.string(), &params);
-    getScreenLayoutLongName(screenLayoutLong.string(), &params);
-    getOrientationName(orientation.string(), &params);
-    getUiModeTypeName(uiModeType.string(), &params);
-    getUiModeNightName(uiModeNight.string(), &params);
-    getDensityName(density.string(), &params);
-    getTouchscreenName(touchscreen.string(), &params);
-    getKeysHiddenName(keysHidden.string(), &params);
-    getKeyboardName(keyboard.string(), &params);
-    getNavHiddenName(navHidden.string(), &params);
-    getNavigationName(navigation.string(), &params);
-    getScreenSizeName(screenSize.string(), &params);
-    getVersionName(version.string(), &params);
-    
-    // Fix up version number based on specified parameters.
-    int minSdk = 0;
-    if (params.smallestScreenWidthDp != ResTable_config::SCREENWIDTH_ANY
-            || params.screenWidthDp != ResTable_config::SCREENWIDTH_ANY
-            || params.screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
-        minSdk = SDK_HONEYCOMB_MR2;
-    } else if ((params.uiMode&ResTable_config::MASK_UI_MODE_TYPE)
-                != ResTable_config::UI_MODE_TYPE_ANY
-            ||  (params.uiMode&ResTable_config::MASK_UI_MODE_NIGHT)
-                != ResTable_config::UI_MODE_NIGHT_ANY) {
-        minSdk = SDK_FROYO;
-    } else if ((params.screenLayout&ResTable_config::MASK_SCREENSIZE)
-                != ResTable_config::SCREENSIZE_ANY
-            ||  (params.screenLayout&ResTable_config::MASK_SCREENLONG)
-                != ResTable_config::SCREENLONG_ANY
-            || params.density != ResTable_config::DENSITY_DEFAULT) {
-        minSdk = SDK_DONUT;
-    }
-    
-    if (minSdk > params.sdkVersion) {
-        params.sdkVersion = minSdk;
-    }
-    
-    return params;
-}
-
-// =========================================================================
-// =========================================================================
-// =========================================================================
-
-void* AaptFile::editData(size_t size)
-{
-    if (size <= mBufferSize) {
-        mDataSize = size;
-        return mData;
-    }
-    size_t allocSize = (size*3)/2;
-    void* buf = realloc(mData, allocSize);
-    if (buf == NULL) {
-        return NULL;
-    }
-    mData = buf;
-    mDataSize = size;
-    mBufferSize = allocSize;
-    return buf;
-}
-
-void* AaptFile::editData(size_t* outSize)
-{
-    if (outSize) {
-        *outSize = mDataSize;
-    }
-    return mData;
-}
-
-void* AaptFile::padData(size_t wordSize)
-{
-    const size_t extra = mDataSize%wordSize;
-    if (extra == 0) {
-        return mData;
-    }
-
-    size_t initial = mDataSize;
-    void* data = editData(initial+(wordSize-extra));
-    if (data != NULL) {
-        memset(((uint8_t*)data) + initial, 0, wordSize-extra);
-    }
-    return data;
-}
-
-status_t AaptFile::writeData(const void* data, size_t size)
-{
-    size_t end = mDataSize;
-    size_t total = size + end;
-    void* buf = editData(total);
-    if (buf == NULL) {
-        return UNKNOWN_ERROR;
-    }
-    memcpy(((char*)buf)+end, data, size);
-    return NO_ERROR;
-}
-
-void AaptFile::clearData()
-{
-    if (mData != NULL) free(mData);
-    mData = NULL;
-    mDataSize = 0;
-    mBufferSize = 0;
-}
-
-String8 AaptFile::getPrintableSource() const
-{
-    if (hasData()) {
-        String8 name(mGroupEntry.toDirName(String8()));
-        name.appendPath(mPath);
-        name.append(" #generated");
-        return name;
-    }
-    return mSourceFile;
-}
-
-// =========================================================================
-// =========================================================================
-// =========================================================================
-
-status_t AaptGroup::addFile(const sp<AaptFile>& file)
-{
-    if (mFiles.indexOfKey(file->getGroupEntry()) < 0) {
-        file->mPath = mPath;
-        mFiles.add(file->getGroupEntry(), file);
-        return NO_ERROR;
-    }
-
-#if 0
-    printf("Error adding file %s: group %s already exists in leaf=%s path=%s\n",
-            file->getSourceFile().string(),
-            file->getGroupEntry().toDirName(String8()).string(),
-            mLeaf.string(), mPath.string());
-#endif
-
-    SourcePos(file->getSourceFile(), -1).error("Duplicate file.\n%s: Original is here.",
-                                               getPrintableSource().string());
-    return UNKNOWN_ERROR;
-}
-
-void AaptGroup::removeFile(size_t index)
-{
-	mFiles.removeItemsAt(index);
-}
-
-void AaptGroup::print(const String8& prefix) const
-{
-    printf("%s%s\n", prefix.string(), getPath().string());
-    const size_t N=mFiles.size();
-    size_t i;
-    for (i=0; i<N; i++) {
-        sp<AaptFile> file = mFiles.valueAt(i);
-        const AaptGroupEntry& e = file->getGroupEntry();
-        if (file->hasData()) {
-            printf("%s  Gen: (%s) %d bytes\n", prefix.string(), e.toDirName(String8()).string(),
-                    (int)file->getSize());
-        } else {
-            printf("%s  Src: (%s) %s\n", prefix.string(), e.toDirName(String8()).string(),
-                    file->getPrintableSource().string());
-        }
-        //printf("%s  File Group Entry: %s\n", prefix.string(),
-        //        file->getGroupEntry().toDirName(String8()).string());
-    }
-}
-
-String8 AaptGroup::getPrintableSource() const
-{
-    if (mFiles.size() > 0) {
-        // Arbitrarily pull the first source file out of the list.
-        return mFiles.valueAt(0)->getPrintableSource();
-    }
-
-    // Should never hit this case, but to be safe...
-    return getPath();
-
-}
-
-// =========================================================================
-// =========================================================================
-// =========================================================================
-
-status_t AaptDir::addFile(const String8& name, const sp<AaptGroup>& file)
-{
-    if (mFiles.indexOfKey(name) >= 0) {
-        return ALREADY_EXISTS;
-    }
-    mFiles.add(name, file);
-    return NO_ERROR;
-}
-
-status_t AaptDir::addDir(const String8& name, const sp<AaptDir>& dir)
-{
-    if (mDirs.indexOfKey(name) >= 0) {
-        return ALREADY_EXISTS;
-    }
-    mDirs.add(name, dir);
-    return NO_ERROR;
-}
-
-sp<AaptDir> AaptDir::makeDir(const String8& path)
-{
-    String8 name;
-    String8 remain = path;
-
-    sp<AaptDir> subdir = this;
-    while (name = remain.walkPath(&remain), remain != "") {
-        subdir = subdir->makeDir(name);
-    }
-
-    ssize_t i = subdir->mDirs.indexOfKey(name);
-    if (i >= 0) {
-        return subdir->mDirs.valueAt(i);
-    }
-    sp<AaptDir> dir = new AaptDir(name, subdir->mPath.appendPathCopy(name));
-    subdir->mDirs.add(name, dir);
-    return dir;
-}
-
-void AaptDir::removeFile(const String8& name)
-{
-    mFiles.removeItem(name);
-}
-
-void AaptDir::removeDir(const String8& name)
-{
-    mDirs.removeItem(name);
-}
-
-status_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file)
-{
-    sp<AaptGroup> group;
-    if (mFiles.indexOfKey(leafName) >= 0) {
-        group = mFiles.valueFor(leafName);
-    } else {
-        group = new AaptGroup(leafName, mPath.appendPathCopy(leafName));
-        mFiles.add(leafName, group);
-    }
-
-    return group->addFile(file);
-}
-
-ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,
-                            const AaptGroupEntry& kind, const String8& resType,
-                            sp<FilePathStore>& fullResPaths)
-{
-    Vector<String8> fileNames;
-    {
-        DIR* dir = NULL;
-
-        dir = opendir(srcDir.string());
-        if (dir == NULL) {
-            fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno));
-            return UNKNOWN_ERROR;
-        }
-
-        /*
-         * Slurp the filenames out of the directory.
-         */
-        while (1) {
-            struct dirent* entry;
-
-            entry = readdir(dir);
-            if (entry == NULL)
-                break;
-
-            if (isHidden(srcDir.string(), entry->d_name))
-                continue;
-
-            String8 name(entry->d_name);
-            fileNames.add(name);
-            // Add fully qualified path for dependency purposes
-            // if we're collecting them
-            if (fullResPaths != NULL) {
-                fullResPaths->add(srcDir.appendPathCopy(name));
-            }
-        }
-        closedir(dir);
-    }
-
-    ssize_t count = 0;
-
-    /*
-     * Stash away the files and recursively descend into subdirectories.
-     */
-    const size_t N = fileNames.size();
-    size_t i;
-    for (i = 0; i < N; i++) {
-        String8 pathName(srcDir);
-        FileType type;
-
-        pathName.appendPath(fileNames[i].string());
-        type = getFileType(pathName.string());
-        if (type == kFileTypeDirectory) {
-            sp<AaptDir> subdir;
-            bool notAdded = false;
-            if (mDirs.indexOfKey(fileNames[i]) >= 0) {
-                subdir = mDirs.valueFor(fileNames[i]);
-            } else {
-                subdir = new AaptDir(fileNames[i], mPath.appendPathCopy(fileNames[i]));
-                notAdded = true;
-            }
-            ssize_t res = subdir->slurpFullTree(bundle, pathName, kind,
-                                                resType, fullResPaths);
-            if (res < NO_ERROR) {
-                return res;
-            }
-            if (res > 0 && notAdded) {
-                mDirs.add(fileNames[i], subdir);
-            }
-            count += res;
-        } else if (type == kFileTypeRegular) {
-            sp<AaptFile> file = new AaptFile(pathName, kind, resType);
-            status_t err = addLeafFile(fileNames[i], file);
-            if (err != NO_ERROR) {
-                return err;
-            }
-
-            count++;
-
-        } else {
-            if (bundle->getVerbose())
-                printf("   (ignoring non-file/dir '%s')\n", pathName.string());
-        }
-    }
-
-    return count;
-}
-
-status_t AaptDir::validate() const
-{
-    const size_t NF = mFiles.size();
-    const size_t ND = mDirs.size();
-    size_t i;
-    for (i = 0; i < NF; i++) {
-        if (!validateFileName(mFiles.valueAt(i)->getLeaf().string())) {
-            SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error(
-                    "Invalid filename.  Unable to add.");
-            return UNKNOWN_ERROR;
-        }
-
-        size_t j;
-        for (j = i+1; j < NF; j++) {
-            if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(),
-                           mFiles.valueAt(j)->getLeaf().string()) == 0) {
-                SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error(
-                        "File is case-insensitive equivalent to: %s",
-                        mFiles.valueAt(j)->getPrintableSource().string());
-                return UNKNOWN_ERROR;
-            }
-
-            // TODO: if ".gz", check for non-.gz; if non-, check for ".gz"
-            // (this is mostly caught by the "marked" stuff, below)
-        }
-
-        for (j = 0; j < ND; j++) {
-            if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(),
-                           mDirs.valueAt(j)->getLeaf().string()) == 0) {
-                SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error(
-                        "File conflicts with dir from: %s",
-                        mDirs.valueAt(j)->getPrintableSource().string());
-                return UNKNOWN_ERROR;
-            }
-        }
-    }
-
-    for (i = 0; i < ND; i++) {
-        if (!validateFileName(mDirs.valueAt(i)->getLeaf().string())) {
-            SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error(
-                    "Invalid directory name, unable to add.");
-            return UNKNOWN_ERROR;
-        }
-
-        size_t j;
-        for (j = i+1; j < ND; j++) {
-            if (strcasecmp(mDirs.valueAt(i)->getLeaf().string(),
-                           mDirs.valueAt(j)->getLeaf().string()) == 0) {
-                SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error(
-                        "Directory is case-insensitive equivalent to: %s",
-                        mDirs.valueAt(j)->getPrintableSource().string());
-                return UNKNOWN_ERROR;
-            }
-        }
-
-        status_t err = mDirs.valueAt(i)->validate();
-        if (err != NO_ERROR) {
-            return err;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-void AaptDir::print(const String8& prefix) const
-{
-    const size_t ND=getDirs().size();
-    size_t i;
-    for (i=0; i<ND; i++) {
-        getDirs().valueAt(i)->print(prefix);
-    }
-
-    const size_t NF=getFiles().size();
-    for (i=0; i<NF; i++) {
-        getFiles().valueAt(i)->print(prefix);
-    }
-}
-
-String8 AaptDir::getPrintableSource() const
-{
-    if (mFiles.size() > 0) {
-        // Arbitrarily pull the first file out of the list as the source dir.
-        return mFiles.valueAt(0)->getPrintableSource().getPathDir();
-    }
-    if (mDirs.size() > 0) {
-        // Or arbitrarily pull the first dir out of the list as the source dir.
-        return mDirs.valueAt(0)->getPrintableSource().getPathDir();
-    }
-
-    // Should never hit this case, but to be safe...
-    return mPath;
-
-}
-
-// =========================================================================
-// =========================================================================
-// =========================================================================
-
-status_t AaptSymbols::applyJavaSymbols(const sp<AaptSymbols>& javaSymbols)
-{
-    status_t err = NO_ERROR;
-    size_t N = javaSymbols->mSymbols.size();
-    for (size_t i=0; i<N; i++) {
-        const String8& name = javaSymbols->mSymbols.keyAt(i);
-        const AaptSymbolEntry& entry = javaSymbols->mSymbols.valueAt(i);
-        ssize_t pos = mSymbols.indexOfKey(name);
-        if (pos < 0) {
-            entry.sourcePos.error("Symbol '%s' declared with <java-symbol> not defined\n", name.string());
-            err = UNKNOWN_ERROR;
-            continue;
-        }
-        //printf("**** setting symbol #%d/%d %s to isJavaSymbol=%d\n",
-        //        i, N, name.string(), entry.isJavaSymbol ? 1 : 0);
-        mSymbols.editValueAt(pos).isJavaSymbol = entry.isJavaSymbol;
-    }
-
-    N = javaSymbols->mNestedSymbols.size();
-    for (size_t i=0; i<N; i++) {
-        const String8& name = javaSymbols->mNestedSymbols.keyAt(i);
-        const sp<AaptSymbols>& symbols = javaSymbols->mNestedSymbols.valueAt(i);
-        ssize_t pos = mNestedSymbols.indexOfKey(name);
-        if (pos < 0) {
-            SourcePos pos;
-            pos.error("Java symbol dir %s not defined\n", name.string());
-            err = UNKNOWN_ERROR;
-            continue;
-        }
-        //printf("**** applying java symbols in dir %s\n", name.string());
-        status_t myerr = mNestedSymbols.valueAt(pos)->applyJavaSymbols(symbols);
-        if (myerr != NO_ERROR) {
-            err = myerr;
-        }
-    }
-
-    return err;
-}
-
-// =========================================================================
-// =========================================================================
-// =========================================================================
-
-AaptAssets::AaptAssets()
-    : AaptDir(String8(), String8()),
-      mChanged(false), mHaveIncludedAssets(false), mRes(NULL)
-{
-}
-
-const SortedVector<AaptGroupEntry>& AaptAssets::getGroupEntries() const {
-    if (mChanged) {
-    }
-    return mGroupEntries;
-}
-
-status_t AaptAssets::addFile(const String8& name, const sp<AaptGroup>& file)
-{
-    mChanged = true;
-    return AaptDir::addFile(name, file);
-}
-
-sp<AaptFile> AaptAssets::addFile(
-        const String8& filePath, const AaptGroupEntry& entry,
-        const String8& srcDir, sp<AaptGroup>* outGroup,
-        const String8& resType)
-{
-    sp<AaptDir> dir = this;
-    sp<AaptGroup> group;
-    sp<AaptFile> file;
-    String8 root, remain(filePath), partialPath;
-    while (remain.length() > 0) {
-        root = remain.walkPath(&remain);
-        partialPath.appendPath(root);
-
-        const String8 rootStr(root);
-
-        if (remain.length() == 0) {
-            ssize_t i = dir->getFiles().indexOfKey(rootStr);
-            if (i >= 0) {
-                group = dir->getFiles().valueAt(i);
-            } else {
-                group = new AaptGroup(rootStr, filePath);
-                status_t res = dir->addFile(rootStr, group);
-                if (res != NO_ERROR) {
-                    return NULL;
-                }
-            }
-            file = new AaptFile(srcDir.appendPathCopy(filePath), entry, resType);
-            status_t res = group->addFile(file);
-            if (res != NO_ERROR) {
-                return NULL;
-            }
-            break;
-
-        } else {
-            ssize_t i = dir->getDirs().indexOfKey(rootStr);
-            if (i >= 0) {
-                dir = dir->getDirs().valueAt(i);
-            } else {
-                sp<AaptDir> subdir = new AaptDir(rootStr, partialPath);
-                status_t res = dir->addDir(rootStr, subdir);
-                if (res != NO_ERROR) {
-                    return NULL;
-                }
-                dir = subdir;
-            }
-        }
-    }
-
-    mGroupEntries.add(entry);
-    if (outGroup) *outGroup = group;
-    return file;
-}
-
-void AaptAssets::addResource(const String8& leafName, const String8& path,
-                const sp<AaptFile>& file, const String8& resType)
-{
-    sp<AaptDir> res = AaptDir::makeDir(kResString);
-    String8 dirname = file->getGroupEntry().toDirName(resType);
-    sp<AaptDir> subdir = res->makeDir(dirname);
-    sp<AaptGroup> grr = new AaptGroup(leafName, path);
-    grr->addFile(file);
-
-    subdir->addFile(leafName, grr);
-}
-
-
-ssize_t AaptAssets::slurpFromArgs(Bundle* bundle)
-{
-    int count;
-    int totalCount = 0;
-    FileType type;
-    const Vector<const char *>& resDirs = bundle->getResourceSourceDirs();
-    const size_t dirCount =resDirs.size();
-    sp<AaptAssets> current = this;
-
-    const int N = bundle->getFileSpecCount();
-
-    /*
-     * If a package manifest was specified, include that first.
-     */
-    if (bundle->getAndroidManifestFile() != NULL) {
-        // place at root of zip.
-        String8 srcFile(bundle->getAndroidManifestFile());
-        addFile(srcFile.getPathLeaf(), AaptGroupEntry(), srcFile.getPathDir(),
-                NULL, String8());
-        totalCount++;
-    }
-
-    /*
-     * If a directory of custom assets was supplied, slurp 'em up.
-     */
-    if (bundle->getAssetSourceDir()) {
-        const char* assetDir = bundle->getAssetSourceDir();
-
-        FileType type = getFileType(assetDir);
-        if (type == kFileTypeNonexistent) {
-            fprintf(stderr, "ERROR: asset directory '%s' does not exist\n", assetDir);
-            return UNKNOWN_ERROR;
-        }
-        if (type != kFileTypeDirectory) {
-            fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDir);
-            return UNKNOWN_ERROR;
-        }
-
-        String8 assetRoot(assetDir);
-        sp<AaptDir> assetAaptDir = makeDir(String8(kAssetDir));
-        AaptGroupEntry group;
-        count = assetAaptDir->slurpFullTree(bundle, assetRoot, group,
-                                            String8(), mFullAssetPaths);
-        if (count < 0) {
-            totalCount = count;
-            goto bail;
-        }
-        if (count > 0) {
-            mGroupEntries.add(group);
-        }
-        totalCount += count;
-
-        if (bundle->getVerbose())
-            printf("Found %d custom asset file%s in %s\n",
-                   count, (count==1) ? "" : "s", assetDir);
-    }
-
-    /*
-     * If a directory of resource-specific assets was supplied, slurp 'em up.
-     */
-    for (size_t i=0; i<dirCount; i++) {
-        const char *res = resDirs[i];
-        if (res) {
-            type = getFileType(res);
-            if (type == kFileTypeNonexistent) {
-                fprintf(stderr, "ERROR: resource directory '%s' does not exist\n", res);
-                return UNKNOWN_ERROR;
-            }
-            if (type == kFileTypeDirectory) {
-                if (i>0) {
-                    sp<AaptAssets> nextOverlay = new AaptAssets();
-                    current->setOverlay(nextOverlay);
-                    current = nextOverlay;
-                    current->setFullResPaths(mFullResPaths);
-                }
-                count = current->slurpResourceTree(bundle, String8(res));
-
-                if (count < 0) {
-                    totalCount = count;
-                    goto bail;
-                }
-                totalCount += count;
-            }
-            else {
-                fprintf(stderr, "ERROR: '%s' is not a directory\n", res);
-                return UNKNOWN_ERROR;
-            }
-        }
-        
-    }
-    /*
-     * Now do any additional raw files.
-     */
-    for (int arg=0; arg<N; arg++) {
-        const char* assetDir = bundle->getFileSpecEntry(arg);
-
-        FileType type = getFileType(assetDir);
-        if (type == kFileTypeNonexistent) {
-            fprintf(stderr, "ERROR: input directory '%s' does not exist\n", assetDir);
-            return UNKNOWN_ERROR;
-        }
-        if (type != kFileTypeDirectory) {
-            fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDir);
-            return UNKNOWN_ERROR;
-        }
-
-        String8 assetRoot(assetDir);
-
-        if (bundle->getVerbose())
-            printf("Processing raw dir '%s'\n", (const char*) assetDir);
-
-        /*
-         * Do a recursive traversal of subdir tree.  We don't make any
-         * guarantees about ordering, so we're okay with an inorder search
-         * using whatever order the OS happens to hand back to us.
-         */
-        count = slurpFullTree(bundle, assetRoot, AaptGroupEntry(), String8(), mFullAssetPaths);
-        if (count < 0) {
-            /* failure; report error and remove archive */
-            totalCount = count;
-            goto bail;
-        }
-        totalCount += count;
-
-        if (bundle->getVerbose())
-            printf("Found %d asset file%s in %s\n",
-                   count, (count==1) ? "" : "s", assetDir);
-    }
-
-    count = validate();
-    if (count != NO_ERROR) {
-        totalCount = count;
-        goto bail;
-    }
-
-    count = filter(bundle);
-    if (count != NO_ERROR) {
-        totalCount = count;
-        goto bail;
-    }
-
-bail:
-    return totalCount;
-}
-
-ssize_t AaptAssets::slurpFullTree(Bundle* bundle, const String8& srcDir,
-                                    const AaptGroupEntry& kind,
-                                    const String8& resType,
-                                    sp<FilePathStore>& fullResPaths)
-{
-    ssize_t res = AaptDir::slurpFullTree(bundle, srcDir, kind, resType, fullResPaths);
-    if (res > 0) {
-        mGroupEntries.add(kind);
-    }
-
-    return res;
-}
-
-ssize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir)
-{
-    ssize_t err = 0;
-
-    DIR* dir = opendir(srcDir.string());
-    if (dir == NULL) {
-        fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno));
-        return UNKNOWN_ERROR;
-    }
-
-    status_t count = 0;
-
-    /*
-     * Run through the directory, looking for dirs that match the
-     * expected pattern.
-     */
-    while (1) {
-        struct dirent* entry = readdir(dir);
-        if (entry == NULL) {
-            break;
-        }
-
-        if (isHidden(srcDir.string(), entry->d_name)) {
-            continue;
-        }
-
-        String8 subdirName(srcDir);
-        subdirName.appendPath(entry->d_name);
-
-        AaptGroupEntry group;
-        String8 resType;
-        bool b = group.initFromDirName(entry->d_name, &resType);
-        if (!b) {
-            fprintf(stderr, "invalid resource directory name: %s/%s\n", srcDir.string(),
-                    entry->d_name);
-            err = -1;
-            continue;
-        }
-
-        if (bundle->getMaxResVersion() != NULL && group.getVersionString().length() != 0) {
-            int maxResInt = atoi(bundle->getMaxResVersion());
-            const char *verString = group.getVersionString().string();
-            int dirVersionInt = atoi(verString + 1); // skip 'v' in version name
-            if (dirVersionInt > maxResInt) {
-              fprintf(stderr, "max res %d, skipping %s\n", maxResInt, entry->d_name);
-              continue;
-            }
-        }
-
-        FileType type = getFileType(subdirName.string());
-
-        if (type == kFileTypeDirectory) {
-            sp<AaptDir> dir = makeDir(resType);
-            ssize_t res = dir->slurpFullTree(bundle, subdirName, group,
-                                                resType, mFullResPaths);
-            if (res < 0) {
-                count = res;
-                goto bail;
-            }
-            if (res > 0) {
-                mGroupEntries.add(group);
-                count += res;
-            }
-
-            // Only add this directory if we don't already have a resource dir
-            // for the current type.  This ensures that we only add the dir once
-            // for all configs.
-            sp<AaptDir> rdir = resDir(resType);
-            if (rdir == NULL) {
-                mResDirs.add(dir);
-            }
-        } else {
-            if (bundle->getVerbose()) {
-                fprintf(stderr, "   (ignoring file '%s')\n", subdirName.string());
-            }
-        }
-    }
-
-bail:
-    closedir(dir);
-    dir = NULL;
-
-    if (err != 0) {
-        return err;
-    }
-    return count;
-}
-
-ssize_t
-AaptAssets::slurpResourceZip(Bundle* bundle, const char* filename)
-{
-    int count = 0;
-    SortedVector<AaptGroupEntry> entries;
-
-    ZipFile* zip = new ZipFile;
-    status_t err = zip->open(filename, ZipFile::kOpenReadOnly);
-    if (err != NO_ERROR) {
-        fprintf(stderr, "error opening zip file %s\n", filename);
-        count = err;
-        delete zip;
-        return -1;
-    }
-
-    const int N = zip->getNumEntries();
-    for (int i=0; i<N; i++) {
-        ZipEntry* entry = zip->getEntryByIndex(i);
-        if (entry->getDeleted()) {
-            continue;
-        }
-
-        String8 entryName(entry->getFileName());
-
-        String8 dirName = entryName.getPathDir();
-        sp<AaptDir> dir = dirName == "" ? this : makeDir(dirName);
-
-        String8 resType;
-        AaptGroupEntry kind;
-
-        String8 remain;
-        if (entryName.walkPath(&remain) == kResourceDir) {
-            // these are the resources, pull their type out of the directory name
-            kind.initFromDirName(remain.walkPath().string(), &resType);
-        } else {
-            // these are untyped and don't have an AaptGroupEntry
-        }
-        if (entries.indexOf(kind) < 0) {
-            entries.add(kind);
-            mGroupEntries.add(kind);
-        }
-
-        // use the one from the zip file if they both exist.
-        dir->removeFile(entryName.getPathLeaf());
-
-        sp<AaptFile> file = new AaptFile(entryName, kind, resType);
-        status_t err = dir->addLeafFile(entryName.getPathLeaf(), file);
-        if (err != NO_ERROR) {
-            fprintf(stderr, "err=%s entryName=%s\n", strerror(err), entryName.string());
-            count = err;
-            goto bail;
-        }
-        file->setCompressionMethod(entry->getCompressionMethod());
-
-#if 0
-        if (entryName == "AndroidManifest.xml") {
-            printf("AndroidManifest.xml\n");
-        }
-        printf("\n\nfile: %s\n", entryName.string());
-#endif
-
-        size_t len = entry->getUncompressedLen();
-        void* data = zip->uncompress(entry);
-        void* buf = file->editData(len);
-        memcpy(buf, data, len);
-
-#if 0
-        const int OFF = 0;
-        const unsigned char* p = (unsigned char*)data;
-        const unsigned char* end = p+len;
-        p += OFF;
-        for (int i=0; i<32 && p < end; i++) {
-            printf("0x%03x ", i*0x10 + OFF);
-            for (int j=0; j<0x10 && p < end; j++) {
-                printf(" %02x", *p);
-                p++;
-            }
-            printf("\n");
-        }
-#endif
-
-        free(data);
-
-        count++;
-    }
-
-bail:
-    delete zip;
-    return count;
-}
-
-status_t AaptAssets::filter(Bundle* bundle)
-{
-    ResourceFilter reqFilter;
-    status_t err = reqFilter.parse(bundle->getConfigurations());
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    ResourceFilter prefFilter;
-    err = prefFilter.parse(bundle->getPreferredConfigurations());
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    if (reqFilter.isEmpty() && prefFilter.isEmpty()) {
-        return NO_ERROR;
-    }
-
-    if (bundle->getVerbose()) {
-        if (!reqFilter.isEmpty()) {
-            printf("Applying required filter: %s\n",
-                    bundle->getConfigurations());
-        }
-        if (!prefFilter.isEmpty()) {
-            printf("Applying preferred filter: %s\n",
-                    bundle->getPreferredConfigurations());
-        }
-    }
-
-    const Vector<sp<AaptDir> >& resdirs = mResDirs;
-    const size_t ND = resdirs.size();
-    for (size_t i=0; i<ND; i++) {
-        const sp<AaptDir>& dir = resdirs.itemAt(i);
-        if (dir->getLeaf() == kValuesDir) {
-            // The "value" dir is special since a single file defines
-            // multiple resources, so we can not do filtering on the
-            // files themselves.
-            continue;
-        }
-        if (dir->getLeaf() == kMipmapDir) {
-            // We also skip the "mipmap" directory, since the point of this
-            // is to include all densities without stripping.  If you put
-            // other configurations in here as well they won't be stripped
-            // either...  So don't do that.  Seriously.  What is wrong with you?
-            continue;
-        }
-
-        const size_t NG = dir->getFiles().size();
-        for (size_t j=0; j<NG; j++) {
-            sp<AaptGroup> grp = dir->getFiles().valueAt(j);
-
-            // First remove any configurations we know we don't need.
-            for (size_t k=0; k<grp->getFiles().size(); k++) {
-                sp<AaptFile> file = grp->getFiles().valueAt(k);
-                if (k == 0 && grp->getFiles().size() == 1) {
-                    // If this is the only file left, we need to keep it.
-                    // Otherwise the resource IDs we are using will be inconsistent
-                    // with what we get when not stripping.  Sucky, but at least
-                    // for now we can rely on the back-end doing another filtering
-                    // pass to take this out and leave us with this resource name
-                    // containing no entries.
-                    continue;
-                }
-                if (file->getPath().getPathExtension() == ".xml") {
-                    // We can't remove .xml files at this point, because when
-                    // we parse them they may add identifier resources, so
-                    // removing them can cause our resource identifiers to
-                    // become inconsistent.
-                    continue;
-                }
-                const ResTable_config& config(file->getGroupEntry().toParams());
-                if (!reqFilter.match(config)) {
-                    if (bundle->getVerbose()) {
-                        printf("Pruning unneeded resource: %s\n",
-                                file->getPrintableSource().string());
-                    }
-                    grp->removeFile(k);
-                    k--;
-                }
-            }
-
-            // Quick check: no preferred filters, nothing more to do.
-            if (prefFilter.isEmpty()) {
-                continue;
-            }
-
-            // Get the preferred density if there is one. We do not match exactly for density.
-            // If our preferred density is hdpi but we only have mdpi and xhdpi resources, we
-            // pick xhdpi.
-            uint32_t preferredDensity = 0;
-            const SortedVector<uint32_t>* preferredConfigs = prefFilter.configsForAxis(AXIS_DENSITY);
-            if (preferredConfigs != NULL && preferredConfigs->size() > 0) {
-                preferredDensity = (*preferredConfigs)[0];
-            }
-
-            // Now deal with preferred configurations.
-            for (int axis=AXIS_START; axis<=AXIS_END; axis++) {
-                for (size_t k=0; k<grp->getFiles().size(); k++) {
-                    sp<AaptFile> file = grp->getFiles().valueAt(k);
-                    if (k == 0 && grp->getFiles().size() == 1) {
-                        // If this is the only file left, we need to keep it.
-                        // Otherwise the resource IDs we are using will be inconsistent
-                        // with what we get when not stripping.  Sucky, but at least
-                        // for now we can rely on the back-end doing another filtering
-                        // pass to take this out and leave us with this resource name
-                        // containing no entries.
-                        continue;
-                    }
-                    if (file->getPath().getPathExtension() == ".xml") {
-                        // We can't remove .xml files at this point, because when
-                        // we parse them they may add identifier resources, so
-                        // removing them can cause our resource identifiers to
-                        // become inconsistent.
-                        continue;
-                    }
-                    const ResTable_config& config(file->getGroupEntry().toParams());
-                    if (!prefFilter.match(axis, config)) {
-                        // This is a resource we would prefer not to have.  Check
-                        // to see if have a similar variation that we would like
-                        // to have and, if so, we can drop it.
-
-                        uint32_t bestDensity = config.density;
-
-                        for (size_t m=0; m<grp->getFiles().size(); m++) {
-                            if (m == k) continue;
-                            sp<AaptFile> mfile = grp->getFiles().valueAt(m);
-                            const ResTable_config& mconfig(mfile->getGroupEntry().toParams());
-                            if (AaptGroupEntry::configSameExcept(config, mconfig, axis)) {
-                                if (axis == AXIS_DENSITY && preferredDensity > 0) {
-                                    // See if there is a better density resource
-                                    if (mconfig.density < bestDensity &&
-                                            mconfig.density > preferredDensity &&
-                                            bestDensity > preferredDensity) {
-                                        // This density is between our best density and
-                                        // the preferred density, therefore it is better.
-                                        bestDensity = mconfig.density;
-                                    } else if (mconfig.density > bestDensity &&
-                                            bestDensity < preferredDensity) {
-                                        // This density is better than our best density and
-                                        // our best density was smaller than our preferred
-                                        // density, so it is better.
-                                        bestDensity = mconfig.density;
-                                    }
-                                } else if (prefFilter.match(axis, mconfig)) {
-                                    if (bundle->getVerbose()) {
-                                        printf("Pruning unneeded resource: %s\n",
-                                                file->getPrintableSource().string());
-                                    }
-                                    grp->removeFile(k);
-                                    k--;
-                                    break;
-                                }
-                            }
-                        }
-
-                        if (axis == AXIS_DENSITY && preferredDensity > 0 &&
-                                bestDensity != config.density) {
-                            if (bundle->getVerbose()) {
-                                printf("Pruning unneeded resource: %s\n",
-                                        file->getPrintableSource().string());
-                            }
-                            grp->removeFile(k);
-                            k--;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    return NO_ERROR;
-}
-
-sp<AaptSymbols> AaptAssets::getSymbolsFor(const String8& name)
-{
-    sp<AaptSymbols> sym = mSymbols.valueFor(name);
-    if (sym == NULL) {
-        sym = new AaptSymbols();
-        mSymbols.add(name, sym);
-    }
-    return sym;
-}
-
-sp<AaptSymbols> AaptAssets::getJavaSymbolsFor(const String8& name)
-{
-    sp<AaptSymbols> sym = mJavaSymbols.valueFor(name);
-    if (sym == NULL) {
-        sym = new AaptSymbols();
-        mJavaSymbols.add(name, sym);
-    }
-    return sym;
-}
-
-status_t AaptAssets::applyJavaSymbols()
-{
-    size_t N = mJavaSymbols.size();
-    for (size_t i=0; i<N; i++) {
-        const String8& name = mJavaSymbols.keyAt(i);
-        const sp<AaptSymbols>& symbols = mJavaSymbols.valueAt(i);
-        ssize_t pos = mSymbols.indexOfKey(name);
-        if (pos < 0) {
-            SourcePos pos;
-            pos.error("Java symbol dir %s not defined\n", name.string());
-            return UNKNOWN_ERROR;
-        }
-        //printf("**** applying java symbols in dir %s\n", name.string());
-        status_t err = mSymbols.valueAt(pos)->applyJavaSymbols(symbols);
-        if (err != NO_ERROR) {
-            return err;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-bool AaptAssets::isJavaSymbol(const AaptSymbolEntry& sym, bool includePrivate) const {
-    //printf("isJavaSymbol %s: public=%d, includePrivate=%d, isJavaSymbol=%d\n",
-    //        sym.name.string(), sym.isPublic ? 1 : 0, includePrivate ? 1 : 0,
-    //        sym.isJavaSymbol ? 1 : 0);
-    if (!mHavePrivateSymbols) return true;
-    if (sym.isPublic) return true;
-    if (includePrivate && sym.isJavaSymbol) return true;
-    return false;
-}
-
-status_t AaptAssets::buildIncludedResources(Bundle* bundle)
-{
-    if (!mHaveIncludedAssets) {
-        // Add in all includes.
-        const Vector<const char*>& incl = bundle->getPackageIncludes();
-        const size_t N=incl.size();
-        for (size_t i=0; i<N; i++) {
-            if (bundle->getVerbose())
-                printf("Including resources from package: %s\n", incl[i]);
-            if (!mIncludedAssets.addAssetPath(String8(incl[i]), NULL)) {
-                fprintf(stderr, "ERROR: Asset package include '%s' not found.\n",
-                        incl[i]);
-                return UNKNOWN_ERROR;
-            }
-        }
-        mHaveIncludedAssets = true;
-    }
-
-    return NO_ERROR;
-}
-
-status_t AaptAssets::addIncludedResources(const sp<AaptFile>& file)
-{
-    const ResTable& res = getIncludedResources();
-    // XXX dirty!
-    return const_cast<ResTable&>(res).add(file->getData(), file->getSize(), NULL);
-}
-
-const ResTable& AaptAssets::getIncludedResources() const
-{
-    return mIncludedAssets.getResources(false);
-}
-
-void AaptAssets::print(const String8& prefix) const
-{
-    String8 innerPrefix(prefix);
-    innerPrefix.append("  ");
-    String8 innerInnerPrefix(innerPrefix);
-    innerInnerPrefix.append("  ");
-    printf("%sConfigurations:\n", prefix.string());
-    const size_t N=mGroupEntries.size();
-    for (size_t i=0; i<N; i++) {
-        String8 cname = mGroupEntries.itemAt(i).toDirName(String8());
-        printf("%s %s\n", prefix.string(),
-                cname != "" ? cname.string() : "(default)");
-    }
-
-    printf("\n%sFiles:\n", prefix.string());
-    AaptDir::print(innerPrefix);
-
-    printf("\n%sResource Dirs:\n", prefix.string());
-    const Vector<sp<AaptDir> >& resdirs = mResDirs;
-    const size_t NR = resdirs.size();
-    for (size_t i=0; i<NR; i++) {
-        const sp<AaptDir>& d = resdirs.itemAt(i);
-        printf("%s  Type %s\n", prefix.string(), d->getLeaf().string());
-        d->print(innerInnerPrefix);
-    }
-}
-
-sp<AaptDir> AaptAssets::resDir(const String8& name) const
-{
-    const Vector<sp<AaptDir> >& resdirs = mResDirs;
-    const size_t N = resdirs.size();
-    for (size_t i=0; i<N; i++) {
-        const sp<AaptDir>& d = resdirs.itemAt(i);
-        if (d->getLeaf() == name) {
-            return d;
-        }
-    }
-    return NULL;
-}
-
-bool
-valid_symbol_name(const String8& symbol)
-{
-    static char const * const KEYWORDS[] = {
-        "abstract", "assert", "boolean", "break",
-        "byte", "case", "catch", "char", "class", "const", "continue",
-        "default", "do", "double", "else", "enum", "extends", "final",
-        "finally", "float", "for", "goto", "if", "implements", "import",
-        "instanceof", "int", "interface", "long", "native", "new", "package",
-        "private", "protected", "public", "return", "short", "static",
-        "strictfp", "super", "switch", "synchronized", "this", "throw",
-        "throws", "transient", "try", "void", "volatile", "while",
-        "true", "false", "null",
-        NULL
-    };
-    const char*const* k = KEYWORDS;
-    const char*const s = symbol.string();
-    while (*k) {
-        if (0 == strcmp(s, *k)) {
-            return false;
-        }
-        k++;
-    }
-    return true;
-}
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
deleted file mode 100644
index 5cfa913..0000000
--- a/tools/aapt/AaptAssets.h
+++ /dev/null
@@ -1,633 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Information about assets being operated on.
-//
-#ifndef __AAPT_ASSETS_H
-#define __AAPT_ASSETS_H
-
-#include <stdlib.h>
-#include <androidfw/AssetManager.h>
-#include <androidfw/ResourceTypes.h>
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-#include <utils/SortedVector.h>
-#include <utils/String8.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
-#include "ZipFile.h"
-
-#include "Bundle.h"
-#include "SourcePos.h"
-
-using namespace android;
-
-
-extern const char * const gDefaultIgnoreAssets;
-extern const char * gUserIgnoreAssets;
-
-bool valid_symbol_name(const String8& str);
-
-class AaptAssets;
-
-enum {
-    AXIS_NONE = 0,
-    AXIS_MCC = 1,
-    AXIS_MNC,
-    AXIS_LANGUAGE,
-    AXIS_REGION,
-    AXIS_SCREENLAYOUTSIZE,
-    AXIS_SCREENLAYOUTLONG,
-    AXIS_ORIENTATION,
-    AXIS_UIMODETYPE,
-    AXIS_UIMODENIGHT,
-    AXIS_DENSITY,
-    AXIS_TOUCHSCREEN,
-    AXIS_KEYSHIDDEN,
-    AXIS_KEYBOARD,
-    AXIS_NAVHIDDEN,
-    AXIS_NAVIGATION,
-    AXIS_SCREENSIZE,
-    AXIS_SMALLESTSCREENWIDTHDP,
-    AXIS_SCREENWIDTHDP,
-    AXIS_SCREENHEIGHTDP,
-    AXIS_LAYOUTDIR,
-    AXIS_VERSION,
-
-    AXIS_START = AXIS_MCC,
-    AXIS_END = AXIS_VERSION,
-};
-
-/**
- * This structure contains a specific variation of a single file out
- * of all the variations it can have that we can have.
- */
-struct AaptGroupEntry
-{
-public:
-    AaptGroupEntry() : mParamsChanged(true) { }
-    AaptGroupEntry(const String8& _locale, const String8& _vendor)
-        : locale(_locale), vendor(_vendor), mParamsChanged(true) { }
-
-    bool initFromDirName(const char* dir, String8* resType);
-
-    static status_t parseNamePart(const String8& part, int* axis, uint32_t* value);
-
-    static uint32_t getConfigValueForAxis(const ResTable_config& config, int axis);
-
-    static bool configSameExcept(const ResTable_config& config,
-            const ResTable_config& otherConfig, int axis);
-
-    static bool getMccName(const char* name, ResTable_config* out = NULL);
-    static bool getMncName(const char* name, ResTable_config* out = NULL);
-    static bool getLocaleName(const char* name, ResTable_config* out = NULL);
-    static bool getScreenLayoutSizeName(const char* name, ResTable_config* out = NULL);
-    static bool getScreenLayoutLongName(const char* name, ResTable_config* out = NULL);
-    static bool getOrientationName(const char* name, ResTable_config* out = NULL);
-    static bool getUiModeTypeName(const char* name, ResTable_config* out = NULL);
-    static bool getUiModeNightName(const char* name, ResTable_config* out = NULL);
-    static bool getDensityName(const char* name, ResTable_config* out = NULL);
-    static bool getTouchscreenName(const char* name, ResTable_config* out = NULL);
-    static bool getKeysHiddenName(const char* name, ResTable_config* out = NULL);
-    static bool getKeyboardName(const char* name, ResTable_config* out = NULL);
-    static bool getNavigationName(const char* name, ResTable_config* out = NULL);
-    static bool getNavHiddenName(const char* name, ResTable_config* out = NULL);
-    static bool getScreenSizeName(const char* name, ResTable_config* out = NULL);
-    static bool getSmallestScreenWidthDpName(const char* name, ResTable_config* out = NULL);
-    static bool getScreenWidthDpName(const char* name, ResTable_config* out = NULL);
-    static bool getScreenHeightDpName(const char* name, ResTable_config* out = NULL);
-    static bool getLayoutDirectionName(const char* name, ResTable_config* out = NULL);
-    static bool getVersionName(const char* name, ResTable_config* out = NULL);
-
-    int compare(const AaptGroupEntry& o) const;
-
-    const ResTable_config& toParams() const;
-
-    inline bool operator<(const AaptGroupEntry& o) const { return compare(o) < 0; }
-    inline bool operator<=(const AaptGroupEntry& o) const { return compare(o) <= 0; }
-    inline bool operator==(const AaptGroupEntry& o) const { return compare(o) == 0; }
-    inline bool operator!=(const AaptGroupEntry& o) const { return compare(o) != 0; }
-    inline bool operator>=(const AaptGroupEntry& o) const { return compare(o) >= 0; }
-    inline bool operator>(const AaptGroupEntry& o) const { return compare(o) > 0; }
-
-    String8 toString() const;
-    String8 toDirName(const String8& resType) const;
-
-    const String8& getVersionString() const { return version; }
-
-private:
-    String8 mcc;
-    String8 mnc;
-    String8 locale;
-    String8 vendor;
-    String8 smallestScreenWidthDp;
-    String8 screenWidthDp;
-    String8 screenHeightDp;
-    String8 screenLayoutSize;
-    String8 screenLayoutLong;
-    String8 orientation;
-    String8 uiModeType;
-    String8 uiModeNight;
-    String8 density;
-    String8 touchscreen;
-    String8 keysHidden;
-    String8 keyboard;
-    String8 navHidden;
-    String8 navigation;
-    String8 screenSize;
-    String8 layoutDirection;
-    String8 version;
-
-    mutable bool mParamsChanged;
-    mutable ResTable_config mParams;
-};
-
-inline int compare_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs)
-{
-    return lhs.compare(rhs);
-}
-
-inline int strictly_order_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs)
-{
-    return compare_type(lhs, rhs) < 0;
-}
-
-class AaptGroup;
-class FilePathStore;
-
-/**
- * A single asset file we know about.
- */
-class AaptFile : public RefBase
-{
-public:
-    AaptFile(const String8& sourceFile, const AaptGroupEntry& groupEntry,
-             const String8& resType)
-        : mGroupEntry(groupEntry)
-        , mResourceType(resType)
-        , mSourceFile(sourceFile)
-        , mData(NULL)
-        , mDataSize(0)
-        , mBufferSize(0)
-        , mCompression(ZipEntry::kCompressStored)
-        {
-            //printf("new AaptFile created %s\n", (const char*)sourceFile);
-        }
-    virtual ~AaptFile() {
-        free(mData);
-    }
-
-    const String8& getPath() const { return mPath; }
-    const AaptGroupEntry& getGroupEntry() const { return mGroupEntry; }
-
-    // Data API.  If there is data attached to the file,
-    // getSourceFile() is not used.
-    bool hasData() const { return mData != NULL; }
-    const void* getData() const { return mData; }
-    size_t getSize() const { return mDataSize; }
-    void* editData(size_t size);
-    void* editData(size_t* outSize = NULL);
-    void* padData(size_t wordSize);
-    status_t writeData(const void* data, size_t size);
-    void clearData();
-
-    const String8& getResourceType() const { return mResourceType; }
-
-    // File API.  If the file does not hold raw data, this is
-    // a full path to a file on the filesystem that holds its data.
-    const String8& getSourceFile() const { return mSourceFile; }
-
-    String8 getPrintableSource() const;
-
-    // Desired compression method, as per utils/ZipEntry.h.  For example,
-    // no compression is ZipEntry::kCompressStored.
-    int getCompressionMethod() const { return mCompression; }
-    void setCompressionMethod(int c) { mCompression = c; }
-private:
-    friend class AaptGroup;
-
-    String8 mPath;
-    AaptGroupEntry mGroupEntry;
-    String8 mResourceType;
-    String8 mSourceFile;
-    void* mData;
-    size_t mDataSize;
-    size_t mBufferSize;
-    int mCompression;
-};
-
-/**
- * A group of related files (the same file, with different
- * vendor/locale variations).
- */
-class AaptGroup : public RefBase
-{
-public:
-    AaptGroup(const String8& leaf, const String8& path)
-        : mLeaf(leaf), mPath(path) { }
-    virtual ~AaptGroup() { }
-
-    const String8& getLeaf() const { return mLeaf; }
-
-    // Returns the relative path after the AaptGroupEntry dirs.
-    const String8& getPath() const { return mPath; }
-
-    const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& getFiles() const
-        { return mFiles; }
-
-    status_t addFile(const sp<AaptFile>& file);
-    void removeFile(size_t index);
-
-    void print(const String8& prefix) const;
-
-    String8 getPrintableSource() const;
-
-private:
-    String8 mLeaf;
-    String8 mPath;
-
-    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > mFiles;
-};
-
-/**
- * A single directory of assets, which can contain files and other
- * sub-directories.
- */
-class AaptDir : public RefBase
-{
-public:
-    AaptDir(const String8& leaf, const String8& path)
-        : mLeaf(leaf), mPath(path) { }
-    virtual ~AaptDir() { }
-
-    const String8& getLeaf() const { return mLeaf; }
-
-    const String8& getPath() const { return mPath; }
-
-    const DefaultKeyedVector<String8, sp<AaptGroup> >& getFiles() const { return mFiles; }
-    const DefaultKeyedVector<String8, sp<AaptDir> >& getDirs() const { return mDirs; }
-
-    virtual status_t addFile(const String8& name, const sp<AaptGroup>& file);
-
-    void removeFile(const String8& name);
-    void removeDir(const String8& name);
-
-    /*
-     * Perform some sanity checks on the names of files and directories here.
-     * In particular:
-     *  - Check for illegal chars in filenames.
-     *  - Check filename length.
-     *  - Check for presence of ".gz" and non-".gz" copies of same file.
-     *  - Check for multiple files whose names match in a case-insensitive
-     *    fashion (problematic for some systems).
-     *
-     * Comparing names against all other names is O(n^2).  We could speed
-     * it up some by sorting the entries and being smarter about what we
-     * compare against, but I'm not expecting to have enough files in a
-     * single directory to make a noticeable difference in speed.
-     *
-     * Note that sorting here is not enough to guarantee that the package
-     * contents are sorted -- subsequent updates can rearrange things.
-     */
-    status_t validate() const;
-
-    void print(const String8& prefix) const;
-
-    String8 getPrintableSource() const;
-
-private:
-    friend class AaptAssets;
-
-    status_t addDir(const String8& name, const sp<AaptDir>& dir);
-    sp<AaptDir> makeDir(const String8& name);
-    status_t addLeafFile(const String8& leafName,
-                         const sp<AaptFile>& file);
-    virtual ssize_t slurpFullTree(Bundle* bundle,
-                                  const String8& srcDir,
-                                  const AaptGroupEntry& kind,
-                                  const String8& resType,
-                                  sp<FilePathStore>& fullResPaths);
-
-    String8 mLeaf;
-    String8 mPath;
-
-    DefaultKeyedVector<String8, sp<AaptGroup> > mFiles;
-    DefaultKeyedVector<String8, sp<AaptDir> > mDirs;
-};
-
-/**
- * All information we know about a particular symbol.
- */
-class AaptSymbolEntry
-{
-public:
-    AaptSymbolEntry()
-        : isPublic(false), isJavaSymbol(false), typeCode(TYPE_UNKNOWN)
-    {
-    }
-    AaptSymbolEntry(const String8& _name)
-        : name(_name), isPublic(false), isJavaSymbol(false), typeCode(TYPE_UNKNOWN)
-    {
-    }
-    AaptSymbolEntry(const AaptSymbolEntry& o)
-        : name(o.name), sourcePos(o.sourcePos), isPublic(o.isPublic)
-        , isJavaSymbol(o.isJavaSymbol), comment(o.comment), typeComment(o.typeComment)
-        , typeCode(o.typeCode), int32Val(o.int32Val), stringVal(o.stringVal)
-    {
-    }
-    AaptSymbolEntry operator=(const AaptSymbolEntry& o)
-    {
-        sourcePos = o.sourcePos;
-        isPublic = o.isPublic;
-        isJavaSymbol = o.isJavaSymbol;
-        comment = o.comment;
-        typeComment = o.typeComment;
-        typeCode = o.typeCode;
-        int32Val = o.int32Val;
-        stringVal = o.stringVal;
-        return *this;
-    }
-    
-    const String8 name;
-    
-    SourcePos sourcePos;
-    bool isPublic;
-    bool isJavaSymbol;
-    
-    String16 comment;
-    String16 typeComment;
-    
-    enum {
-        TYPE_UNKNOWN = 0,
-        TYPE_INT32,
-        TYPE_STRING
-    };
-    
-    int typeCode;
-    
-    // Value.  May be one of these.
-    int32_t int32Val;
-    String8 stringVal;
-};
-
-/**
- * A group of related symbols (such as indices into a string block)
- * that have been generated from the assets.
- */
-class AaptSymbols : public RefBase
-{
-public:
-    AaptSymbols() { }
-    virtual ~AaptSymbols() { }
-
-    status_t addSymbol(const String8& name, int32_t value, const SourcePos& pos) {
-        if (!check_valid_symbol_name(name, pos, "symbol")) {
-            return BAD_VALUE;
-        }
-        AaptSymbolEntry& sym = edit_symbol(name, &pos);
-        sym.typeCode = AaptSymbolEntry::TYPE_INT32;
-        sym.int32Val = value;
-        return NO_ERROR;
-    }
-
-    status_t addStringSymbol(const String8& name, const String8& value,
-            const SourcePos& pos) {
-        if (!check_valid_symbol_name(name, pos, "symbol")) {
-            return BAD_VALUE;
-        }
-        AaptSymbolEntry& sym = edit_symbol(name, &pos);
-        sym.typeCode = AaptSymbolEntry::TYPE_STRING;
-        sym.stringVal = value;
-        return NO_ERROR;
-    }
-
-    status_t makeSymbolPublic(const String8& name, const SourcePos& pos) {
-        if (!check_valid_symbol_name(name, pos, "symbol")) {
-            return BAD_VALUE;
-        }
-        AaptSymbolEntry& sym = edit_symbol(name, &pos);
-        sym.isPublic = true;
-        return NO_ERROR;
-    }
-
-    status_t makeSymbolJavaSymbol(const String8& name, const SourcePos& pos) {
-        if (!check_valid_symbol_name(name, pos, "symbol")) {
-            return BAD_VALUE;
-        }
-        AaptSymbolEntry& sym = edit_symbol(name, &pos);
-        sym.isJavaSymbol = true;
-        return NO_ERROR;
-    }
-
-    void appendComment(const String8& name, const String16& comment, const SourcePos& pos) {
-        if (comment.size() <= 0) {
-            return;
-        }
-        AaptSymbolEntry& sym = edit_symbol(name, &pos);
-        if (sym.comment.size() == 0) {
-            sym.comment = comment;
-        } else {
-            sym.comment.append(String16("\n"));
-            sym.comment.append(comment);
-        }
-    }
-
-    void appendTypeComment(const String8& name, const String16& comment) {
-        if (comment.size() <= 0) {
-            return;
-        }
-        AaptSymbolEntry& sym = edit_symbol(name, NULL);
-        if (sym.typeComment.size() == 0) {
-            sym.typeComment = comment;
-        } else {
-            sym.typeComment.append(String16("\n"));
-            sym.typeComment.append(comment);
-        }
-    }
-    
-    sp<AaptSymbols> addNestedSymbol(const String8& name, const SourcePos& pos) {
-        if (!check_valid_symbol_name(name, pos, "nested symbol")) {
-            return NULL;
-        }
-        
-        sp<AaptSymbols> sym = mNestedSymbols.valueFor(name);
-        if (sym == NULL) {
-            sym = new AaptSymbols();
-            mNestedSymbols.add(name, sym);
-        }
-
-        return sym;
-    }
-
-    status_t applyJavaSymbols(const sp<AaptSymbols>& javaSymbols);
-
-    const KeyedVector<String8, AaptSymbolEntry>& getSymbols() const
-        { return mSymbols; }
-    const DefaultKeyedVector<String8, sp<AaptSymbols> >& getNestedSymbols() const
-        { return mNestedSymbols; }
-
-    const String16& getComment(const String8& name) const
-        { return get_symbol(name).comment; }
-    const String16& getTypeComment(const String8& name) const
-        { return get_symbol(name).typeComment; }
-
-private:
-    bool check_valid_symbol_name(const String8& symbol, const SourcePos& pos, const char* label) {
-        if (valid_symbol_name(symbol)) {
-            return true;
-        }
-        pos.error("invalid %s: '%s'\n", label, symbol.string());
-        return false;
-    }
-    AaptSymbolEntry& edit_symbol(const String8& symbol, const SourcePos* pos) {
-        ssize_t i = mSymbols.indexOfKey(symbol);
-        if (i < 0) {
-            i = mSymbols.add(symbol, AaptSymbolEntry(symbol));
-        }
-        AaptSymbolEntry& sym = mSymbols.editValueAt(i);
-        if (pos != NULL && sym.sourcePos.line < 0) {
-            sym.sourcePos = *pos;
-        }
-        return sym;
-    }
-    const AaptSymbolEntry& get_symbol(const String8& symbol) const {
-        ssize_t i = mSymbols.indexOfKey(symbol);
-        if (i >= 0) {
-            return mSymbols.valueAt(i);
-        }
-        return mDefSymbol;
-    }
-
-    KeyedVector<String8, AaptSymbolEntry>           mSymbols;
-    DefaultKeyedVector<String8, sp<AaptSymbols> >   mNestedSymbols;
-    AaptSymbolEntry                                 mDefSymbol;
-};
-
-class ResourceTypeSet : public RefBase,
-                        public KeyedVector<String8,sp<AaptGroup> >
-{
-public:
-    ResourceTypeSet();
-};
-
-// Storage for lists of fully qualified paths for
-// resources encountered during slurping.
-class FilePathStore : public RefBase,
-                      public Vector<String8>
-{
-public:
-    FilePathStore();
-};
-
-/**
- * Asset hierarchy being operated on.
- */
-class AaptAssets : public AaptDir
-{
-public:
-    AaptAssets();
-    virtual ~AaptAssets() { delete mRes; }
-
-    const String8& getPackage() const { return mPackage; }
-    void setPackage(const String8& package) {
-        mPackage = package;
-        mSymbolsPrivatePackage = package;
-        mHavePrivateSymbols = false;
-    }
-
-    const SortedVector<AaptGroupEntry>& getGroupEntries() const;
-
-    virtual status_t addFile(const String8& name, const sp<AaptGroup>& file);
-
-    sp<AaptFile> addFile(const String8& filePath,
-                         const AaptGroupEntry& entry,
-                         const String8& srcDir,
-                         sp<AaptGroup>* outGroup,
-                         const String8& resType);
-
-    void addResource(const String8& leafName,
-                     const String8& path,
-                     const sp<AaptFile>& file,
-                     const String8& resType);
-
-    void addGroupEntry(const AaptGroupEntry& entry) { mGroupEntries.add(entry); }
-    
-    ssize_t slurpFromArgs(Bundle* bundle);
-
-    sp<AaptSymbols> getSymbolsFor(const String8& name);
-
-    sp<AaptSymbols> getJavaSymbolsFor(const String8& name);
-
-    status_t applyJavaSymbols();
-
-    const DefaultKeyedVector<String8, sp<AaptSymbols> >& getSymbols() const { return mSymbols; }
-
-    String8 getSymbolsPrivatePackage() const { return mSymbolsPrivatePackage; }
-    void setSymbolsPrivatePackage(const String8& pkg) {
-        mSymbolsPrivatePackage = pkg;
-        mHavePrivateSymbols = mSymbolsPrivatePackage != mPackage;
-    }
-
-    bool havePrivateSymbols() const { return mHavePrivateSymbols; }
-
-    bool isJavaSymbol(const AaptSymbolEntry& sym, bool includePrivate) const;
-
-    status_t buildIncludedResources(Bundle* bundle);
-    status_t addIncludedResources(const sp<AaptFile>& file);
-    const ResTable& getIncludedResources() const;
-
-    void print(const String8& prefix) const;
-
-    inline const Vector<sp<AaptDir> >& resDirs() const { return mResDirs; }
-    sp<AaptDir> resDir(const String8& name) const;
-
-    inline sp<AaptAssets> getOverlay() { return mOverlay; }
-    inline void setOverlay(sp<AaptAssets>& overlay) { mOverlay = overlay; }
-    
-    inline KeyedVector<String8, sp<ResourceTypeSet> >* getResources() { return mRes; }
-    inline void 
-        setResources(KeyedVector<String8, sp<ResourceTypeSet> >* res) { delete mRes; mRes = res; }
-
-    inline sp<FilePathStore>& getFullResPaths() { return mFullResPaths; }
-    inline void
-        setFullResPaths(sp<FilePathStore>& res) { mFullResPaths = res; }
-
-    inline sp<FilePathStore>& getFullAssetPaths() { return mFullAssetPaths; }
-    inline void
-        setFullAssetPaths(sp<FilePathStore>& res) { mFullAssetPaths = res; }
-
-private:
-    virtual ssize_t slurpFullTree(Bundle* bundle,
-                                  const String8& srcDir,
-                                  const AaptGroupEntry& kind,
-                                  const String8& resType,
-                                  sp<FilePathStore>& fullResPaths);
-
-    ssize_t slurpResourceTree(Bundle* bundle, const String8& srcDir);
-    ssize_t slurpResourceZip(Bundle* bundle, const char* filename);
-
-    status_t filter(Bundle* bundle);
-
-    String8 mPackage;
-    SortedVector<AaptGroupEntry> mGroupEntries;
-    DefaultKeyedVector<String8, sp<AaptSymbols> > mSymbols;
-    DefaultKeyedVector<String8, sp<AaptSymbols> > mJavaSymbols;
-    String8 mSymbolsPrivatePackage;
-    bool mHavePrivateSymbols;
-
-    Vector<sp<AaptDir> > mResDirs;
-
-    bool mChanged;
-
-    bool mHaveIncludedAssets;
-    AssetManager mIncludedAssets;
-
-    sp<AaptAssets> mOverlay;
-    KeyedVector<String8, sp<ResourceTypeSet> >* mRes;
-
-    sp<FilePathStore> mFullResPaths;
-    sp<FilePathStore> mFullAssetPaths;
-};
-
-#endif // __AAPT_ASSETS_H
-
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
deleted file mode 100644
index 452c60a..0000000
--- a/tools/aapt/Android.mk
+++ /dev/null
@@ -1,103 +0,0 @@
-# 
-# Copyright 2006 The Android Open Source Project
-#
-# Android Asset Packaging Tool
-#
-
-# This tool is prebuilt if we're doing an app-only build.
-ifeq ($(TARGET_BUILD_APPS),)
-
-
-aapt_src_files := \
-	AaptAssets.cpp \
-	Command.cpp \
-	CrunchCache.cpp \
-	FileFinder.cpp \
-	Main.cpp \
-	Package.cpp \
-	StringPool.cpp \
-	XMLNode.cpp \
-	ResourceFilter.cpp \
-	ResourceIdCache.cpp \
-	ResourceTable.cpp \
-	Images.cpp \
-	Resource.cpp \
-    pseudolocalize.cpp \
-    SourcePos.cpp \
-	WorkQueue.cpp \
-    ZipEntry.cpp \
-    ZipFile.cpp \
-	qsort_r_compat.c
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(aapt_src_files)
-
-LOCAL_CFLAGS += -Wno-format-y2k
-ifeq (darwin,$(HOST_OS))
-LOCAL_CFLAGS += -D_DARWIN_UNLIMITED_STREAMS
-endif
-
-LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
-
-LOCAL_C_INCLUDES += external/libpng
-LOCAL_C_INCLUDES += external/zlib
-
-LOCAL_STATIC_LIBRARIES := \
-	libandroidfw \
-	libutils \
-	libcutils \
-	libexpat \
-	libpng \
-	liblog
-
-ifeq ($(HOST_OS),linux)
-LOCAL_LDLIBS += -lrt -ldl -lpthread
-endif
-
-# Statically link libz for MinGW (Win SDK under Linux),
-# and dynamically link for all others.
-ifneq ($(strip $(USE_MINGW)),)
-  LOCAL_STATIC_LIBRARIES += libz
-else
-  LOCAL_LDLIBS += -lz
-endif
-
-LOCAL_MODULE := aapt
-
-include $(BUILD_HOST_EXECUTABLE)
-
-# aapt for running on the device
-# =========================================================
-ifneq ($(SDK_ONLY),true)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(aapt_src_files)
-
-LOCAL_MODULE := aapt
-
-LOCAL_C_INCLUDES += bionic
-LOCAL_C_INCLUDES += bionic/libstdc++/include
-LOCAL_C_INCLUDES += external/stlport/stlport
-LOCAL_C_INCLUDES += external/libpng
-LOCAL_C_INCLUDES += external/zlib
-
-LOCAL_CFLAGS += -Wno-non-virtual-dtor
-
-LOCAL_SHARED_LIBRARIES := \
-        libandroidfw \
-        libutils \
-        libcutils \
-        libpng \
-        liblog \
-        libz
-
-LOCAL_STATIC_LIBRARIES := \
-        libstlport_static \
-        libexpat_static
-
-include $(BUILD_EXECUTABLE)
-endif
-
-endif # TARGET_BUILD_APPS
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
deleted file mode 100644
index 5089b9d..0000000
--- a/tools/aapt/Bundle.h
+++ /dev/null
@@ -1,306 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// State bundle.  Used to pass around stuff like command-line args.
-//
-#ifndef __BUNDLE_H
-#define __BUNDLE_H
-
-#include <stdlib.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <utils/List.h>
-#include <utils/Errors.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
-
-enum {
-    SDK_CUPCAKE = 3,
-    SDK_DONUT = 4,
-    SDK_ECLAIR = 5,
-    SDK_ECLAIR_0_1 = 6,
-    SDK_MR1 = 7,
-    SDK_FROYO = 8,
-    SDK_HONEYCOMB_MR2 = 13,
-    SDK_ICE_CREAM_SANDWICH = 14,
-    SDK_ICE_CREAM_SANDWICH_MR1 = 15,
-};
-
-/*
- * Things we can do.
- */
-typedef enum Command {
-    kCommandUnknown = 0,
-    kCommandVersion,
-    kCommandList,
-    kCommandDump,
-    kCommandAdd,
-    kCommandRemove,
-    kCommandPackage,
-    kCommandCrunch,
-    kCommandSingleCrunch,
-} Command;
-
-/*
- * Bundle of goodies, including everything specified on the command line.
- */
-class Bundle {
-public:
-    Bundle(void)
-        : mCmd(kCommandUnknown), mVerbose(false), mAndroidList(false),
-          mForce(false), mGrayscaleTolerance(0), mMakePackageDirs(false),
-          mUpdate(false), mExtending(false),
-          mRequireLocalization(false), mPseudolocalize(false),
-          mWantUTF16(false), mValues(false),
-          mCompressionMethod(0), mJunkPath(false), mOutputAPKFile(NULL),
-          mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
-          mAutoAddOverlay(false), mGenDependencies(false),
-          mAssetSourceDir(NULL), 
-          mCrunchedOutputDir(NULL), mProguardFile(NULL),
-          mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
-          mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
-          mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
-          mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL), mExtraPackages(NULL),
-          mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL),
-          mUseCrunchCache(false), mErrorOnFailedInsert(false), mOutputTextSymbols(NULL),
-          mSingleCrunchInputFile(NULL), mSingleCrunchOutputFile(NULL),
-          mArgc(0), mArgv(NULL)
-        {}
-    ~Bundle(void) {}
-
-    /*
-     * Set the command value.  Returns "false" if it was previously set.
-     */
-    Command getCommand(void) const { return mCmd; }
-    void setCommand(Command cmd) { mCmd = cmd; }
-
-    /*
-     * Command modifiers.  Not all modifiers are appropriate for all
-     * commands.
-     */
-    bool getVerbose(void) const { return mVerbose; }
-    void setVerbose(bool val) { mVerbose = val; }
-    bool getAndroidList(void) const { return mAndroidList; }
-    void setAndroidList(bool val) { mAndroidList = val; }
-    bool getForce(void) const { return mForce; }
-    void setForce(bool val) { mForce = val; }
-    void setGrayscaleTolerance(int val) { mGrayscaleTolerance = val; }
-    int  getGrayscaleTolerance() const { return mGrayscaleTolerance; }
-    bool getMakePackageDirs(void) const { return mMakePackageDirs; }
-    void setMakePackageDirs(bool val) { mMakePackageDirs = val; }
-    bool getUpdate(void) const { return mUpdate; }
-    void setUpdate(bool val) { mUpdate = val; }
-    bool getExtending(void) const { return mExtending; }
-    void setExtending(bool val) { mExtending = val; }
-    bool getRequireLocalization(void) const { return mRequireLocalization; }
-    void setRequireLocalization(bool val) { mRequireLocalization = val; }
-    bool getPseudolocalize(void) const { return mPseudolocalize; }
-    void setPseudolocalize(bool val) { mPseudolocalize = val; }
-    void setWantUTF16(bool val) { mWantUTF16 = val; }
-    bool getValues(void) const { return mValues; }
-    void setValues(bool val) { mValues = val; }
-    int getCompressionMethod(void) const { return mCompressionMethod; }
-    void setCompressionMethod(int val) { mCompressionMethod = val; }
-    bool getJunkPath(void) const { return mJunkPath; }
-    void setJunkPath(bool val) { mJunkPath = val; }
-    const char* getOutputAPKFile() const { return mOutputAPKFile; }
-    void setOutputAPKFile(const char* val) { mOutputAPKFile = val; }
-    const char* getManifestPackageNameOverride() const { return mManifestPackageNameOverride; }
-    void setManifestPackageNameOverride(const char * val) { mManifestPackageNameOverride = val; }
-    const char* getInstrumentationPackageNameOverride() const { return mInstrumentationPackageNameOverride; }
-    void setInstrumentationPackageNameOverride(const char * val) { mInstrumentationPackageNameOverride = val; }
-    bool getAutoAddOverlay() { return mAutoAddOverlay; }
-    void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; }
-    bool getGenDependencies() { return mGenDependencies; }
-    void setGenDependencies(bool val) { mGenDependencies = val; }
-    bool getErrorOnFailedInsert() { return mErrorOnFailedInsert; }
-    void setErrorOnFailedInsert(bool val) { mErrorOnFailedInsert = val; }
-
-    bool getUTF16StringsOption() {
-        return mWantUTF16 || !isMinSdkAtLeast(SDK_FROYO);
-    }
-
-    /*
-     * Input options.
-     */
-    const char* getAssetSourceDir() const { return mAssetSourceDir; }
-    void setAssetSourceDir(const char* dir) { mAssetSourceDir = dir; }
-    const char* getCrunchedOutputDir() const { return mCrunchedOutputDir; }
-    void setCrunchedOutputDir(const char* dir) { mCrunchedOutputDir = dir; }
-    const char* getProguardFile() const { return mProguardFile; }
-    void setProguardFile(const char* file) { mProguardFile = file; }
-    const android::Vector<const char*>& getResourceSourceDirs() const { return mResourceSourceDirs; }
-    void addResourceSourceDir(const char* dir) { mResourceSourceDirs.insertAt(dir,0); }
-    const char* getAndroidManifestFile() const { return mAndroidManifestFile; }
-    void setAndroidManifestFile(const char* file) { mAndroidManifestFile = file; }
-    const char* getPublicOutputFile() const { return mPublicOutputFile; }
-    void setPublicOutputFile(const char* file) { mPublicOutputFile = file; }
-    const char* getRClassDir() const { return mRClassDir; }
-    void setRClassDir(const char* dir) { mRClassDir = dir; }
-    const char* getConfigurations() const { return mConfigurations.size() > 0 ? mConfigurations.string() : NULL; }
-    void addConfigurations(const char* val) { if (mConfigurations.size() > 0) { mConfigurations.append(","); mConfigurations.append(val); } else { mConfigurations = val; } }
-    const char* getPreferredConfigurations() const { return mPreferredConfigurations.size() > 0 ? mPreferredConfigurations.string() : NULL; }
-    void addPreferredConfigurations(const char* val) { if (mPreferredConfigurations.size() > 0) { mPreferredConfigurations.append(","); mPreferredConfigurations.append(val); } else { mPreferredConfigurations = val; } }
-    const char* getResourceIntermediatesDir() const { return mResourceIntermediatesDir; }
-    void setResourceIntermediatesDir(const char* dir) { mResourceIntermediatesDir = dir; }
-    const android::Vector<const char*>& getPackageIncludes() const { return mPackageIncludes; }
-    void addPackageInclude(const char* file) { mPackageIncludes.add(file); }
-    const android::Vector<const char*>& getJarFiles() const { return mJarFiles; }
-    void addJarFile(const char* file) { mJarFiles.add(file); }
-    const android::Vector<const char*>& getNoCompressExtensions() const { return mNoCompressExtensions; }
-    void addNoCompressExtension(const char* ext) { mNoCompressExtensions.add(ext); }
-
-    const char*  getManifestMinSdkVersion() const { return mManifestMinSdkVersion; }
-    void setManifestMinSdkVersion(const char*  val) { mManifestMinSdkVersion = val; }
-    const char*  getMinSdkVersion() const { return mMinSdkVersion; }
-    void setMinSdkVersion(const char*  val) { mMinSdkVersion = val; }
-    const char*  getTargetSdkVersion() const { return mTargetSdkVersion; }
-    void setTargetSdkVersion(const char*  val) { mTargetSdkVersion = val; }
-    const char*  getMaxSdkVersion() const { return mMaxSdkVersion; }
-    void setMaxSdkVersion(const char*  val) { mMaxSdkVersion = val; }
-    const char*  getVersionCode() const { return mVersionCode; }
-    void setVersionCode(const char*  val) { mVersionCode = val; }
-    const char* getVersionName() const { return mVersionName; }
-    void setVersionName(const char* val) { mVersionName = val; }
-    const char* getCustomPackage() const { return mCustomPackage; }
-    void setCustomPackage(const char* val) { mCustomPackage = val; }
-    const char* getExtraPackages() const { return mExtraPackages; }
-    void setExtraPackages(const char* val) { mExtraPackages = val; }
-    const char* getMaxResVersion() const { return mMaxResVersion; }
-    void setMaxResVersion(const char * val) { mMaxResVersion = val; }
-    bool getDebugMode() const { return mDebugMode; }
-    void setDebugMode(bool val) { mDebugMode = val; }
-    bool getNonConstantId() const { return mNonConstantId; }
-    void setNonConstantId(bool val) { mNonConstantId = val; }
-    const char* getProduct() const { return mProduct; }
-    void setProduct(const char * val) { mProduct = val; }
-    void setUseCrunchCache(bool val) { mUseCrunchCache = val; }
-    bool getUseCrunchCache() const { return mUseCrunchCache; }
-    const char* getOutputTextSymbols() const { return mOutputTextSymbols; }
-    void setOutputTextSymbols(const char* val) { mOutputTextSymbols = val; }
-    const char* getSingleCrunchInputFile() const { return mSingleCrunchInputFile; }
-    void setSingleCrunchInputFile(const char* val) { mSingleCrunchInputFile = val; }
-    const char* getSingleCrunchOutputFile() const { return mSingleCrunchOutputFile; }
-    void setSingleCrunchOutputFile(const char* val) { mSingleCrunchOutputFile = val; }
-
-    /*
-     * Set and get the file specification.
-     *
-     * Note this does NOT make a copy of argv.
-     */
-    void setFileSpec(char* const argv[], int argc) {
-        mArgc = argc;
-        mArgv = argv;
-    }
-    int getFileSpecCount(void) const { return mArgc; }
-    const char* getFileSpecEntry(int idx) const { return mArgv[idx]; }
-    void eatArgs(int n) {
-        if (n > mArgc) n = mArgc;
-        mArgv += n;
-        mArgc -= n;
-    }
-
-#if 0
-    /*
-     * Package count.  Nothing to do with anything else here; this is
-     * just a convenient place to stuff it so we don't have to pass it
-     * around everywhere.
-     */
-    int getPackageCount(void) const { return mPackageCount; }
-    void setPackageCount(int val) { mPackageCount = val; }
-#endif
-
-    /* Certain features may only be available on a specific SDK level or
-     * above. SDK levels that have a non-numeric identifier are assumed
-     * to be newer than any SDK level that has a number designated.
-     */
-    bool isMinSdkAtLeast(int desired) {
-        /* If the application specifies a minSdkVersion in the manifest
-         * then use that. Otherwise, check what the user specified on
-         * the command line. If neither, it's not available since
-         * the minimum SDK version is assumed to be 1.
-         */
-        const char *minVer;
-        if (mManifestMinSdkVersion != NULL) {
-            minVer = mManifestMinSdkVersion;
-        } else if (mMinSdkVersion != NULL) {
-            minVer = mMinSdkVersion;
-        } else {
-            return false;
-        }
-
-        char *end;
-        int minSdkNum = (int)strtol(minVer, &end, 0);
-        if (*end == '\0') {
-            if (minSdkNum < desired) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-private:
-    /* commands & modifiers */
-    Command     mCmd;
-    bool        mVerbose;
-    bool        mAndroidList;
-    bool        mForce;
-    int         mGrayscaleTolerance;
-    bool        mMakePackageDirs;
-    bool        mUpdate;
-    bool        mExtending;
-    bool        mRequireLocalization;
-    bool        mPseudolocalize;
-    bool        mWantUTF16;
-    bool        mValues;
-    int         mCompressionMethod;
-    bool        mJunkPath;
-    const char* mOutputAPKFile;
-    const char* mManifestPackageNameOverride;
-    const char* mInstrumentationPackageNameOverride;
-    bool        mAutoAddOverlay;
-    bool        mGenDependencies;
-    const char* mAssetSourceDir;
-    const char* mCrunchedOutputDir;
-    const char* mProguardFile;
-    const char* mAndroidManifestFile;
-    const char* mPublicOutputFile;
-    const char* mRClassDir;
-    const char* mResourceIntermediatesDir;
-    android::String8 mConfigurations;
-    android::String8 mPreferredConfigurations;
-    android::Vector<const char*> mPackageIncludes;
-    android::Vector<const char*> mJarFiles;
-    android::Vector<const char*> mNoCompressExtensions;
-    android::Vector<const char*> mResourceSourceDirs;
-
-    const char* mManifestMinSdkVersion;
-    const char* mMinSdkVersion;
-    const char* mTargetSdkVersion;
-    const char* mMaxSdkVersion;
-    const char* mVersionCode;
-    const char* mVersionName;
-    const char* mCustomPackage;
-    const char* mExtraPackages;
-    const char* mMaxResVersion;
-    bool        mDebugMode;
-    bool        mNonConstantId;
-    const char* mProduct;
-    bool        mUseCrunchCache;
-    bool        mErrorOnFailedInsert;
-    const char* mOutputTextSymbols;
-    const char* mSingleCrunchInputFile;
-    const char* mSingleCrunchOutputFile;
-
-    /* file specification */
-    int         mArgc;
-    char* const* mArgv;
-
-#if 0
-    /* misc stuff */
-    int         mPackageCount;
-#endif
-
-};
-
-#endif // __BUNDLE_H
diff --git a/tools/aapt/CacheUpdater.h b/tools/aapt/CacheUpdater.h
deleted file mode 100644
index 0e65589..0000000
--- a/tools/aapt/CacheUpdater.h
+++ /dev/null
@@ -1,107 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-// Abstraction of calls to system to make directories and delete files and
-// wrapper to image processing.
-
-#ifndef CACHE_UPDATER_H
-#define CACHE_UPDATER_H
-
-#include <utils/String8.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include "Images.h"
-
-using namespace android;
-
-/** CacheUpdater
- *  This is a pure virtual class that declares abstractions of functions useful
- *  for managing a cache files. This manager is set up to be used in a
- *  mirror cache where the source tree is duplicated and filled with processed
- *  images. This class is abstracted to allow for dependency injection during
- *  unit testing.
- *  Usage:
- *      To update/add a file to the cache, call processImage
- *      To remove a file from the cache, call deleteFile
- */
-class CacheUpdater {
-public:
-    // Make sure all the directories along this path exist
-    virtual void ensureDirectoriesExist(String8 path) = 0;
-
-    // Delete a file
-    virtual void deleteFile(String8 path) = 0;
-
-    // Process an image from source out to dest
-    virtual void processImage(String8 source, String8 dest) = 0;
-private:
-};
-
-/** SystemCacheUpdater
- * This is an implementation of the above virtual cache updater specification.
- * This implementations hits the filesystem to manage a cache and calls out to
- * the PNG crunching in images.h to process images out to its cache components.
- */
-class SystemCacheUpdater : public CacheUpdater {
-public:
-    // Constructor to set bundle to pass to preProcessImage
-    SystemCacheUpdater (Bundle* b)
-        : bundle(b) { };
-
-    // Make sure all the directories along this path exist
-    virtual void ensureDirectoriesExist(String8 path)
-    {
-        // Check to see if we're dealing with a fully qualified path
-        String8 existsPath;
-        String8 toCreate;
-        String8 remains;
-        struct stat s;
-
-        // Check optomistically to see if all directories exist.
-        // If something in the path doesn't exist, then walk the path backwards
-        // and find the place to start creating directories forward.
-        if (stat(path.string(),&s) == -1) {
-            // Walk backwards to find place to start creating directories
-            existsPath = path;
-            do {
-                // As we remove the end of existsPath add it to
-                // the string of paths to create.
-                toCreate = existsPath.getPathLeaf().appendPath(toCreate);
-                existsPath = existsPath.getPathDir();
-            } while (stat(existsPath.string(),&s) == -1);
-
-            // Walk forwards and build directories as we go
-            do {
-                // Advance to the next segment of the path
-                existsPath.appendPath(toCreate.walkPath(&remains));
-                toCreate = remains;
-#ifdef HAVE_MS_C_RUNTIME
-                _mkdir(existsPath.string());
-#else
-                mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
-#endif
-            } while (remains.length() > 0);
-        } //if
-    };
-
-    // Delete a file
-    virtual void deleteFile(String8 path)
-    {
-        if (remove(path.string()) != 0)
-            fprintf(stderr,"ERROR DELETING %s\n",path.string());
-    };
-
-    // Process an image from source out to dest
-    virtual void processImage(String8 source, String8 dest)
-    {
-        // Make sure we're trying to write to a directory that is extant
-        ensureDirectoriesExist(dest.getPathDir());
-
-        preProcessImageToCache(bundle, source, dest);
-    };
-private:
-    Bundle* bundle;
-};
-
-#endif // CACHE_UPDATER_H
\ No newline at end of file
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
deleted file mode 100644
index 632efe0..0000000
--- a/tools/aapt/Command.cpp
+++ /dev/null
@@ -1,2269 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Android Asset Packaging Tool main entry point.
-//
-#include "Main.h"
-#include "Bundle.h"
-#include "ResourceFilter.h"
-#include "ResourceTable.h"
-#include "Images.h"
-#include "XMLNode.h"
-
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <utils/List.h>
-#include <utils/Errors.h>
-
-#include <fcntl.h>
-#include <errno.h>
-
-using namespace android;
-
-/*
- * Show version info.  All the cool kids do it.
- */
-int doVersion(Bundle* bundle)
-{
-    if (bundle->getFileSpecCount() != 0)
-        printf("(ignoring extra arguments)\n");
-    printf("Android Asset Packaging Tool, v0.2\n");
-
-    return 0;
-}
-
-
-/*
- * Open the file read only.  The call fails if the file doesn't exist.
- *
- * Returns NULL on failure.
- */
-ZipFile* openReadOnly(const char* fileName)
-{
-    ZipFile* zip;
-    status_t result;
-
-    zip = new ZipFile;
-    result = zip->open(fileName, ZipFile::kOpenReadOnly);
-    if (result != NO_ERROR) {
-        if (result == NAME_NOT_FOUND)
-            fprintf(stderr, "ERROR: '%s' not found\n", fileName);
-        else if (result == PERMISSION_DENIED)
-            fprintf(stderr, "ERROR: '%s' access denied\n", fileName);
-        else
-            fprintf(stderr, "ERROR: failed opening '%s' as Zip file\n",
-                fileName);
-        delete zip;
-        return NULL;
-    }
-
-    return zip;
-}
-
-/*
- * Open the file read-write.  The file will be created if it doesn't
- * already exist and "okayToCreate" is set.
- *
- * Returns NULL on failure.
- */
-ZipFile* openReadWrite(const char* fileName, bool okayToCreate)
-{
-    ZipFile* zip = NULL;
-    status_t result;
-    int flags;
-
-    flags = ZipFile::kOpenReadWrite;
-    if (okayToCreate)
-        flags |= ZipFile::kOpenCreate;
-
-    zip = new ZipFile;
-    result = zip->open(fileName, flags);
-    if (result != NO_ERROR) {
-        delete zip;
-        zip = NULL;
-        goto bail;
-    }
-
-bail:
-    return zip;
-}
-
-
-/*
- * Return a short string describing the compression method.
- */
-const char* compressionName(int method)
-{
-    if (method == ZipEntry::kCompressStored)
-        return "Stored";
-    else if (method == ZipEntry::kCompressDeflated)
-        return "Deflated";
-    else
-        return "Unknown";
-}
-
-/*
- * Return the percent reduction in size (0% == no compression).
- */
-int calcPercent(long uncompressedLen, long compressedLen)
-{
-    if (!uncompressedLen)
-        return 0;
-    else
-        return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5);
-}
-
-/*
- * Handle the "list" command, which can be a simple file dump or
- * a verbose listing.
- *
- * The verbose listing closely matches the output of the Info-ZIP "unzip"
- * command.
- */
-int doList(Bundle* bundle)
-{
-    int result = 1;
-    ZipFile* zip = NULL;
-    const ZipEntry* entry;
-    long totalUncLen, totalCompLen;
-    const char* zipFileName;
-
-    if (bundle->getFileSpecCount() != 1) {
-        fprintf(stderr, "ERROR: specify zip file name (only)\n");
-        goto bail;
-    }
-    zipFileName = bundle->getFileSpecEntry(0);
-
-    zip = openReadOnly(zipFileName);
-    if (zip == NULL)
-        goto bail;
-
-    int count, i;
-
-    if (bundle->getVerbose()) {
-        printf("Archive:  %s\n", zipFileName);
-        printf(
-            " Length   Method    Size  Ratio   Offset      Date  Time  CRC-32    Name\n");
-        printf(
-            "--------  ------  ------- -----  -------      ----  ----  ------    ----\n");
-    }
-
-    totalUncLen = totalCompLen = 0;
-
-    count = zip->getNumEntries();
-    for (i = 0; i < count; i++) {
-        entry = zip->getEntryByIndex(i);
-        if (bundle->getVerbose()) {
-            char dateBuf[32];
-            time_t when;
-
-            when = entry->getModWhen();
-            strftime(dateBuf, sizeof(dateBuf), "%m-%d-%y %H:%M",
-                localtime(&when));
-
-            printf("%8ld  %-7.7s %7ld %3d%%  %8zd  %s  %08lx  %s\n",
-                (long) entry->getUncompressedLen(),
-                compressionName(entry->getCompressionMethod()),
-                (long) entry->getCompressedLen(),
-                calcPercent(entry->getUncompressedLen(),
-                            entry->getCompressedLen()),
-                (size_t) entry->getLFHOffset(),
-                dateBuf,
-                entry->getCRC32(),
-                entry->getFileName());
-        } else {
-            printf("%s\n", entry->getFileName());
-        }
-
-        totalUncLen += entry->getUncompressedLen();
-        totalCompLen += entry->getCompressedLen();
-    }
-
-    if (bundle->getVerbose()) {
-        printf(
-        "--------          -------  ---                            -------\n");
-        printf("%8ld          %7ld  %2d%%                            %d files\n",
-            totalUncLen,
-            totalCompLen,
-            calcPercent(totalUncLen, totalCompLen),
-            zip->getNumEntries());
-    }
-
-    if (bundle->getAndroidList()) {
-        AssetManager assets;
-        if (!assets.addAssetPath(String8(zipFileName), NULL)) {
-            fprintf(stderr, "ERROR: list -a failed because assets could not be loaded\n");
-            goto bail;
-        }
-
-        const ResTable& res = assets.getResources(false);
-        if (&res == NULL) {
-            printf("\nNo resource table found.\n");
-        } else {
-#ifndef HAVE_ANDROID_OS
-            printf("\nResource table:\n");
-            res.print(false);
-#endif
-        }
-
-        Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml",
-                                                   Asset::ACCESS_BUFFER);
-        if (manifestAsset == NULL) {
-            printf("\nNo AndroidManifest.xml found.\n");
-        } else {
-            printf("\nAndroid manifest:\n");
-            ResXMLTree tree;
-            tree.setTo(manifestAsset->getBuffer(true),
-                       manifestAsset->getLength());
-            printXMLBlock(&tree);
-        }
-        delete manifestAsset;
-    }
-
-    result = 0;
-
-bail:
-    delete zip;
-    return result;
-}
-
-static ssize_t indexOfAttribute(const ResXMLTree& tree, uint32_t attrRes)
-{
-    size_t N = tree.getAttributeCount();
-    for (size_t i=0; i<N; i++) {
-        if (tree.getAttributeNameResID(i) == attrRes) {
-            return (ssize_t)i;
-        }
-    }
-    return -1;
-}
-
-String8 getAttribute(const ResXMLTree& tree, const char* ns,
-                            const char* attr, String8* outError)
-{
-    ssize_t idx = tree.indexOfAttribute(ns, attr);
-    if (idx < 0) {
-        return String8();
-    }
-    Res_value value;
-    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
-        if (value.dataType != Res_value::TYPE_STRING) {
-            if (outError != NULL) *outError = "attribute is not a string value";
-            return String8();
-        }
-    }
-    size_t len;
-    const uint16_t* str = tree.getAttributeStringValue(idx, &len);
-    return str ? String8(str, len) : String8();
-}
-
-static String8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError)
-{
-    ssize_t idx = indexOfAttribute(tree, attrRes);
-    if (idx < 0) {
-        return String8();
-    }
-    Res_value value;
-    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
-        if (value.dataType != Res_value::TYPE_STRING) {
-            if (outError != NULL) *outError = "attribute is not a string value";
-            return String8();
-        }
-    }
-    size_t len;
-    const uint16_t* str = tree.getAttributeStringValue(idx, &len);
-    return str ? String8(str, len) : String8();
-}
-
-static int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes,
-        String8* outError, int32_t defValue = -1)
-{
-    ssize_t idx = indexOfAttribute(tree, attrRes);
-    if (idx < 0) {
-        return defValue;
-    }
-    Res_value value;
-    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
-        if (value.dataType < Res_value::TYPE_FIRST_INT
-                || value.dataType > Res_value::TYPE_LAST_INT) {
-            if (outError != NULL) *outError = "attribute is not an integer value";
-            return defValue;
-        }
-    }
-    return value.data;
-}
-
-static int32_t getResolvedIntegerAttribute(const ResTable* resTable, const ResXMLTree& tree,
-        uint32_t attrRes, String8* outError, int32_t defValue = -1)
-{
-    ssize_t idx = indexOfAttribute(tree, attrRes);
-    if (idx < 0) {
-        return defValue;
-    }
-    Res_value value;
-    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
-        if (value.dataType == Res_value::TYPE_REFERENCE) {
-            resTable->resolveReference(&value, 0);
-        }
-        if (value.dataType < Res_value::TYPE_FIRST_INT
-                || value.dataType > Res_value::TYPE_LAST_INT) {
-            if (outError != NULL) *outError = "attribute is not an integer value";
-            return defValue;
-        }
-    }
-    return value.data;
-}
-
-static String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& tree,
-        uint32_t attrRes, String8* outError)
-{
-    ssize_t idx = indexOfAttribute(tree, attrRes);
-    if (idx < 0) {
-        return String8();
-    }
-    Res_value value;
-    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
-        if (value.dataType == Res_value::TYPE_STRING) {
-            size_t len;
-            const uint16_t* str = tree.getAttributeStringValue(idx, &len);
-            return str ? String8(str, len) : String8();
-        }
-        resTable->resolveReference(&value, 0);
-        if (value.dataType != Res_value::TYPE_STRING) {
-            if (outError != NULL) *outError = "attribute is not a string value";
-            return String8();
-        }
-    }
-    size_t len;
-    const Res_value* value2 = &value;
-    const char16_t* str = const_cast<ResTable*>(resTable)->valueToString(value2, 0, NULL, &len);
-    return str ? String8(str, len) : String8();
-}
-
-// These are attribute resource constants for the platform, as found
-// in android.R.attr
-enum {
-    LABEL_ATTR = 0x01010001,
-    ICON_ATTR = 0x01010002,
-    NAME_ATTR = 0x01010003,
-    PERMISSION_ATTR = 0x01010006,
-    RESOURCE_ATTR = 0x01010025,
-    DEBUGGABLE_ATTR = 0x0101000f,
-    VERSION_CODE_ATTR = 0x0101021b,
-    VERSION_NAME_ATTR = 0x0101021c,
-    SCREEN_ORIENTATION_ATTR = 0x0101001e,
-    MIN_SDK_VERSION_ATTR = 0x0101020c,
-    MAX_SDK_VERSION_ATTR = 0x01010271,
-    REQ_TOUCH_SCREEN_ATTR = 0x01010227,
-    REQ_KEYBOARD_TYPE_ATTR = 0x01010228,
-    REQ_HARD_KEYBOARD_ATTR = 0x01010229,
-    REQ_NAVIGATION_ATTR = 0x0101022a,
-    REQ_FIVE_WAY_NAV_ATTR = 0x01010232,
-    TARGET_SDK_VERSION_ATTR = 0x01010270,
-    TEST_ONLY_ATTR = 0x01010272,
-    ANY_DENSITY_ATTR = 0x0101026c,
-    GL_ES_VERSION_ATTR = 0x01010281,
-    SMALL_SCREEN_ATTR = 0x01010284,
-    NORMAL_SCREEN_ATTR = 0x01010285,
-    LARGE_SCREEN_ATTR = 0x01010286,
-    XLARGE_SCREEN_ATTR = 0x010102bf,
-    REQUIRED_ATTR = 0x0101028e,
-    SCREEN_SIZE_ATTR = 0x010102ca,
-    SCREEN_DENSITY_ATTR = 0x010102cb,
-    REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364,
-    COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365,
-    LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366,
-    PUBLIC_KEY_ATTR = 0x010103a6,
-    CATEGORY_ATTR = 0x010103e8,
-};
-
-const char *getComponentName(String8 &pkgName, String8 &componentName) {
-    ssize_t idx = componentName.find(".");
-    String8 retStr(pkgName);
-    if (idx == 0) {
-        retStr += componentName;
-    } else if (idx < 0) {
-        retStr += ".";
-        retStr += componentName;
-    } else {
-        return componentName.string();
-    }
-    return retStr.string();
-}
-
-static void printCompatibleScreens(ResXMLTree& tree) {
-    size_t len;
-    ResXMLTree::event_code_t code;
-    int depth = 0;
-    bool first = true;
-    printf("compatible-screens:");
-    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-        if (code == ResXMLTree::END_TAG) {
-            depth--;
-            if (depth < 0) {
-                break;
-            }
-            continue;
-        }
-        if (code != ResXMLTree::START_TAG) {
-            continue;
-        }
-        depth++;
-        String8 tag(tree.getElementName(&len));
-        if (tag == "screen") {
-            int32_t screenSize = getIntegerAttribute(tree,
-                    SCREEN_SIZE_ATTR, NULL, -1);
-            int32_t screenDensity = getIntegerAttribute(tree,
-                    SCREEN_DENSITY_ATTR, NULL, -1);
-            if (screenSize > 0 && screenDensity > 0) {
-                if (!first) {
-                    printf(",");
-                }
-                first = false;
-                printf("'%d/%d'", screenSize, screenDensity);
-            }
-        }
-    }
-    printf("\n");
-}
-
-Vector<String8> getNfcAidCategories(AssetManager& assets, String8 xmlPath, bool offHost,
-        String8 *outError = NULL)
-{
-    Asset* aidAsset = assets.openNonAsset(xmlPath, Asset::ACCESS_BUFFER);
-    if (aidAsset == NULL) {
-        if (outError != NULL) *outError = "xml resource does not exist";
-        return Vector<String8>();
-    }
-
-    const String8 serviceTagName(offHost ? "offhost-apdu-service" : "host-apdu-service");
-
-    bool withinApduService = false;
-    Vector<String8> categories;
-
-    String8 error;
-    ResXMLTree tree;
-    tree.setTo(aidAsset->getBuffer(true), aidAsset->getLength());
-
-    size_t len;
-    int depth = 0;
-    ResXMLTree::event_code_t code;
-    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-        if (code == ResXMLTree::END_TAG) {
-            depth--;
-            String8 tag(tree.getElementName(&len));
-
-            if (depth == 0 && tag == serviceTagName) {
-                withinApduService = false;
-            }
-
-        } else if (code == ResXMLTree::START_TAG) {
-            depth++;
-            String8 tag(tree.getElementName(&len));
-
-            if (depth == 1) {
-                if (tag == serviceTagName) {
-                    withinApduService = true;
-                }
-            } else if (depth == 2 && withinApduService) {
-                if (tag == "aid-group") {
-                    String8 category = getAttribute(tree, CATEGORY_ATTR, &error);
-                    if (error != "") {
-                        if (outError != NULL) *outError = error;
-                        return Vector<String8>();
-                    }
-
-                    categories.add(category);
-                }
-            }
-        }
-    }
-    aidAsset->close();
-    return categories;
-}
-
-/*
- * Handle the "dump" command, to extract select data from an archive.
- */
-extern char CONSOLE_DATA[2925]; // see EOF
-int doDump(Bundle* bundle)
-{
-    status_t result = UNKNOWN_ERROR;
-    Asset* asset = NULL;
-
-    if (bundle->getFileSpecCount() < 1) {
-        fprintf(stderr, "ERROR: no dump option specified\n");
-        return 1;
-    }
-
-    if (bundle->getFileSpecCount() < 2) {
-        fprintf(stderr, "ERROR: no dump file specified\n");
-        return 1;
-    }
-
-    const char* option = bundle->getFileSpecEntry(0);
-    const char* filename = bundle->getFileSpecEntry(1);
-
-    AssetManager assets;
-    void* assetsCookie;
-    if (!assets.addAssetPath(String8(filename), &assetsCookie)) {
-        fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n");
-        return 1;
-    }
-
-    // Make a dummy config for retrieving resources...  we need to supply
-    // non-default values for some configs so that we can retrieve resources
-    // in the app that don't have a default.  The most important of these is
-    // the API version because key resources like icons will have an implicit
-    // version if they are using newer config types like density.
-    ResTable_config config;
-    config.language[0] = 'e';
-    config.language[1] = 'n';
-    config.country[0] = 'U';
-    config.country[1] = 'S';
-    config.orientation = ResTable_config::ORIENTATION_PORT;
-    config.density = ResTable_config::DENSITY_MEDIUM;
-    config.sdkVersion = 10000; // Very high.
-    config.screenWidthDp = 320;
-    config.screenHeightDp = 480;
-    config.smallestScreenWidthDp = 320;
-    assets.setConfiguration(config);
-
-    const ResTable& res = assets.getResources(false);
-    if (&res == NULL) {
-        fprintf(stderr, "ERROR: dump failed because no resource table was found\n");
-        goto bail;
-    }
-
-    if (strcmp("resources", option) == 0) {
-#ifndef HAVE_ANDROID_OS
-        res.print(bundle->getValues());
-#endif
-
-    } else if (strcmp("strings", option) == 0) {
-        const ResStringPool* pool = res.getTableStringBlock(0);
-        printStringPool(pool);
-
-    } else if (strcmp("xmltree", option) == 0) {
-        if (bundle->getFileSpecCount() < 3) {
-            fprintf(stderr, "ERROR: no dump xmltree resource file specified\n");
-            goto bail;
-        }
-
-        for (int i=2; i<bundle->getFileSpecCount(); i++) {
-            const char* resname = bundle->getFileSpecEntry(i);
-            ResXMLTree tree;
-            asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER);
-            if (asset == NULL) {
-                fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname);
-                goto bail;
-            }
-
-            if (tree.setTo(asset->getBuffer(true),
-                           asset->getLength()) != NO_ERROR) {
-                fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname);
-                goto bail;
-            }
-            tree.restart();
-            printXMLBlock(&tree);
-            tree.uninit();
-            delete asset;
-            asset = NULL;
-        }
-
-    } else if (strcmp("xmlstrings", option) == 0) {
-        if (bundle->getFileSpecCount() < 3) {
-            fprintf(stderr, "ERROR: no dump xmltree resource file specified\n");
-            goto bail;
-        }
-
-        for (int i=2; i<bundle->getFileSpecCount(); i++) {
-            const char* resname = bundle->getFileSpecEntry(i);
-            ResXMLTree tree;
-            asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER);
-            if (asset == NULL) {
-                fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname);
-                goto bail;
-            }
-
-            if (tree.setTo(asset->getBuffer(true),
-                           asset->getLength()) != NO_ERROR) {
-                fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname);
-                goto bail;
-            }
-            printStringPool(&tree.getStrings());
-            delete asset;
-            asset = NULL;
-        }
-
-    } else {
-        ResXMLTree tree;
-        asset = assets.openNonAsset("AndroidManifest.xml",
-                                            Asset::ACCESS_BUFFER);
-        if (asset == NULL) {
-            fprintf(stderr, "ERROR: dump failed because no AndroidManifest.xml found\n");
-            goto bail;
-        }
-
-        if (tree.setTo(asset->getBuffer(true),
-                       asset->getLength()) != NO_ERROR) {
-            fprintf(stderr, "ERROR: AndroidManifest.xml is corrupt\n");
-            goto bail;
-        }
-        tree.restart();
-
-        if (strcmp("permissions", option) == 0) {
-            size_t len;
-            ResXMLTree::event_code_t code;
-            int depth = 0;
-            while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-                if (code == ResXMLTree::END_TAG) {
-                    depth--;
-                    continue;
-                }
-                if (code != ResXMLTree::START_TAG) {
-                    continue;
-                }
-                depth++;
-                String8 tag(tree.getElementName(&len));
-                //printf("Depth %d tag %s\n", depth, tag.string());
-                if (depth == 1) {
-                    if (tag != "manifest") {
-                        fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n");
-                        goto bail;
-                    }
-                    String8 pkg = getAttribute(tree, NULL, "package", NULL);
-                    printf("package: %s\n", pkg.string());
-                } else if (depth == 2 && tag == "permission") {
-                    String8 error;
-                    String8 name = getAttribute(tree, NAME_ATTR, &error);
-                    if (error != "") {
-                        fprintf(stderr, "ERROR: %s\n", error.string());
-                        goto bail;
-                    }
-                    printf("permission: %s\n", name.string());
-                } else if (depth == 2 && tag == "uses-permission") {
-                    String8 error;
-                    String8 name = getAttribute(tree, NAME_ATTR, &error);
-                    if (error != "") {
-                        fprintf(stderr, "ERROR: %s\n", error.string());
-                        goto bail;
-                    }
-                    printf("uses-permission: %s\n", name.string());
-                    int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1);
-                    if (!req) {
-                        printf("optional-permission: %s\n", name.string());
-                    }
-                }
-            }
-        } else if (strcmp("badging", option) == 0) {
-            Vector<String8> locales;
-            res.getLocales(&locales);
-
-            Vector<ResTable_config> configs;
-            res.getConfigurations(&configs);
-            SortedVector<int> densities;
-            const size_t NC = configs.size();
-            for (size_t i=0; i<NC; i++) {
-                int dens = configs[i].density;
-                if (dens == 0) dens = 160;
-                densities.add(dens);
-            }
-
-            size_t len;
-            ResXMLTree::event_code_t code;
-            int depth = 0;
-            String8 error;
-            bool withinActivity = false;
-            bool isMainActivity = false;
-            bool isLauncherActivity = false;
-            bool isSearchable = false;
-            bool withinApplication = false;
-            bool withinSupportsInput = false;
-            bool withinReceiver = false;
-            bool withinService = false;
-            bool withinIntentFilter = false;
-            bool hasMainActivity = false;
-            bool hasOtherActivities = false;
-            bool hasOtherReceivers = false;
-            bool hasOtherServices = false;
-            bool hasWallpaperService = false;
-            bool hasImeService = false;
-            bool hasAccessibilityService = false;
-            bool hasPrintService = false;
-            bool hasWidgetReceivers = false;
-            bool hasDeviceAdminReceiver = false;
-            bool hasIntentFilter = false;
-            bool hasPaymentService = false;
-            bool actMainActivity = false;
-            bool actWidgetReceivers = false;
-            bool actDeviceAdminEnabled = false;
-            bool actImeService = false;
-            bool actWallpaperService = false;
-            bool actAccessibilityService = false;
-            bool actPrintService = false;
-            bool actHostApduService = false;
-            bool actOffHostApduService = false;
-            bool hasMetaHostPaymentCategory = false;
-            bool hasMetaOffHostPaymentCategory = false;
-
-            // These permissions are required by services implementing services
-            // the system binds to (IME, Accessibility, PrintServices, etc.)
-            bool hasBindDeviceAdminPermission = false;
-            bool hasBindInputMethodPermission = false;
-            bool hasBindAccessibilityServicePermission = false;
-            bool hasBindPrintServicePermission = false;
-            bool hasBindNfcServicePermission = false;
-
-            // These two implement the implicit permissions that are granted
-            // to pre-1.6 applications.
-            bool hasWriteExternalStoragePermission = false;
-            bool hasReadPhoneStatePermission = false;
-
-            // If an app requests write storage, they will also get read storage.
-            bool hasReadExternalStoragePermission = false;
-
-            // Implement transition to read and write call log.
-            bool hasReadContactsPermission = false;
-            bool hasWriteContactsPermission = false;
-            bool hasReadCallLogPermission = false;
-            bool hasWriteCallLogPermission = false;
-
-            // This next group of variables is used to implement a group of
-            // backward-compatibility heuristics necessitated by the addition of
-            // some new uses-feature constants in 2.1 and 2.2. In most cases, the
-            // heuristic is "if an app requests a permission but doesn't explicitly
-            // request the corresponding <uses-feature>, presume it's there anyway".
-            bool specCameraFeature = false; // camera-related
-            bool specCameraAutofocusFeature = false;
-            bool reqCameraAutofocusFeature = false;
-            bool reqCameraFlashFeature = false;
-            bool hasCameraPermission = false;
-            bool specLocationFeature = false; // location-related
-            bool specNetworkLocFeature = false;
-            bool reqNetworkLocFeature = false;
-            bool specGpsFeature = false;
-            bool reqGpsFeature = false;
-            bool hasMockLocPermission = false;
-            bool hasCoarseLocPermission = false;
-            bool hasGpsPermission = false;
-            bool hasGeneralLocPermission = false;
-            bool specBluetoothFeature = false; // Bluetooth API-related
-            bool hasBluetoothPermission = false;
-            bool specMicrophoneFeature = false; // microphone-related
-            bool hasRecordAudioPermission = false;
-            bool specWiFiFeature = false;
-            bool hasWiFiPermission = false;
-            bool specTelephonyFeature = false; // telephony-related
-            bool reqTelephonySubFeature = false;
-            bool hasTelephonyPermission = false;
-            bool specTouchscreenFeature = false; // touchscreen-related
-            bool specMultitouchFeature = false;
-            bool reqDistinctMultitouchFeature = false;
-            bool specScreenPortraitFeature = false;
-            bool specScreenLandscapeFeature = false;
-            bool reqScreenPortraitFeature = false;
-            bool reqScreenLandscapeFeature = false;
-            // 2.2 also added some other features that apps can request, but that
-            // have no corresponding permission, so we cannot implement any
-            // back-compatibility heuristic for them. The below are thus unnecessary
-            // (but are retained here for documentary purposes.)
-            //bool specCompassFeature = false;
-            //bool specAccelerometerFeature = false;
-            //bool specProximityFeature = false;
-            //bool specAmbientLightFeature = false;
-            //bool specLiveWallpaperFeature = false;
-
-            int targetSdk = 0;
-            int smallScreen = 1;
-            int normalScreen = 1;
-            int largeScreen = 1;
-            int xlargeScreen = 1;
-            int anyDensity = 1;
-            int requiresSmallestWidthDp = 0;
-            int compatibleWidthLimitDp = 0;
-            int largestWidthLimitDp = 0;
-            String8 pkg;
-            String8 activityName;
-            String8 activityLabel;
-            String8 activityIcon;
-            String8 receiverName;
-            String8 serviceName;
-            Vector<String8> supportedInput;
-            while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-                if (code == ResXMLTree::END_TAG) {
-                    depth--;
-                    if (depth < 2) {
-                        if (withinSupportsInput && !supportedInput.isEmpty()) {
-                            printf("supports-input: '");
-                            const size_t N = supportedInput.size();
-                            for (size_t i=0; i<N; i++) {
-                                printf("%s", supportedInput[i].string());
-                                if (i != N - 1) {
-                                    printf("' '");
-                                } else {
-                                    printf("'\n");
-                                }
-                            }
-                            supportedInput.clear();
-                        }
-                        withinApplication = false;
-                        withinSupportsInput = false;
-                    } else if (depth < 3) {
-                        if (withinActivity && isMainActivity && isLauncherActivity) {
-                            const char *aName = getComponentName(pkg, activityName);
-                            printf("launchable-activity:");
-                            if (aName != NULL) {
-                                printf(" name='%s' ", aName);
-                            }
-                            printf(" label='%s' icon='%s'\n",
-                                    activityLabel.string(),
-                                    activityIcon.string());
-                        }
-                        if (!hasIntentFilter) {
-                            hasOtherActivities |= withinActivity;
-                            hasOtherReceivers |= withinReceiver;
-                            hasOtherServices |= withinService;
-                        } else {
-                            if (withinService) {
-                                hasPaymentService |= (actHostApduService && hasMetaHostPaymentCategory &&
-                                        hasBindNfcServicePermission);
-                                hasPaymentService |= (actOffHostApduService && hasMetaOffHostPaymentCategory &&
-                                        hasBindNfcServicePermission);
-                            }
-                        }
-                        withinActivity = false;
-                        withinService = false;
-                        withinReceiver = false;
-                        hasIntentFilter = false;
-                        isMainActivity = isLauncherActivity = false;
-                    } else if (depth < 4) {
-                        if (withinIntentFilter) {
-                            if (withinActivity) {
-                                hasMainActivity |= actMainActivity;
-                                hasOtherActivities |= !actMainActivity;
-                            } else if (withinReceiver) {
-                                hasWidgetReceivers |= actWidgetReceivers;
-                                hasDeviceAdminReceiver |= (actDeviceAdminEnabled &&
-                                        hasBindDeviceAdminPermission);
-                                hasOtherReceivers |= (!actWidgetReceivers && !actDeviceAdminEnabled);
-                            } else if (withinService) {
-                                hasImeService |= actImeService;
-                                hasWallpaperService |= actWallpaperService;
-                                hasAccessibilityService |= (actAccessibilityService &&
-                                        hasBindAccessibilityServicePermission);
-                                hasPrintService |= (actPrintService && hasBindPrintServicePermission);
-                                hasOtherServices |= (!actImeService && !actWallpaperService &&
-                                        !actAccessibilityService && !actPrintService &&
-                                        !actHostApduService && !actOffHostApduService);
-                            }
-                        }
-                        withinIntentFilter = false;
-                    }
-                    continue;
-                }
-                if (code != ResXMLTree::START_TAG) {
-                    continue;
-                }
-                depth++;
-                String8 tag(tree.getElementName(&len));
-                //printf("Depth %d,  %s\n", depth, tag.string());
-                if (depth == 1) {
-                    if (tag != "manifest") {
-                        fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n");
-                        goto bail;
-                    }
-                    pkg = getAttribute(tree, NULL, "package", NULL);
-                    printf("package: name='%s' ", pkg.string());
-                    int32_t versionCode = getIntegerAttribute(tree, VERSION_CODE_ATTR, &error);
-                    if (error != "") {
-                        fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", error.string());
-                        goto bail;
-                    }
-                    if (versionCode > 0) {
-                        printf("versionCode='%d' ", versionCode);
-                    } else {
-                        printf("versionCode='' ");
-                    }
-                    String8 versionName = getResolvedAttribute(&res, tree, VERSION_NAME_ATTR, &error);
-                    if (error != "") {
-                        fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", error.string());
-                        goto bail;
-                    }
-                    printf("versionName='%s'\n", versionName.string());
-                } else if (depth == 2) {
-                    withinApplication = false;
-                    if (tag == "application") {
-                        withinApplication = true;
-
-                        String8 label;
-                        const size_t NL = locales.size();
-                        for (size_t i=0; i<NL; i++) {
-                            const char* localeStr =  locales[i].string();
-                            assets.setLocale(localeStr != NULL ? localeStr : "");
-                            String8 llabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error);
-                            if (llabel != "") {
-                                if (localeStr == NULL || strlen(localeStr) == 0) {
-                                    label = llabel;
-                                    printf("application-label:'%s'\n", llabel.string());
-                                } else {
-                                    if (label == "") {
-                                        label = llabel;
-                                    }
-                                    printf("application-label-%s:'%s'\n", localeStr,
-                                            llabel.string());
-                                }
-                            }
-                        }
-
-                        ResTable_config tmpConfig = config;
-                        const size_t ND = densities.size();
-                        for (size_t i=0; i<ND; i++) {
-                            tmpConfig.density = densities[i];
-                            assets.setConfiguration(tmpConfig);
-                            String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
-                            if (icon != "") {
-                                printf("application-icon-%d:'%s'\n", densities[i], icon.string());
-                            }
-                        }
-                        assets.setConfiguration(config);
-
-                        String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string());
-                            goto bail;
-                        }
-                        int32_t testOnly = getIntegerAttribute(tree, TEST_ONLY_ATTR, &error, 0);
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string());
-                            goto bail;
-                        }
-                        printf("application: label='%s' ", label.string());
-                        printf("icon='%s'\n", icon.string());
-                        if (testOnly != 0) {
-                            printf("testOnly='%d'\n", testOnly);
-                        }
-
-                        int32_t debuggable = getResolvedIntegerAttribute(&res, tree, DEBUGGABLE_ATTR, &error, 0);
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:debuggable' attribute: %s\n", error.string());
-                            goto bail;
-                        }
-                        if (debuggable != 0) {
-                            printf("application-debuggable\n");
-                        }
-                    } else if (tag == "uses-sdk") {
-                        int32_t code = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error);
-                        if (error != "") {
-                            error = "";
-                            String8 name = getResolvedAttribute(&res, tree, MIN_SDK_VERSION_ATTR, &error);
-                            if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:minSdkVersion' attribute: %s\n",
-                                        error.string());
-                                goto bail;
-                            }
-                            if (name == "Donut") targetSdk = 4;
-                            printf("sdkVersion:'%s'\n", name.string());
-                        } else if (code != -1) {
-                            targetSdk = code;
-                            printf("sdkVersion:'%d'\n", code);
-                        }
-                        code = getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1);
-                        if (code != -1) {
-                            printf("maxSdkVersion:'%d'\n", code);
-                        }
-                        code = getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error);
-                        if (error != "") {
-                            error = "";
-                            String8 name = getResolvedAttribute(&res, tree, TARGET_SDK_VERSION_ATTR, &error);
-                            if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:targetSdkVersion' attribute: %s\n",
-                                        error.string());
-                                goto bail;
-                            }
-                            if (name == "Donut" && targetSdk < 4) targetSdk = 4;
-                            printf("targetSdkVersion:'%s'\n", name.string());
-                        } else if (code != -1) {
-                            if (targetSdk < code) {
-                                targetSdk = code;
-                            }
-                            printf("targetSdkVersion:'%d'\n", code);
-                        }
-                    } else if (tag == "uses-configuration") {
-                        int32_t reqTouchScreen = getIntegerAttribute(tree,
-                                REQ_TOUCH_SCREEN_ATTR, NULL, 0);
-                        int32_t reqKeyboardType = getIntegerAttribute(tree,
-                                REQ_KEYBOARD_TYPE_ATTR, NULL, 0);
-                        int32_t reqHardKeyboard = getIntegerAttribute(tree,
-                                REQ_HARD_KEYBOARD_ATTR, NULL, 0);
-                        int32_t reqNavigation = getIntegerAttribute(tree,
-                                REQ_NAVIGATION_ATTR, NULL, 0);
-                        int32_t reqFiveWayNav = getIntegerAttribute(tree,
-                                REQ_FIVE_WAY_NAV_ATTR, NULL, 0);
-                        printf("uses-configuration:");
-                        if (reqTouchScreen != 0) {
-                            printf(" reqTouchScreen='%d'", reqTouchScreen);
-                        }
-                        if (reqKeyboardType != 0) {
-                            printf(" reqKeyboardType='%d'", reqKeyboardType);
-                        }
-                        if (reqHardKeyboard != 0) {
-                            printf(" reqHardKeyboard='%d'", reqHardKeyboard);
-                        }
-                        if (reqNavigation != 0) {
-                            printf(" reqNavigation='%d'", reqNavigation);
-                        }
-                        if (reqFiveWayNav != 0) {
-                            printf(" reqFiveWayNav='%d'", reqFiveWayNav);
-                        }
-                        printf("\n");
-                    } else if (tag == "supports-input") {
-                        withinSupportsInput = true;
-                    } else if (tag == "supports-screens") {
-                        smallScreen = getIntegerAttribute(tree,
-                                SMALL_SCREEN_ATTR, NULL, 1);
-                        normalScreen = getIntegerAttribute(tree,
-                                NORMAL_SCREEN_ATTR, NULL, 1);
-                        largeScreen = getIntegerAttribute(tree,
-                                LARGE_SCREEN_ATTR, NULL, 1);
-                        xlargeScreen = getIntegerAttribute(tree,
-                                XLARGE_SCREEN_ATTR, NULL, 1);
-                        anyDensity = getIntegerAttribute(tree,
-                                ANY_DENSITY_ATTR, NULL, 1);
-                        requiresSmallestWidthDp = getIntegerAttribute(tree,
-                                REQUIRES_SMALLEST_WIDTH_DP_ATTR, NULL, 0);
-                        compatibleWidthLimitDp = getIntegerAttribute(tree,
-                                COMPATIBLE_WIDTH_LIMIT_DP_ATTR, NULL, 0);
-                        largestWidthLimitDp = getIntegerAttribute(tree,
-                                LARGEST_WIDTH_LIMIT_DP_ATTR, NULL, 0);
-                    } else if (tag == "uses-feature") {
-                        String8 name = getAttribute(tree, NAME_ATTR, &error);
-
-                        if (name != "" && error == "") {
-                            int req = getIntegerAttribute(tree,
-                                    REQUIRED_ATTR, NULL, 1);
-
-                            if (name == "android.hardware.camera") {
-                                specCameraFeature = true;
-                            } else if (name == "android.hardware.camera.autofocus") {
-                                // these have no corresponding permission to check for,
-                                // but should imply the foundational camera permission
-                                reqCameraAutofocusFeature = reqCameraAutofocusFeature || req;
-                                specCameraAutofocusFeature = true;
-                            } else if (req && (name == "android.hardware.camera.flash")) {
-                                // these have no corresponding permission to check for,
-                                // but should imply the foundational camera permission
-                                reqCameraFlashFeature = true;
-                            } else if (name == "android.hardware.location") {
-                                specLocationFeature = true;
-                            } else if (name == "android.hardware.location.network") {
-                                specNetworkLocFeature = true;
-                                reqNetworkLocFeature = reqNetworkLocFeature || req;
-                            } else if (name == "android.hardware.location.gps") {
-                                specGpsFeature = true;
-                                reqGpsFeature = reqGpsFeature || req;
-                            } else if (name == "android.hardware.bluetooth") {
-                                specBluetoothFeature = true;
-                            } else if (name == "android.hardware.touchscreen") {
-                                specTouchscreenFeature = true;
-                            } else if (name == "android.hardware.touchscreen.multitouch") {
-                                specMultitouchFeature = true;
-                            } else if (name == "android.hardware.touchscreen.multitouch.distinct") {
-                                reqDistinctMultitouchFeature = reqDistinctMultitouchFeature || req;
-                            } else if (name == "android.hardware.microphone") {
-                                specMicrophoneFeature = true;
-                            } else if (name == "android.hardware.wifi") {
-                                specWiFiFeature = true;
-                            } else if (name == "android.hardware.telephony") {
-                                specTelephonyFeature = true;
-                            } else if (req && (name == "android.hardware.telephony.gsm" ||
-                                               name == "android.hardware.telephony.cdma")) {
-                                // these have no corresponding permission to check for,
-                                // but should imply the foundational telephony permission
-                                reqTelephonySubFeature = true;
-                            } else if (name == "android.hardware.screen.portrait") {
-                                specScreenPortraitFeature = true;
-                            } else if (name == "android.hardware.screen.landscape") {
-                                specScreenLandscapeFeature = true;
-                            }
-                            printf("uses-feature%s:'%s'\n",
-                                    req ? "" : "-not-required", name.string());
-                        } else {
-                            int vers = getIntegerAttribute(tree,
-                                    GL_ES_VERSION_ATTR, &error);
-                            if (error == "") {
-                                printf("uses-gl-es:'0x%x'\n", vers);
-                            }
-                        }
-                    } else if (tag == "uses-permission") {
-                        String8 name = getAttribute(tree, NAME_ATTR, &error);
-                        if (name != "" && error == "") {
-                            if (name == "android.permission.CAMERA") {
-                                hasCameraPermission = true;
-                            } else if (name == "android.permission.ACCESS_FINE_LOCATION") {
-                                hasGpsPermission = true;
-                            } else if (name == "android.permission.ACCESS_MOCK_LOCATION") {
-                                hasMockLocPermission = true;
-                            } else if (name == "android.permission.ACCESS_COARSE_LOCATION") {
-                                hasCoarseLocPermission = true;
-                            } else if (name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" ||
-                                       name == "android.permission.INSTALL_LOCATION_PROVIDER") {
-                                hasGeneralLocPermission = true;
-                            } else if (name == "android.permission.BLUETOOTH" ||
-                                       name == "android.permission.BLUETOOTH_ADMIN") {
-                                hasBluetoothPermission = true;
-                            } else if (name == "android.permission.RECORD_AUDIO") {
-                                hasRecordAudioPermission = true;
-                            } else if (name == "android.permission.ACCESS_WIFI_STATE" ||
-                                       name == "android.permission.CHANGE_WIFI_STATE" ||
-                                       name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") {
-                                hasWiFiPermission = true;
-                            } else if (name == "android.permission.CALL_PHONE" ||
-                                       name == "android.permission.CALL_PRIVILEGED" ||
-                                       name == "android.permission.MODIFY_PHONE_STATE" ||
-                                       name == "android.permission.PROCESS_OUTGOING_CALLS" ||
-                                       name == "android.permission.READ_SMS" ||
-                                       name == "android.permission.RECEIVE_SMS" ||
-                                       name == "android.permission.RECEIVE_MMS" ||
-                                       name == "android.permission.RECEIVE_WAP_PUSH" ||
-                                       name == "android.permission.SEND_SMS" ||
-                                       name == "android.permission.WRITE_APN_SETTINGS" ||
-                                       name == "android.permission.WRITE_SMS") {
-                                hasTelephonyPermission = true;
-                            } else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") {
-                                hasWriteExternalStoragePermission = true;
-                            } else if (name == "android.permission.READ_EXTERNAL_STORAGE") {
-                                hasReadExternalStoragePermission = true;
-                            } else if (name == "android.permission.READ_PHONE_STATE") {
-                                hasReadPhoneStatePermission = true;
-                            } else if (name == "android.permission.READ_CONTACTS") {
-                                hasReadContactsPermission = true;
-                            } else if (name == "android.permission.WRITE_CONTACTS") {
-                                hasWriteContactsPermission = true;
-                            } else if (name == "android.permission.READ_CALL_LOG") {
-                                hasReadCallLogPermission = true;
-                            } else if (name == "android.permission.WRITE_CALL_LOG") {
-                                hasWriteCallLogPermission = true;
-                            }
-                            printf("uses-permission:'%s'\n", name.string());
-                            int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1);
-                            if (!req) {
-                                printf("optional-permission:'%s'\n", name.string());
-                            }
-                        } else {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
-                                    error.string());
-                            goto bail;
-                        }
-                    } else if (tag == "uses-package") {
-                        String8 name = getAttribute(tree, NAME_ATTR, &error);
-                        if (name != "" && error == "") {
-                            printf("uses-package:'%s'\n", name.string());
-                        } else {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
-                                    error.string());
-                                goto bail;
-                        }
-                    } else if (tag == "original-package") {
-                        String8 name = getAttribute(tree, NAME_ATTR, &error);
-                        if (name != "" && error == "") {
-                            printf("original-package:'%s'\n", name.string());
-                        } else {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
-                                    error.string());
-                                goto bail;
-                        }
-                    } else if (tag == "supports-gl-texture") {
-                        String8 name = getAttribute(tree, NAME_ATTR, &error);
-                        if (name != "" && error == "") {
-                            printf("supports-gl-texture:'%s'\n", name.string());
-                        } else {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
-                                    error.string());
-                                goto bail;
-                        }
-                    } else if (tag == "compatible-screens") {
-                        printCompatibleScreens(tree);
-                        depth--;
-                    } else if (tag == "package-verifier") {
-                        String8 name = getAttribute(tree, NAME_ATTR, &error);
-                        if (name != "" && error == "") {
-                            String8 publicKey = getAttribute(tree, PUBLIC_KEY_ATTR, &error);
-                            if (publicKey != "" && error == "") {
-                                printf("package-verifier: name='%s' publicKey='%s'\n",
-                                        name.string(), publicKey.string());
-                            }
-                        }
-                    }
-                } else if (depth == 3) {
-                    withinActivity = false;
-                    withinReceiver = false;
-                    withinService = false;
-                    hasIntentFilter = false;
-                    hasMetaHostPaymentCategory = false;
-                    hasMetaOffHostPaymentCategory = false;
-                    hasBindDeviceAdminPermission = false;
-                    hasBindInputMethodPermission = false;
-                    hasBindAccessibilityServicePermission = false;
-                    hasBindPrintServicePermission = false;
-                    hasBindNfcServicePermission = false;
-                    if (withinApplication) {
-                        if(tag == "activity") {
-                            withinActivity = true;
-                            activityName = getAttribute(tree, NAME_ATTR, &error);
-                            if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
-                                        error.string());
-                                goto bail;
-                            }
-
-                            activityLabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error);
-                            if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n",
-                                        error.string());
-                                goto bail;
-                            }
-
-                            activityIcon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
-                            if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n",
-                                        error.string());
-                                goto bail;
-                            }
-
-                            int32_t orien = getResolvedIntegerAttribute(&res, tree,
-                                    SCREEN_ORIENTATION_ATTR, &error);
-                            if (error == "") {
-                                if (orien == 0 || orien == 6 || orien == 8) {
-                                    // Requests landscape, sensorLandscape, or reverseLandscape.
-                                    reqScreenLandscapeFeature = true;
-                                } else if (orien == 1 || orien == 7 || orien == 9) {
-                                    // Requests portrait, sensorPortrait, or reversePortrait.
-                                    reqScreenPortraitFeature = true;
-                                }
-                            }
-                        } else if (tag == "uses-library") {
-                            String8 libraryName = getAttribute(tree, NAME_ATTR, &error);
-                            if (error != "") {
-                                fprintf(stderr,
-                                        "ERROR getting 'android:name' attribute for uses-library"
-                                        " %s\n", error.string());
-                                goto bail;
-                            }
-                            int req = getIntegerAttribute(tree,
-                                    REQUIRED_ATTR, NULL, 1);
-                            printf("uses-library%s:'%s'\n",
-                                    req ? "" : "-not-required", libraryName.string());
-                        } else if (tag == "receiver") {
-                            withinReceiver = true;
-                            receiverName = getAttribute(tree, NAME_ATTR, &error);
-
-                            if (error != "") {
-                                fprintf(stderr,
-                                        "ERROR getting 'android:name' attribute for receiver:"
-                                        " %s\n", error.string());
-                                goto bail;
-                            }
-
-                            String8 permission = getAttribute(tree, PERMISSION_ATTR, &error);
-                            if (error == "") {
-                                if (permission == "android.permission.BIND_DEVICE_ADMIN") {
-                                    hasBindDeviceAdminPermission = true;
-                                }
-                            } else {
-                                fprintf(stderr, "ERROR getting 'android:permission' attribute for"
-                                        " receiver '%s': %s\n", receiverName.string(), error.string());
-                            }
-                        } else if (tag == "service") {
-                            withinService = true;
-                            serviceName = getAttribute(tree, NAME_ATTR, &error);
-
-                            if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:name' attribute for"
-                                        " service: %s\n", error.string());
-                                goto bail;
-                            }
-
-                            String8 permission = getAttribute(tree, PERMISSION_ATTR, &error);
-                            if (error == "") {
-                                if (permission == "android.permission.BIND_INPUT_METHOD") {
-                                    hasBindInputMethodPermission = true;
-                                } else if (permission == "android.permission.BIND_ACCESSIBILITY_SERVICE") {
-                                    hasBindAccessibilityServicePermission = true;
-                                } else if (permission == "android.permission.BIND_PRINT_SERVICE") {
-                                    hasBindPrintServicePermission = true;
-                                } else if (permission == "android.permission.BIND_NFC_SERVICE") {
-                                    hasBindNfcServicePermission = true;
-                                }
-                            } else {
-                                fprintf(stderr, "ERROR getting 'android:permission' attribute for"
-                                        " service '%s': %s\n", serviceName.string(), error.string());
-                            }
-                        }
-                    } else if (withinSupportsInput && tag == "input-type") {
-                        String8 name = getAttribute(tree, NAME_ATTR, &error);
-                        if (name != "" && error == "") {
-                            supportedInput.add(name);
-                        } else {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
-                                    error.string());
-                            goto bail;
-                        }
-                    }
-                } else if (depth == 4) {
-                    if (tag == "intent-filter") {
-                        hasIntentFilter = true;
-                        withinIntentFilter = true;
-                        actMainActivity = false;
-                        actWidgetReceivers = false;
-                        actImeService = false;
-                        actWallpaperService = false;
-                        actAccessibilityService = false;
-                        actPrintService = false;
-                        actDeviceAdminEnabled = false;
-                        actHostApduService = false;
-                        actOffHostApduService = false;
-                    } else if (withinService && tag == "meta-data") {
-                        String8 name = getAttribute(tree, NAME_ATTR, &error);
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute for"
-                                    " meta-data tag in service '%s': %s\n", serviceName.string(), error.string());
-                            goto bail;
-                        }
-
-                        if (name == "android.nfc.cardemulation.host_apdu_service" ||
-                                name == "android.nfc.cardemulation.off_host_apdu_service") {
-                            bool offHost = true;
-                            if (name == "android.nfc.cardemulation.host_apdu_service") {
-                                offHost = false;
-                            }
-
-                            String8 xmlPath = getResolvedAttribute(&res, tree, RESOURCE_ATTR, &error);
-                            if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:resource' attribute for"
-                                        " meta-data tag in service '%s': %s\n", serviceName.string(), error.string());
-                                goto bail;
-                            }
-
-                            Vector<String8> categories = getNfcAidCategories(assets, xmlPath,
-                                    offHost, &error);
-                            if (error != "") {
-                                fprintf(stderr, "ERROR getting AID category for service '%s'\n",
-                                        serviceName.string());
-                                goto bail;
-                            }
-
-                            const size_t catLen = categories.size();
-                            for (size_t i = 0; i < catLen; i++) {
-                                bool paymentCategory = (categories[i] == "payment");
-                                if (offHost) {
-                                    hasMetaOffHostPaymentCategory |= paymentCategory;
-                                } else {
-                                    hasMetaHostPaymentCategory |= paymentCategory;
-                                }
-                            }
-                        }
-                    }
-                } else if ((depth == 5) && withinIntentFilter){
-                    String8 action;
-                    if (tag == "action") {
-                        action = getAttribute(tree, NAME_ATTR, &error);
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string());
-                            goto bail;
-                        }
-                        if (withinActivity) {
-                            if (action == "android.intent.action.MAIN") {
-                                isMainActivity = true;
-                                actMainActivity = true;
-                            }
-                        } else if (withinReceiver) {
-                            if (action == "android.appwidget.action.APPWIDGET_UPDATE") {
-                                actWidgetReceivers = true;
-                            } else if (action == "android.app.action.DEVICE_ADMIN_ENABLED") {
-                                actDeviceAdminEnabled = true;
-                            }
-                        } else if (withinService) {
-                            if (action == "android.view.InputMethod") {
-                                actImeService = true;
-                            } else if (action == "android.service.wallpaper.WallpaperService") {
-                                actWallpaperService = true;
-                            } else if (action == "android.accessibilityservice.AccessibilityService") {
-                                actAccessibilityService = true;
-                            } else if (action == "android.printservice.PrintService") {
-                                actPrintService = true;
-                            } else if (action == "android.nfc.cardemulation.action.HOST_APDU_SERVICE") {
-                                actHostApduService = true;
-                            } else if (action == "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE") {
-                                actOffHostApduService = true;
-                            }
-                        }
-                        if (action == "android.intent.action.SEARCH") {
-                            isSearchable = true;
-                        }
-                    }
-
-                    if (tag == "category") {
-                        String8 category = getAttribute(tree, NAME_ATTR, &error);
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'name' attribute: %s\n", error.string());
-                            goto bail;
-                        }
-                        if (withinActivity) {
-                            if (category == "android.intent.category.LAUNCHER") {
-                                isLauncherActivity = true;
-                            }
-                        }
-                    }
-                }
-            }
-
-            // Pre-1.6 implicitly granted permission compatibility logic
-            if (targetSdk < 4) {
-                if (!hasWriteExternalStoragePermission) {
-                    printf("uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'\n");
-                    printf("uses-implied-permission:'android.permission.WRITE_EXTERNAL_STORAGE'," \
-                            "'targetSdkVersion < 4'\n");
-                    hasWriteExternalStoragePermission = true;
-                }
-                if (!hasReadPhoneStatePermission) {
-                    printf("uses-permission:'android.permission.READ_PHONE_STATE'\n");
-                    printf("uses-implied-permission:'android.permission.READ_PHONE_STATE'," \
-                            "'targetSdkVersion < 4'\n");
-                }
-            }
-
-            // If the application has requested WRITE_EXTERNAL_STORAGE, we will
-            // force them to always take READ_EXTERNAL_STORAGE as well.  We always
-            // do this (regardless of target API version) because we can't have
-            // an app with write permission but not read permission.
-            if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) {
-                printf("uses-permission:'android.permission.READ_EXTERNAL_STORAGE'\n");
-                printf("uses-implied-permission:'android.permission.READ_EXTERNAL_STORAGE'," \
-                        "'requested WRITE_EXTERNAL_STORAGE'\n");
-            }
-
-            // Pre-JellyBean call log permission compatibility.
-            if (targetSdk < 16) {
-                if (!hasReadCallLogPermission && hasReadContactsPermission) {
-                    printf("uses-permission:'android.permission.READ_CALL_LOG'\n");
-                    printf("uses-implied-permission:'android.permission.READ_CALL_LOG'," \
-                            "'targetSdkVersion < 16 and requested READ_CONTACTS'\n");
-                }
-                if (!hasWriteCallLogPermission && hasWriteContactsPermission) {
-                    printf("uses-permission:'android.permission.WRITE_CALL_LOG'\n");
-                    printf("uses-implied-permission:'android.permission.WRITE_CALL_LOG'," \
-                            "'targetSdkVersion < 16 and requested WRITE_CONTACTS'\n");
-                }
-            }
-
-            /* The following blocks handle printing "inferred" uses-features, based
-             * on whether related features or permissions are used by the app.
-             * Note that the various spec*Feature variables denote whether the
-             * relevant tag was *present* in the AndroidManfest, not that it was
-             * present and set to true.
-             */
-            // Camera-related back-compatibility logic
-            if (!specCameraFeature) {
-                if (reqCameraFlashFeature) {
-                    // if app requested a sub-feature (autofocus or flash) and didn't
-                    // request the base camera feature, we infer that it meant to
-                    printf("uses-feature:'android.hardware.camera'\n");
-                    printf("uses-implied-feature:'android.hardware.camera'," \
-                            "'requested android.hardware.camera.flash feature'\n");
-                } else if (reqCameraAutofocusFeature) {
-                    // if app requested a sub-feature (autofocus or flash) and didn't
-                    // request the base camera feature, we infer that it meant to
-                    printf("uses-feature:'android.hardware.camera'\n");
-                    printf("uses-implied-feature:'android.hardware.camera'," \
-                            "'requested android.hardware.camera.autofocus feature'\n");
-                } else if (hasCameraPermission) {
-                    // if app wants to use camera but didn't request the feature, we infer 
-                    // that it meant to, and further that it wants autofocus
-                    // (which was the 1.0 - 1.5 behavior)
-                    printf("uses-feature:'android.hardware.camera'\n");
-                    if (!specCameraAutofocusFeature) {
-                        printf("uses-feature:'android.hardware.camera.autofocus'\n");
-                        printf("uses-implied-feature:'android.hardware.camera.autofocus'," \
-                                "'requested android.permission.CAMERA permission'\n");
-                    }
-                }
-            }
-
-            // Location-related back-compatibility logic
-            if (!specLocationFeature &&
-                (hasMockLocPermission || hasCoarseLocPermission || hasGpsPermission ||
-                 hasGeneralLocPermission || reqNetworkLocFeature || reqGpsFeature)) {
-                // if app either takes a location-related permission or requests one of the
-                // sub-features, we infer that it also meant to request the base location feature
-                printf("uses-feature:'android.hardware.location'\n");
-                printf("uses-implied-feature:'android.hardware.location'," \
-                        "'requested a location access permission'\n");
-            }
-            if (!specGpsFeature && hasGpsPermission) {
-                // if app takes GPS (FINE location) perm but does not request the GPS
-                // feature, we infer that it meant to
-                printf("uses-feature:'android.hardware.location.gps'\n");
-                printf("uses-implied-feature:'android.hardware.location.gps'," \
-                        "'requested android.permission.ACCESS_FINE_LOCATION permission'\n");
-            }
-            if (!specNetworkLocFeature && hasCoarseLocPermission) {
-                // if app takes Network location (COARSE location) perm but does not request the
-                // network location feature, we infer that it meant to
-                printf("uses-feature:'android.hardware.location.network'\n");
-                printf("uses-implied-feature:'android.hardware.location.network'," \
-                        "'requested android.permission.ACCESS_COARSE_LOCATION permission'\n");
-            }
-
-            // Bluetooth-related compatibility logic
-            if (!specBluetoothFeature && hasBluetoothPermission && (targetSdk > 4)) {
-                // if app takes a Bluetooth permission but does not request the Bluetooth
-                // feature, we infer that it meant to
-                printf("uses-feature:'android.hardware.bluetooth'\n");
-                printf("uses-implied-feature:'android.hardware.bluetooth'," \
-                        "'requested android.permission.BLUETOOTH or android.permission.BLUETOOTH_ADMIN " \
-                        "permission and targetSdkVersion > 4'\n");
-            }
-
-            // Microphone-related compatibility logic
-            if (!specMicrophoneFeature && hasRecordAudioPermission) {
-                // if app takes the record-audio permission but does not request the microphone
-                // feature, we infer that it meant to
-                printf("uses-feature:'android.hardware.microphone'\n");
-                printf("uses-implied-feature:'android.hardware.microphone'," \
-                        "'requested android.permission.RECORD_AUDIO permission'\n");
-            }
-
-            // WiFi-related compatibility logic
-            if (!specWiFiFeature && hasWiFiPermission) {
-                // if app takes one of the WiFi permissions but does not request the WiFi
-                // feature, we infer that it meant to
-                printf("uses-feature:'android.hardware.wifi'\n");
-                printf("uses-implied-feature:'android.hardware.wifi'," \
-                        "'requested android.permission.ACCESS_WIFI_STATE, " \
-                        "android.permission.CHANGE_WIFI_STATE, or " \
-                        "android.permission.CHANGE_WIFI_MULTICAST_STATE permission'\n");
-            }
-
-            // Telephony-related compatibility logic
-            if (!specTelephonyFeature && (hasTelephonyPermission || reqTelephonySubFeature)) {
-                // if app takes one of the telephony permissions or requests a sub-feature but
-                // does not request the base telephony feature, we infer that it meant to
-                printf("uses-feature:'android.hardware.telephony'\n");
-                printf("uses-implied-feature:'android.hardware.telephony'," \
-                        "'requested a telephony-related permission or feature'\n");
-            }
-
-            // Touchscreen-related back-compatibility logic
-            if (!specTouchscreenFeature) { // not a typo!
-                // all apps are presumed to require a touchscreen, unless they explicitly say
-                // <uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
-                // Note that specTouchscreenFeature is true if the tag is present, regardless
-                // of whether its value is true or false, so this is safe
-                printf("uses-feature:'android.hardware.touchscreen'\n");
-                printf("uses-implied-feature:'android.hardware.touchscreen'," \
-                        "'assumed you require a touch screen unless explicitly made optional'\n");
-            }
-            if (!specMultitouchFeature && reqDistinctMultitouchFeature) {
-                // if app takes one of the telephony permissions or requests a sub-feature but
-                // does not request the base telephony feature, we infer that it meant to
-                printf("uses-feature:'android.hardware.touchscreen.multitouch'\n");
-                printf("uses-implied-feature:'android.hardware.touchscreen.multitouch'," \
-                        "'requested android.hardware.touchscreen.multitouch.distinct feature'\n");
-            }
-
-            // Landscape/portrait-related compatibility logic
-            if (!specScreenLandscapeFeature && !specScreenPortraitFeature) {
-                // If the app has specified any activities in its manifest
-                // that request a specific orientation, then assume that
-                // orientation is required.
-                if (reqScreenLandscapeFeature) {
-                    printf("uses-feature:'android.hardware.screen.landscape'\n");
-                    printf("uses-implied-feature:'android.hardware.screen.landscape'," \
-                            "'one or more activities have specified a landscape orientation'\n");
-                }
-                if (reqScreenPortraitFeature) {
-                    printf("uses-feature:'android.hardware.screen.portrait'\n");
-                    printf("uses-implied-feature:'android.hardware.screen.portrait'," \
-                            "'one or more activities have specified a portrait orientation'\n");
-                }
-            }
-
-            if (hasMainActivity) {
-                printf("main\n");
-            }
-            if (hasWidgetReceivers) {
-                printf("app-widget\n");
-            }
-            if (hasDeviceAdminReceiver) {
-                printf("device-admin\n");
-            }
-            if (hasImeService) {
-                printf("ime\n");
-            }
-            if (hasWallpaperService) {
-                printf("wallpaper\n");
-            }
-            if (hasAccessibilityService) {
-                printf("accessibility\n");
-            }
-            if (hasPrintService) {
-                printf("print\n");
-            }
-            if (hasPaymentService) {
-                printf("payment\n");
-            }
-            if (hasOtherActivities) {
-                printf("other-activities\n");
-            }
-            if (isSearchable) {
-                printf("search\n");
-            }
-            if (hasOtherReceivers) {
-                printf("other-receivers\n");
-            }
-            if (hasOtherServices) {
-                printf("other-services\n");
-            }
-
-            // For modern apps, if screen size buckets haven't been specified
-            // but the new width ranges have, then infer the buckets from them.
-            if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0
-                    && requiresSmallestWidthDp > 0) {
-                int compatWidth = compatibleWidthLimitDp;
-                if (compatWidth <= 0) compatWidth = requiresSmallestWidthDp;
-                if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) {
-                    smallScreen = -1;
-                } else {
-                    smallScreen = 0;
-                }
-                if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) {
-                    normalScreen = -1;
-                } else {
-                    normalScreen = 0;
-                }
-                if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) {
-                    largeScreen = -1;
-                } else {
-                    largeScreen = 0;
-                }
-                if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) {
-                    xlargeScreen = -1;
-                } else {
-                    xlargeScreen = 0;
-                }
-            }
-
-            // Determine default values for any unspecified screen sizes,
-            // based on the target SDK of the package.  As of 4 (donut)
-            // the screen size support was introduced, so all default to
-            // enabled.
-            if (smallScreen > 0) {
-                smallScreen = targetSdk >= 4 ? -1 : 0;
-            }
-            if (normalScreen > 0) {
-                normalScreen = -1;
-            }
-            if (largeScreen > 0) {
-                largeScreen = targetSdk >= 4 ? -1 : 0;
-            }
-            if (xlargeScreen > 0) {
-                // Introduced in Gingerbread.
-                xlargeScreen = targetSdk >= 9 ? -1 : 0;
-            }
-            if (anyDensity > 0) {
-                anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0
-                        || compatibleWidthLimitDp > 0) ? -1 : 0;
-            }
-            printf("supports-screens:");
-            if (smallScreen != 0) printf(" 'small'");
-            if (normalScreen != 0) printf(" 'normal'");
-            if (largeScreen != 0) printf(" 'large'");
-            if (xlargeScreen != 0) printf(" 'xlarge'");
-            printf("\n");
-            printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false");
-            if (requiresSmallestWidthDp > 0) {
-                printf("requires-smallest-width:'%d'\n", requiresSmallestWidthDp);
-            }
-            if (compatibleWidthLimitDp > 0) {
-                printf("compatible-width-limit:'%d'\n", compatibleWidthLimitDp);
-            }
-            if (largestWidthLimitDp > 0) {
-                printf("largest-width-limit:'%d'\n", largestWidthLimitDp);
-            }
-
-            printf("locales:");
-            const size_t NL = locales.size();
-            for (size_t i=0; i<NL; i++) {
-                const char* localeStr =  locales[i].string();
-                if (localeStr == NULL || strlen(localeStr) == 0) {
-                    localeStr = "--_--";
-                }
-                printf(" '%s'", localeStr);
-            }
-            printf("\n");
-
-            printf("densities:");
-            const size_t ND = densities.size();
-            for (size_t i=0; i<ND; i++) {
-                printf(" '%d'", densities[i]);
-            }
-            printf("\n");
-
-            AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib");
-            if (dir != NULL) {
-                if (dir->getFileCount() > 0) {
-                    printf("native-code:");
-                    for (size_t i=0; i<dir->getFileCount(); i++) {
-                        printf(" '%s'", dir->getFileName(i).string());
-                    }
-                    printf("\n");
-                }
-                delete dir;
-            }
-        } else if (strcmp("badger", option) == 0) {
-            printf("%s", CONSOLE_DATA);
-        } else if (strcmp("configurations", option) == 0) {
-            Vector<ResTable_config> configs;
-            res.getConfigurations(&configs);
-            const size_t N = configs.size();
-            for (size_t i=0; i<N; i++) {
-                printf("%s\n", configs[i].toString().string());
-            }
-        } else {
-            fprintf(stderr, "ERROR: unknown dump option '%s'\n", option);
-            goto bail;
-        }
-    }
-
-    result = NO_ERROR;
-
-bail:
-    if (asset) {
-        delete asset;
-    }
-    return (result != NO_ERROR);
-}
-
-
-/*
- * Handle the "add" command, which wants to add files to a new or
- * pre-existing archive.
- */
-int doAdd(Bundle* bundle)
-{
-    ZipFile* zip = NULL;
-    status_t result = UNKNOWN_ERROR;
-    const char* zipFileName;
-
-    if (bundle->getUpdate()) {
-        /* avoid confusion */
-        fprintf(stderr, "ERROR: can't use '-u' with add\n");
-        goto bail;
-    }
-
-    if (bundle->getFileSpecCount() < 1) {
-        fprintf(stderr, "ERROR: must specify zip file name\n");
-        goto bail;
-    }
-    zipFileName = bundle->getFileSpecEntry(0);
-
-    if (bundle->getFileSpecCount() < 2) {
-        fprintf(stderr, "NOTE: nothing to do\n");
-        goto bail;
-    }
-
-    zip = openReadWrite(zipFileName, true);
-    if (zip == NULL) {
-        fprintf(stderr, "ERROR: failed opening/creating '%s' as Zip file\n", zipFileName);
-        goto bail;
-    }
-
-    for (int i = 1; i < bundle->getFileSpecCount(); i++) {
-        const char* fileName = bundle->getFileSpecEntry(i);
-
-        if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) {
-            printf(" '%s'... (from gzip)\n", fileName);
-            result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL);
-        } else {
-            if (bundle->getJunkPath()) {
-                String8 storageName = String8(fileName).getPathLeaf();
-                printf(" '%s' as '%s'...\n", fileName, storageName.string());
-                result = zip->add(fileName, storageName.string(),
-                                  bundle->getCompressionMethod(), NULL);
-            } else {
-                printf(" '%s'...\n", fileName);
-                result = zip->add(fileName, bundle->getCompressionMethod(), NULL);
-            }
-        }
-        if (result != NO_ERROR) {
-            fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName);
-            if (result == NAME_NOT_FOUND)
-                fprintf(stderr, ": file not found\n");
-            else if (result == ALREADY_EXISTS)
-                fprintf(stderr, ": already exists in archive\n");
-            else
-                fprintf(stderr, "\n");
-            goto bail;
-        }
-    }
-
-    result = NO_ERROR;
-
-bail:
-    delete zip;
-    return (result != NO_ERROR);
-}
-
-
-/*
- * Delete files from an existing archive.
- */
-int doRemove(Bundle* bundle)
-{
-    ZipFile* zip = NULL;
-    status_t result = UNKNOWN_ERROR;
-    const char* zipFileName;
-
-    if (bundle->getFileSpecCount() < 1) {
-        fprintf(stderr, "ERROR: must specify zip file name\n");
-        goto bail;
-    }
-    zipFileName = bundle->getFileSpecEntry(0);
-
-    if (bundle->getFileSpecCount() < 2) {
-        fprintf(stderr, "NOTE: nothing to do\n");
-        goto bail;
-    }
-
-    zip = openReadWrite(zipFileName, false);
-    if (zip == NULL) {
-        fprintf(stderr, "ERROR: failed opening Zip archive '%s'\n",
-            zipFileName);
-        goto bail;
-    }
-
-    for (int i = 1; i < bundle->getFileSpecCount(); i++) {
-        const char* fileName = bundle->getFileSpecEntry(i);
-        ZipEntry* entry;
-
-        entry = zip->getEntryByName(fileName);
-        if (entry == NULL) {
-            printf(" '%s' NOT FOUND\n", fileName);
-            continue;
-        }
-
-        result = zip->remove(entry);
-
-        if (result != NO_ERROR) {
-            fprintf(stderr, "Unable to delete '%s' from '%s'\n",
-                bundle->getFileSpecEntry(i), zipFileName);
-            goto bail;
-        }
-    }
-
-    /* update the archive */
-    zip->flush();
-
-bail:
-    delete zip;
-    return (result != NO_ERROR);
-}
-
-
-/*
- * Package up an asset directory and associated application files.
- */
-int doPackage(Bundle* bundle)
-{
-    const char* outputAPKFile;
-    int retVal = 1;
-    status_t err;
-    sp<AaptAssets> assets;
-    int N;
-    FILE* fp;
-    String8 dependencyFile;
-
-    // -c zz_ZZ means do pseudolocalization
-    ResourceFilter filter;
-    err = filter.parse(bundle->getConfigurations());
-    if (err != NO_ERROR) {
-        goto bail;
-    }
-    if (filter.containsPseudo()) {
-        bundle->setPseudolocalize(true);
-    }
-
-    N = bundle->getFileSpecCount();
-    if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0
-            && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDir() == NULL) {
-        fprintf(stderr, "ERROR: no input files\n");
-        goto bail;
-    }
-
-    outputAPKFile = bundle->getOutputAPKFile();
-
-    // Make sure the filenames provided exist and are of the appropriate type.
-    if (outputAPKFile) {
-        FileType type;
-        type = getFileType(outputAPKFile);
-        if (type != kFileTypeNonexistent && type != kFileTypeRegular) {
-            fprintf(stderr,
-                "ERROR: output file '%s' exists but is not regular file\n",
-                outputAPKFile);
-            goto bail;
-        }
-    }
-
-    // Load the assets.
-    assets = new AaptAssets();
-
-    // Set up the resource gathering in assets if we're going to generate
-    // dependency files. Every time we encounter a resource while slurping
-    // the tree, we'll add it to these stores so we have full resource paths
-    // to write to a dependency file.
-    if (bundle->getGenDependencies()) {
-        sp<FilePathStore> resPathStore = new FilePathStore;
-        assets->setFullResPaths(resPathStore);
-        sp<FilePathStore> assetPathStore = new FilePathStore;
-        assets->setFullAssetPaths(assetPathStore);
-    }
-
-    err = assets->slurpFromArgs(bundle);
-    if (err < 0) {
-        goto bail;
-    }
-
-    if (bundle->getVerbose()) {
-        assets->print(String8());
-    }
-
-    // If they asked for any fileAs that need to be compiled, do so.
-    if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) {
-        err = buildResources(bundle, assets);
-        if (err != 0) {
-            goto bail;
-        }
-    }
-
-    // At this point we've read everything and processed everything.  From here
-    // on out it's just writing output files.
-    if (SourcePos::hasErrors()) {
-        goto bail;
-    }
-
-    // Update symbols with information about which ones are needed as Java symbols.
-    assets->applyJavaSymbols();
-    if (SourcePos::hasErrors()) {
-        goto bail;
-    }
-
-    // If we've been asked to generate a dependency file, do that here
-    if (bundle->getGenDependencies()) {
-        // If this is the packaging step, generate the dependency file next to
-        // the output apk (e.g. bin/resources.ap_.d)
-        if (outputAPKFile) {
-            dependencyFile = String8(outputAPKFile);
-            // Add the .d extension to the dependency file.
-            dependencyFile.append(".d");
-        } else {
-            // Else if this is the R.java dependency generation step,
-            // generate the dependency file in the R.java package subdirectory
-            // e.g. gen/com/foo/app/R.java.d
-            dependencyFile = String8(bundle->getRClassDir());
-            dependencyFile.appendPath("R.java.d");
-        }
-        // Make sure we have a clean dependency file to start with
-        fp = fopen(dependencyFile, "w");
-        fclose(fp);
-    }
-
-    // Write out R.java constants
-    if (!assets->havePrivateSymbols()) {
-        if (bundle->getCustomPackage() == NULL) {
-            // Write the R.java file into the appropriate class directory
-            // e.g. gen/com/foo/app/R.java
-            err = writeResourceSymbols(bundle, assets, assets->getPackage(), true);
-        } else {
-            const String8 customPkg(bundle->getCustomPackage());
-            err = writeResourceSymbols(bundle, assets, customPkg, true);
-        }
-        if (err < 0) {
-            goto bail;
-        }
-        // If we have library files, we're going to write our R.java file into
-        // the appropriate class directory for those libraries as well.
-        // e.g. gen/com/foo/app/lib/R.java
-        if (bundle->getExtraPackages() != NULL) {
-            // Split on colon
-            String8 libs(bundle->getExtraPackages());
-            char* packageString = strtok(libs.lockBuffer(libs.length()), ":");
-            while (packageString != NULL) {
-                // Write the R.java file out with the correct package name
-                err = writeResourceSymbols(bundle, assets, String8(packageString), true);
-                if (err < 0) {
-                    goto bail;
-                }
-                packageString = strtok(NULL, ":");
-            }
-            libs.unlockBuffer();
-        }
-    } else {
-        err = writeResourceSymbols(bundle, assets, assets->getPackage(), false);
-        if (err < 0) {
-            goto bail;
-        }
-        err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true);
-        if (err < 0) {
-            goto bail;
-        }
-    }
-
-    // Write out the ProGuard file
-    err = writeProguardFile(bundle, assets);
-    if (err < 0) {
-        goto bail;
-    }
-
-    // Write the apk
-    if (outputAPKFile) {
-        err = writeAPK(bundle, assets, String8(outputAPKFile));
-        if (err != NO_ERROR) {
-            fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputAPKFile);
-            goto bail;
-        }
-    }
-
-    // If we've been asked to generate a dependency file, we need to finish up here.
-    // the writeResourceSymbols and writeAPK functions have already written the target
-    // half of the dependency file, now we need to write the prerequisites. (files that
-    // the R.java file or .ap_ file depend on)
-    if (bundle->getGenDependencies()) {
-        // Now that writeResourceSymbols or writeAPK has taken care of writing
-        // the targets to our dependency file, we'll write the prereqs
-        fp = fopen(dependencyFile, "a+");
-        fprintf(fp, " : ");
-        bool includeRaw = (outputAPKFile != NULL);
-        err = writeDependencyPreReqs(bundle, assets, fp, includeRaw);
-        // Also manually add the AndroidManifeset since it's not under res/ or assets/
-        // and therefore was not added to our pathstores during slurping
-        fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile());
-        fclose(fp);
-    }
-
-    retVal = 0;
-bail:
-    if (SourcePos::hasErrors()) {
-        SourcePos::printErrors(stderr);
-    }
-    return retVal;
-}
-
-/*
- * Do PNG Crunching
- * PRECONDITIONS
- *  -S flag points to a source directory containing drawable* folders
- *  -C flag points to destination directory. The folder structure in the
- *     source directory will be mirrored to the destination (cache) directory
- *
- * POSTCONDITIONS
- *  Destination directory will be updated to match the PNG files in
- *  the source directory. 
- */
-int doCrunch(Bundle* bundle)
-{
-    fprintf(stdout, "Crunching PNG Files in ");
-    fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]);
-    fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir());
-
-    updatePreProcessedCache(bundle);
-
-    return NO_ERROR;
-}
-
-/*
- * Do PNG Crunching on a single flag
- *  -i points to a single png file
- *  -o points to a single png output file
- */
-int doSingleCrunch(Bundle* bundle)
-{
-    fprintf(stdout, "Crunching single PNG file: %s\n", bundle->getSingleCrunchInputFile());
-    fprintf(stdout, "\tOutput file: %s\n", bundle->getSingleCrunchOutputFile());
-
-    String8 input(bundle->getSingleCrunchInputFile());
-    String8 output(bundle->getSingleCrunchOutputFile());
-
-    if (preProcessImageToCache(bundle, input, output) != NO_ERROR) {
-        // we can't return the status_t as it gets truncate to the lower 8 bits.
-        return 42;
-    }
-
-    return NO_ERROR;
-}
-
-char CONSOLE_DATA[2925] = {
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63,
-    86, 35, 40, 46, 46, 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83,
-    62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 46, 58, 59, 61, 59, 61, 81,
-    81, 81, 81, 66, 96, 61, 61, 58, 46, 46, 46, 58, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81, 81, 81, 102, 59, 61, 59,
-    59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59,
-    59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59, 46, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87,
-    58, 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46,
-    47, 61, 59, 59, 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58,
-    121, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81,
-    81, 81, 81, 109, 58, 59, 59, 59, 59, 61, 109, 81, 81, 76, 46, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81, 81, 81, 81, 81, 59, 61, 59,
-    59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 81, 91, 59,
-    59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81, 81, 76, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81,
-    70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 93, 40, 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81,
-    81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 46, 46, 46, 32, 46, 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109,
-    81, 81, 81, 87, 46, 58, 61, 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
-    32, 32, 32, 32, 32, 32, 32, 46, 46, 61, 59, 61, 61, 61, 59, 61, 61, 59,
-    59, 59, 58, 58, 46, 46, 41, 58, 59, 58, 81, 81, 81, 81, 69, 58, 59, 59,
-    60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 58, 59,
-    61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 46,
-    61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68, 96, 32, 32, 32,
-    46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59,
-    59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36, 81,
-    109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81,
-    67, 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
-    59, 59, 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58,
-    61, 59, 59, 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59,
-    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37,
-    73, 108, 108, 62, 52, 81, 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59,
-    59, 61, 59, 61, 61, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,
-    32, 46, 45, 57, 101, 43, 43, 61, 61, 59, 59, 59, 59, 59, 59, 61, 59, 59,
-    59, 59, 59, 59, 59, 59, 59, 58, 97, 46, 61, 108, 62, 126, 58, 106, 80, 96,
-    46, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61,
-    97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 45, 46, 32,
-    46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 58, 59, 59, 59, 59, 61,
-    119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61, 58, 59, 59, 59,
-    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81, 99, 32, 32,
-    32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119,
-    119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59,
-    59, 59, 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 61, 58, 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81,
-    81, 58, 59, 59, 59, 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41,
-    87, 66, 33, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81,
-    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58,
-    45, 32, 46, 32, 32, 32, 32, 32, 46, 32, 126, 96, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81,
-    81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58,
-    59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58,
-    59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81,
-    81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
-    81, 81, 40, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106,
-    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59,
-    32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 61, 58, 58, 81, 81, 81, 81, 81, 81, 81, 81,
-    81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 59,
-    61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81, 81,
-    81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81,
-    81, 102, 94, 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59,
-    59, 59, 43, 63, 36, 81, 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59,
-    59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 43, 33,
-    58, 126, 126, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46,
-    61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61, 59, 59, 59, 59, 59,
-    59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 58, 95,
-    32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59, 59,
-    61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45,
-    59, 58, 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59,
-    59, 59, 59, 59, 59, 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59,
-    59, 59, 59, 59, 59, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 45, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 58, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 61,
-    46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59,
-    59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59, 59, 59,
-    59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32,
-    32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61,
-    59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59,
-    59, 59, 59, 58, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 61, 59, 58, 45, 45, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10
-  };
diff --git a/tools/aapt/CrunchCache.cpp b/tools/aapt/CrunchCache.cpp
deleted file mode 100644
index c4cf6bc..0000000
--- a/tools/aapt/CrunchCache.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-// Implementation file for CrunchCache
-// This file defines functions laid out and documented in
-// CrunchCache.h
-
-#include <utils/Vector.h>
-#include <utils/String8.h>
-
-#include "DirectoryWalker.h"
-#include "FileFinder.h"
-#include "CacheUpdater.h"
-#include "CrunchCache.h"
-
-using namespace android;
-
-CrunchCache::CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff)
-    : mSourcePath(sourcePath), mDestPath(destPath), mSourceFiles(0), mDestFiles(0), mFileFinder(ff)
-{
-    // We initialize the default value to return to 0 so if a file doesn't exist
-    // then all files are automatically "newer" than it.
-
-    // Set file extensions to look for. Right now just pngs.
-    mExtensions.push(String8(".png"));
-
-    // Load files into our data members
-    loadFiles();
-}
-
-size_t CrunchCache::crunch(CacheUpdater* cu, bool forceOverwrite)
-{
-    size_t numFilesUpdated = 0;
-
-    // Iterate through the source files and compare to cache.
-    // After processing a file, remove it from the source files and
-    // from the dest files.
-    // We're done when we're out of files in source.
-    String8 relativePath;
-    while (mSourceFiles.size() > 0) {
-        // Get the full path to the source file, then convert to a c-string
-        // and offset our beginning pointer to the length of the sourcePath
-        // This efficiently strips the source directory prefix from our path.
-        // Also, String8 doesn't have a substring method so this is what we've
-        // got to work with.
-        const char* rPathPtr = mSourceFiles.keyAt(0).string()+mSourcePath.length();
-        // Strip leading slash if present
-        int offset = 0;
-        if (rPathPtr[0] == OS_PATH_SEPARATOR)
-            offset = 1;
-        relativePath = String8(rPathPtr + offset);
-
-        if (forceOverwrite || needsUpdating(relativePath)) {
-            cu->processImage(mSourcePath.appendPathCopy(relativePath),
-                             mDestPath.appendPathCopy(relativePath));
-            numFilesUpdated++;
-            // crunchFile(relativePath);
-        }
-        // Delete this file from the source files and (if it exists) from the
-        // dest files.
-        mSourceFiles.removeItemsAt(0);
-        mDestFiles.removeItem(mDestPath.appendPathCopy(relativePath));
-    }
-
-    // Iterate through what's left of destFiles and delete leftovers
-    while (mDestFiles.size() > 0) {
-        cu->deleteFile(mDestFiles.keyAt(0));
-        mDestFiles.removeItemsAt(0);
-    }
-
-    // Update our knowledge of the files cache
-    // both source and dest should be empty by now.
-    loadFiles();
-
-    return numFilesUpdated;
-}
-
-void CrunchCache::loadFiles()
-{
-    // Clear out our data structures to avoid putting in duplicates
-    mSourceFiles.clear();
-    mDestFiles.clear();
-
-    // Make a directory walker that points to the system.
-    DirectoryWalker* dw = new SystemDirectoryWalker();
-
-    // Load files in the source directory
-    mFileFinder->findFiles(mSourcePath, mExtensions, mSourceFiles,dw);
-
-    // Load files in the destination directory
-    mFileFinder->findFiles(mDestPath,mExtensions,mDestFiles,dw);
-
-    delete dw;
-}
-
-bool CrunchCache::needsUpdating(String8 relativePath) const
-{
-    // Retrieve modification dates for this file entry under the source and
-    // cache directory trees. The vectors will return a modification date of 0
-    // if the file doesn't exist.
-    time_t sourceDate = mSourceFiles.valueFor(mSourcePath.appendPathCopy(relativePath));
-    time_t destDate = mDestFiles.valueFor(mDestPath.appendPathCopy(relativePath));
-    return sourceDate > destDate;
-}
\ No newline at end of file
diff --git a/tools/aapt/CrunchCache.h b/tools/aapt/CrunchCache.h
deleted file mode 100644
index be3da5c..0000000
--- a/tools/aapt/CrunchCache.h
+++ /dev/null
@@ -1,102 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-// Cache manager for pre-processed PNG files.
-// Contains code for managing which PNG files get processed
-// at build time.
-//
-
-#ifndef CRUNCHCACHE_H
-#define CRUNCHCACHE_H
-
-#include <utils/KeyedVector.h>
-#include <utils/String8.h>
-#include "FileFinder.h"
-#include "CacheUpdater.h"
-
-using namespace android;
-
-/** CrunchCache
- *  This class is a cache manager which can pre-process PNG files and store
- *  them in a mirror-cache. It's capable of doing incremental updates to its
- *  cache.
- *
- *  Usage:
- *      Create an instance initialized with the root of the source tree, the
- *      root location to store the cache files, and an instance of a file finder.
- *      Then update the cache by calling crunch.
- */
-class CrunchCache {
-public:
-    // Constructor
-    CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff);
-
-    // Nobody should be calling the default constructor
-    // So this space is intentionally left blank
-
-    // Default Copy Constructor and Destructor are fine
-
-    /** crunch is the workhorse of this class.
-     * It goes through all the files found in the sourcePath and compares
-     * them to the cached versions in the destPath. If the optional
-     * argument forceOverwrite is set to true, then all source files are
-     * re-crunched even if they have not been modified recently. Otherwise,
-     * source files are only crunched when they needUpdating. Afterwards,
-     * we delete any leftover files in the cache that are no longer present
-     * in source.
-     *
-     * PRECONDITIONS:
-     *      No setup besides construction is needed
-     * POSTCONDITIONS:
-     *      The cache is updated to fully reflect all changes in source.
-     *      The function then returns the number of files changed in cache
-     *      (counting deletions).
-     */
-    size_t crunch(CacheUpdater* cu, bool forceOverwrite=false);
-
-private:
-    /** loadFiles is a wrapper to the FileFinder that places matching
-     * files into mSourceFiles and mDestFiles.
-     *
-     *  POSTCONDITIONS
-     *      mDestFiles and mSourceFiles are refreshed to reflect the current
-     *      state of the files in the source and dest directories.
-     *      Any previous contents of mSourceFiles and mDestFiles are cleared.
-     */
-    void loadFiles();
-
-    /** needsUpdating takes a file path
-     * and returns true if the file represented by this path is newer in the
-     * sourceFiles than in the cache (mDestFiles).
-     *
-     * PRECONDITIONS:
-     *      mSourceFiles and mDestFiles must be initialized and filled.
-     * POSTCONDITIONS:
-     *      returns true if and only if source file's modification time
-     *      is greater than the cached file's mod-time. Otherwise returns false.
-     *
-     * USAGE:
-     *      Should be used something like the following:
-     *      if (needsUpdating(filePath))
-     *          // Recrunch sourceFile out to destFile.
-     *
-     */
-    bool needsUpdating(String8 relativePath) const;
-
-    // DATA MEMBERS ====================================================
-
-    String8 mSourcePath;
-    String8 mDestPath;
-
-    Vector<String8> mExtensions;
-
-    // Each vector of paths contains one entry per PNG file encountered.
-    // Each entry consists of a path pointing to that PNG.
-    DefaultKeyedVector<String8,time_t> mSourceFiles;
-    DefaultKeyedVector<String8,time_t> mDestFiles;
-
-    // Pointer to a FileFinder to use
-    FileFinder* mFileFinder;
-};
-
-#endif // CRUNCHCACHE_H
diff --git a/tools/aapt/DirectoryWalker.h b/tools/aapt/DirectoryWalker.h
deleted file mode 100644
index 88031d0..0000000
--- a/tools/aapt/DirectoryWalker.h
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-// Defines an abstraction for opening a directory on the filesystem and
-// iterating through it.
-
-#ifndef DIRECTORYWALKER_H
-#define DIRECTORYWALKER_H
-
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <utils/String8.h>
-
-#include <stdio.h>
-
-using namespace android;
-
-// Directory Walker
-// This is an abstraction for walking through a directory and getting files
-// and descriptions.
-
-class DirectoryWalker {
-public:
-    virtual ~DirectoryWalker() {};
-    virtual bool openDir(String8 path) = 0;
-    virtual bool openDir(const char* path) = 0;
-    // Advance to next directory entry
-    virtual struct dirent* nextEntry() = 0;
-    // Get the stats for the current entry
-    virtual struct stat*   entryStats() = 0;
-    // Clean Up
-    virtual void closeDir() = 0;
-    // This class is able to replicate itself on the heap
-    virtual DirectoryWalker* clone() = 0;
-
-    // DATA MEMBERS
-    // Current directory entry
-    struct dirent mEntry;
-    // Stats for that directory entry
-    struct stat mStats;
-    // Base path
-    String8 mBasePath;
-};
-
-// System Directory Walker
-// This is an implementation of the above abstraction that calls
-// real system calls and is fully functional.
-// functions are inlined since they're very short and simple
-
-class SystemDirectoryWalker : public DirectoryWalker {
-
-    // Default constructor, copy constructor, and destructor are fine
-public:
-    virtual bool openDir(String8 path) {
-        mBasePath = path;
-        dir = NULL;
-        dir = opendir(mBasePath.string() );
-
-        if (dir == NULL)
-            return false;
-
-        return true;
-    };
-    virtual bool openDir(const char* path) {
-        String8 p(path);
-        openDir(p);
-        return true;
-    };
-    // Advance to next directory entry
-    virtual struct dirent* nextEntry() {
-        struct dirent* entryPtr = readdir(dir);
-        if (entryPtr == NULL)
-            return NULL;
-
-        mEntry = *entryPtr;
-        // Get stats
-        String8 fullPath = mBasePath.appendPathCopy(mEntry.d_name);
-        stat(fullPath.string(),&mStats);
-        return &mEntry;
-    };
-    // Get the stats for the current entry
-    virtual struct stat*   entryStats() {
-        return &mStats;
-    };
-    virtual void closeDir() {
-        closedir(dir);
-    };
-    virtual DirectoryWalker* clone() {
-        return new SystemDirectoryWalker(*this);
-    };
-private:
-    DIR* dir;
-};
-
-#endif // DIRECTORYWALKER_H
diff --git a/tools/aapt/FileFinder.cpp b/tools/aapt/FileFinder.cpp
deleted file mode 100644
index 18775c0..0000000
--- a/tools/aapt/FileFinder.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-
-// File Finder implementation.
-// Implementation for the functions declared and documented in FileFinder.h
-
-#include <utils/Vector.h>
-#include <utils/String8.h>
-#include <utils/KeyedVector.h>
-
-#include <dirent.h>
-#include <sys/stat.h>
-
-#include "DirectoryWalker.h"
-#include "FileFinder.h"
-
-//#define DEBUG
-
-using android::String8;
-
-// Private function to check whether a file is a directory or not
-bool isDirectory(const char* filename) {
-    struct stat fileStat;
-    if (stat(filename, &fileStat) == -1) {
-        return false;
-    }
-    return(S_ISDIR(fileStat.st_mode));
-}
-
-
-// Private function to check whether a file is a regular file or not
-bool isFile(const char* filename) {
-    struct stat fileStat;
-    if (stat(filename, &fileStat) == -1) {
-        return false;
-    }
-    return(S_ISREG(fileStat.st_mode));
-}
-
-bool SystemFileFinder::findFiles(String8 basePath, Vector<String8>& extensions,
-                                 KeyedVector<String8,time_t>& fileStore,
-                                 DirectoryWalker* dw)
-{
-    // Scan the directory pointed to by basePath
-    // check files and recurse into subdirectories.
-    if (!dw->openDir(basePath)) {
-        return false;
-    }
-    /*
-     *  Go through all directory entries. Check each file using checkAndAddFile
-     *  and recurse into sub-directories.
-     */
-    struct dirent* entry;
-    while ((entry = dw->nextEntry()) != NULL) {
-        String8 entryName(entry->d_name);
-        if (entry->d_name[0] == '.') // Skip hidden files and directories
-            continue;
-
-        String8 fullPath = basePath.appendPathCopy(entryName);
-        // If this entry is a directory we'll recurse into it
-        if (isDirectory(fullPath.string()) ) {
-            DirectoryWalker* copy = dw->clone();
-            findFiles(fullPath, extensions, fileStore,copy);
-            delete copy;
-        }
-
-        // If this entry is a file, we'll pass it over to checkAndAddFile
-        if (isFile(fullPath.string()) ) {
-            checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore);
-        }
-    }
-
-    // Clean up
-    dw->closeDir();
-
-    return true;
-}
-
-void SystemFileFinder::checkAndAddFile(String8 path, const struct stat* stats,
-                                       Vector<String8>& extensions,
-                                       KeyedVector<String8,time_t>& fileStore)
-{
-    // Loop over the extensions, checking for a match
-    bool done = false;
-    String8 ext(path.getPathExtension());
-    ext.toLower();
-    for (size_t i = 0; i < extensions.size() && !done; ++i) {
-        String8 ext2 = extensions[i].getPathExtension();
-        ext2.toLower();
-        // Compare the extensions. If a match is found, add to storage.
-        if (ext == ext2) {
-            done = true;
-            fileStore.add(path,stats->st_mtime);
-        }
-    }
-}
-
diff --git a/tools/aapt/FileFinder.h b/tools/aapt/FileFinder.h
deleted file mode 100644
index 6974aee..0000000
--- a/tools/aapt/FileFinder.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-
-// File Finder.
-// This is a collection of useful functions for finding paths and modification
-// times of files that match an extension pattern in a directory tree.
-// and finding files in it.
-
-#ifndef FILEFINDER_H
-#define FILEFINDER_H
-
-#include <utils/Vector.h>
-#include <utils/KeyedVector.h>
-#include <utils/String8.h>
-
-#include "DirectoryWalker.h"
-
-using namespace android;
-
-// Abstraction to allow for dependency injection. See MockFileFinder.h
-// for the testing implementation.
-class FileFinder {
-public:
-    virtual bool findFiles(String8 basePath, Vector<String8>& extensions,
-                           KeyedVector<String8,time_t>& fileStore,
-                           DirectoryWalker* dw) = 0;
-
-    virtual ~FileFinder() {};
-};
-
-class SystemFileFinder : public FileFinder {
-public:
-
-    /* findFiles takes a path, a Vector of extensions, and a destination KeyedVector
-     *           and places path/modification date key/values pointing to
-     *          all files with matching extensions found into the KeyedVector
-     * PRECONDITIONS
-     *     path is a valid system path
-     *     extensions should include leading "."
-     *                This is not necessary, but the comparison directly
-     *                compares the end of the path string so if the "."
-     *                is excluded there is a small chance you could have
-     *                a false positive match. (For example: extension "png"
-     *                would match a file called "blahblahpng")
-     *
-     * POSTCONDITIONS
-     *     fileStore contains (in no guaranteed order) paths to all
-     *                matching files encountered in subdirectories of path
-     *                as keys in the KeyedVector. Each key has the modification time
-     *                of the file as its value.
-     *
-     * Calls checkAndAddFile on each file encountered in the directory tree
-     * Recursively descends into subdirectories.
-     */
-    virtual bool findFiles(String8 basePath, Vector<String8>& extensions,
-                           KeyedVector<String8,time_t>& fileStore,
-                           DirectoryWalker* dw);
-
-private:
-    /**
-     * checkAndAddFile looks at a single file path and stat combo
-     * to determine whether it is a matching file (by looking at
-     * the extension)
-     *
-     * PRECONDITIONS
-     *    no setup is needed
-     *
-     * POSTCONDITIONS
-     *    If the given file has a matching extension then a new entry
-     *    is added to the KeyedVector with the path as the key and the modification
-     *    time as the value.
-     *
-     */
-    static void checkAndAddFile(String8 path, const struct stat* stats,
-                                Vector<String8>& extensions,
-                                KeyedVector<String8,time_t>& fileStore);
-
-};
-#endif // FILEFINDER_H
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
deleted file mode 100644
index 9de685a..0000000
--- a/tools/aapt/Images.cpp
+++ /dev/null
@@ -1,1382 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Build resource files from raw assets.
-//
-
-#define PNG_INTERNAL
-
-#include "Images.h"
-
-#include <androidfw/ResourceTypes.h>
-#include <utils/ByteOrder.h>
-
-#include <png.h>
-
-#define NOISY(x) //x
-
-static void
-png_write_aapt_file(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-    status_t err = ((AaptFile*)png_ptr->io_ptr)->writeData(data, length);
-    if (err != NO_ERROR) {
-        png_error(png_ptr, "Write Error");
-    }
-}
-
-
-static void
-png_flush_aapt_file(png_structp png_ptr)
-{
-}
-
-// This holds an image as 8bpp RGBA.
-struct image_info
-{
-    image_info() : rows(NULL), is9Patch(false), allocRows(NULL) { }
-    ~image_info() {
-        if (rows && rows != allocRows) {
-            free(rows);
-        }
-        if (allocRows) {
-            for (int i=0; i<(int)allocHeight; i++) {
-                free(allocRows[i]);
-            }
-            free(allocRows);
-        }
-        free(info9Patch.xDivs);
-        free(info9Patch.yDivs);
-        free(info9Patch.colors);
-    }
-
-    png_uint_32 width;
-    png_uint_32 height;
-    png_bytepp rows;
-
-    // 9-patch info.
-    bool is9Patch;
-    Res_png_9patch info9Patch;
-
-    // Layout padding, if relevant
-    bool haveLayoutBounds;
-    int32_t layoutBoundsLeft;
-    int32_t layoutBoundsTop;
-    int32_t layoutBoundsRight;
-    int32_t layoutBoundsBottom;
-
-    png_uint_32 allocHeight;
-    png_bytepp allocRows;
-};
-
-static void read_png(const char* imageName,
-                     png_structp read_ptr, png_infop read_info,
-                     image_info* outImageInfo)
-{
-    int color_type;
-    int bit_depth, interlace_type, compression_type;
-    int i;
-
-    png_read_info(read_ptr, read_info);
-
-    png_get_IHDR(read_ptr, read_info, &outImageInfo->width,
-       &outImageInfo->height, &bit_depth, &color_type,
-       &interlace_type, &compression_type, NULL);
-
-    //printf("Image %s:\n", imageName);
-    //printf("color_type=%d, bit_depth=%d, interlace_type=%d, compression_type=%d\n",
-    //       color_type, bit_depth, interlace_type, compression_type);
-
-    if (color_type == PNG_COLOR_TYPE_PALETTE)
-        png_set_palette_to_rgb(read_ptr);
-
-    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
-        png_set_gray_1_2_4_to_8(read_ptr);
-
-    if (png_get_valid(read_ptr, read_info, PNG_INFO_tRNS)) {
-        //printf("Has PNG_INFO_tRNS!\n");
-        png_set_tRNS_to_alpha(read_ptr);
-    }
-
-    if (bit_depth == 16)
-        png_set_strip_16(read_ptr);
-
-    if ((color_type&PNG_COLOR_MASK_ALPHA) == 0)
-        png_set_add_alpha(read_ptr, 0xFF, PNG_FILLER_AFTER);
-
-    if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-        png_set_gray_to_rgb(read_ptr);
-
-    png_read_update_info(read_ptr, read_info);
-
-    outImageInfo->rows = (png_bytepp)malloc(
-        outImageInfo->height * png_sizeof(png_bytep));
-    outImageInfo->allocHeight = outImageInfo->height;
-    outImageInfo->allocRows = outImageInfo->rows;
-
-    png_set_rows(read_ptr, read_info, outImageInfo->rows);
-
-    for (i = 0; i < (int)outImageInfo->height; i++)
-    {
-        outImageInfo->rows[i] = (png_bytep)
-            malloc(png_get_rowbytes(read_ptr, read_info));
-    }
-
-    png_read_image(read_ptr, outImageInfo->rows);
-
-    png_read_end(read_ptr, read_info);
-
-    NOISY(printf("Image %s: w=%d, h=%d, d=%d, colors=%d, inter=%d, comp=%d\n",
-                 imageName,
-                 (int)outImageInfo->width, (int)outImageInfo->height,
-                 bit_depth, color_type,
-                 interlace_type, compression_type));
-
-    png_get_IHDR(read_ptr, read_info, &outImageInfo->width,
-       &outImageInfo->height, &bit_depth, &color_type,
-       &interlace_type, &compression_type, NULL);
-}
-
-#define COLOR_TRANSPARENT 0
-#define COLOR_WHITE 0xFFFFFFFF
-#define COLOR_TICK  0xFF000000
-#define COLOR_LAYOUT_BOUNDS_TICK 0xFF0000FF
-
-enum {
-    TICK_TYPE_NONE,
-    TICK_TYPE_TICK,
-    TICK_TYPE_LAYOUT_BOUNDS,
-    TICK_TYPE_BOTH
-};
-
-static int tick_type(png_bytep p, bool transparent, const char** outError)
-{
-    png_uint_32 color = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
-
-    if (transparent) {
-        if (p[3] == 0) {
-            return TICK_TYPE_NONE;
-        }
-        if (color == COLOR_LAYOUT_BOUNDS_TICK) {
-            return TICK_TYPE_LAYOUT_BOUNDS;
-        }
-        if (color == COLOR_TICK) {
-            return TICK_TYPE_TICK;
-        }
-
-        // Error cases
-        if (p[3] != 0xff) {
-            *outError = "Frame pixels must be either solid or transparent (not intermediate alphas)";
-            return TICK_TYPE_NONE;
-        }
-        if (p[0] != 0 || p[1] != 0 || p[2] != 0) {
-            *outError = "Ticks in transparent frame must be black or red";
-        }
-        return TICK_TYPE_TICK;
-    }
-
-    if (p[3] != 0xFF) {
-        *outError = "White frame must be a solid color (no alpha)";
-    }
-    if (color == COLOR_WHITE) {
-        return TICK_TYPE_NONE;
-    }
-    if (color == COLOR_TICK) {
-        return TICK_TYPE_TICK;
-    }
-    if (color == COLOR_LAYOUT_BOUNDS_TICK) {
-        return TICK_TYPE_LAYOUT_BOUNDS;
-    }
-
-    if (p[0] != 0 || p[1] != 0 || p[2] != 0) {
-        *outError = "Ticks in white frame must be black or red";
-        return TICK_TYPE_NONE;
-    }
-    return TICK_TYPE_TICK;
-}
-
-enum {
-    TICK_START,
-    TICK_INSIDE_1,
-    TICK_OUTSIDE_1
-};
-
-static status_t get_horizontal_ticks(
-        png_bytep row, int width, bool transparent, bool required,
-        int32_t* outLeft, int32_t* outRight, const char** outError,
-        uint8_t* outDivs, bool multipleAllowed)
-{
-    int i;
-    *outLeft = *outRight = -1;
-    int state = TICK_START;
-    bool found = false;
-
-    for (i=1; i<width-1; i++) {
-        if (TICK_TYPE_TICK == tick_type(row+i*4, transparent, outError)) {
-            if (state == TICK_START ||
-                (state == TICK_OUTSIDE_1 && multipleAllowed)) {
-                *outLeft = i-1;
-                *outRight = width-2;
-                found = true;
-                if (outDivs != NULL) {
-                    *outDivs += 2;
-                }
-                state = TICK_INSIDE_1;
-            } else if (state == TICK_OUTSIDE_1) {
-                *outError = "Can't have more than one marked region along edge";
-                *outLeft = i;
-                return UNKNOWN_ERROR;
-            }
-        } else if (*outError == NULL) {
-            if (state == TICK_INSIDE_1) {
-                // We're done with this div.  Move on to the next.
-                *outRight = i-1;
-                outRight += 2;
-                outLeft += 2;
-                state = TICK_OUTSIDE_1;
-            }
-        } else {
-            *outLeft = i;
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    if (required && !found) {
-        *outError = "No marked region found along edge";
-        *outLeft = -1;
-        return UNKNOWN_ERROR;
-    }
-
-    return NO_ERROR;
-}
-
-static status_t get_vertical_ticks(
-        png_bytepp rows, int offset, int height, bool transparent, bool required,
-        int32_t* outTop, int32_t* outBottom, const char** outError,
-        uint8_t* outDivs, bool multipleAllowed)
-{
-    int i;
-    *outTop = *outBottom = -1;
-    int state = TICK_START;
-    bool found = false;
-
-    for (i=1; i<height-1; i++) {
-        if (TICK_TYPE_TICK == tick_type(rows[i]+offset, transparent, outError)) {
-            if (state == TICK_START ||
-                (state == TICK_OUTSIDE_1 && multipleAllowed)) {
-                *outTop = i-1;
-                *outBottom = height-2;
-                found = true;
-                if (outDivs != NULL) {
-                    *outDivs += 2;
-                }
-                state = TICK_INSIDE_1;
-            } else if (state == TICK_OUTSIDE_1) {
-                *outError = "Can't have more than one marked region along edge";
-                *outTop = i;
-                return UNKNOWN_ERROR;
-            }
-        } else if (*outError == NULL) {
-            if (state == TICK_INSIDE_1) {
-                // We're done with this div.  Move on to the next.
-                *outBottom = i-1;
-                outTop += 2;
-                outBottom += 2;
-                state = TICK_OUTSIDE_1;
-            }
-        } else {
-            *outTop = i;
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    if (required && !found) {
-        *outError = "No marked region found along edge";
-        *outTop = -1;
-        return UNKNOWN_ERROR;
-    }
-
-    return NO_ERROR;
-}
-
-static status_t get_horizontal_layout_bounds_ticks(
-        png_bytep row, int width, bool transparent, bool required,
-        int32_t* outLeft, int32_t* outRight, const char** outError)
-{
-    int i;
-    *outLeft = *outRight = 0;
-
-    // Look for left tick
-    if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(row + 4, transparent, outError)) {
-        // Starting with a layout padding tick
-        i = 1;
-        while (i < width - 1) {
-            (*outLeft)++;
-            i++;
-            int tick = tick_type(row + i * 4, transparent, outError);
-            if (tick != TICK_TYPE_LAYOUT_BOUNDS) {
-                break;
-            }
-        }
-    }
-
-    // Look for right tick
-    if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(row + (width - 2) * 4, transparent, outError)) {
-        // Ending with a layout padding tick
-        i = width - 2;
-        while (i > 1) {
-            (*outRight)++;
-            i--;
-            int tick = tick_type(row+i*4, transparent, outError);
-            if (tick != TICK_TYPE_LAYOUT_BOUNDS) {
-                break;
-            }
-        }
-    }
-
-    return NO_ERROR;
-}
-
-static status_t get_vertical_layout_bounds_ticks(
-        png_bytepp rows, int offset, int height, bool transparent, bool required,
-        int32_t* outTop, int32_t* outBottom, const char** outError)
-{
-    int i;
-    *outTop = *outBottom = 0;
-
-    // Look for top tick
-    if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(rows[1] + offset, transparent, outError)) {
-        // Starting with a layout padding tick
-        i = 1;
-        while (i < height - 1) {
-            (*outTop)++;
-            i++;
-            int tick = tick_type(rows[i] + offset, transparent, outError);
-            if (tick != TICK_TYPE_LAYOUT_BOUNDS) {
-                break;
-            }
-        }
-    }
-
-    // Look for bottom tick
-    if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(rows[height - 2] + offset, transparent, outError)) {
-        // Ending with a layout padding tick
-        i = height - 2;
-        while (i > 1) {
-            (*outBottom)++;
-            i--;
-            int tick = tick_type(rows[i] + offset, transparent, outError);
-            if (tick != TICK_TYPE_LAYOUT_BOUNDS) {
-                break;
-            }
-        }
-    }
-
-    return NO_ERROR;
-}
-
-
-static uint32_t get_color(
-    png_bytepp rows, int left, int top, int right, int bottom)
-{
-    png_bytep color = rows[top] + left*4;
-
-    if (left > right || top > bottom) {
-        return Res_png_9patch::TRANSPARENT_COLOR;
-    }
-
-    while (top <= bottom) {
-        for (int i = left; i <= right; i++) {
-            png_bytep p = rows[top]+i*4;
-            if (color[3] == 0) {
-                if (p[3] != 0) {
-                    return Res_png_9patch::NO_COLOR;
-                }
-            } else if (p[0] != color[0] || p[1] != color[1]
-                       || p[2] != color[2] || p[3] != color[3]) {
-                return Res_png_9patch::NO_COLOR;
-            }
-        }
-        top++;
-    }
-
-    if (color[3] == 0) {
-        return Res_png_9patch::TRANSPARENT_COLOR;
-    }
-    return (color[3]<<24) | (color[0]<<16) | (color[1]<<8) | color[2];
-}
-
-static void select_patch(
-    int which, int front, int back, int size, int* start, int* end)
-{
-    switch (which) {
-    case 0:
-        *start = 0;
-        *end = front-1;
-        break;
-    case 1:
-        *start = front;
-        *end = back-1;
-        break;
-    case 2:
-        *start = back;
-        *end = size-1;
-        break;
-    }
-}
-
-static uint32_t get_color(image_info* image, int hpatch, int vpatch)
-{
-    int left, right, top, bottom;
-    select_patch(
-        hpatch, image->info9Patch.xDivs[0], image->info9Patch.xDivs[1],
-        image->width, &left, &right);
-    select_patch(
-        vpatch, image->info9Patch.yDivs[0], image->info9Patch.yDivs[1],
-        image->height, &top, &bottom);
-    //printf("Selecting h=%d v=%d: (%d,%d)-(%d,%d)\n",
-    //       hpatch, vpatch, left, top, right, bottom);
-    const uint32_t c = get_color(image->rows, left, top, right, bottom);
-    NOISY(printf("Color in (%d,%d)-(%d,%d): #%08x\n", left, top, right, bottom, c));
-    return c;
-}
-
-static status_t do_9patch(const char* imageName, image_info* image)
-{
-    image->is9Patch = true;
-
-    int W = image->width;
-    int H = image->height;
-    int i, j;
-
-    int maxSizeXDivs = W * sizeof(int32_t);
-    int maxSizeYDivs = H * sizeof(int32_t);
-    int32_t* xDivs = (int32_t*) malloc(maxSizeXDivs);
-    int32_t* yDivs = (int32_t*) malloc(maxSizeYDivs);
-    uint8_t  numXDivs = 0;
-    uint8_t  numYDivs = 0;
-    int8_t numColors;
-    int numRows;
-    int numCols;
-    int top;
-    int left;
-    int right;
-    int bottom;
-    memset(xDivs, -1, maxSizeXDivs);
-    memset(yDivs, -1, maxSizeYDivs);
-    image->info9Patch.paddingLeft = image->info9Patch.paddingRight =
-        image->info9Patch.paddingTop = image->info9Patch.paddingBottom = -1;
-
-    image->layoutBoundsLeft = image->layoutBoundsRight =
-        image->layoutBoundsTop = image->layoutBoundsBottom = 0;
-
-    png_bytep p = image->rows[0];
-    bool transparent = p[3] == 0;
-    bool hasColor = false;
-
-    const char* errorMsg = NULL;
-    int errorPixel = -1;
-    const char* errorEdge = NULL;
-
-    int colorIndex = 0;
-
-    // Validate size...
-    if (W < 3 || H < 3) {
-        errorMsg = "Image must be at least 3x3 (1x1 without frame) pixels";
-        goto getout;
-    }
-
-    // Validate frame...
-    if (!transparent &&
-        (p[0] != 0xFF || p[1] != 0xFF || p[2] != 0xFF || p[3] != 0xFF)) {
-        errorMsg = "Must have one-pixel frame that is either transparent or white";
-        goto getout;
-    }
-
-    // Find left and right of sizing areas...
-    if (get_horizontal_ticks(p, W, transparent, true, &xDivs[0],
-                             &xDivs[1], &errorMsg, &numXDivs, true) != NO_ERROR) {
-        errorPixel = xDivs[0];
-        errorEdge = "top";
-        goto getout;
-    }
-
-    // Find top and bottom of sizing areas...
-    if (get_vertical_ticks(image->rows, 0, H, transparent, true, &yDivs[0],
-                           &yDivs[1], &errorMsg, &numYDivs, true) != NO_ERROR) {
-        errorPixel = yDivs[0];
-        errorEdge = "left";
-        goto getout;
-    }
-
-    // Find left and right of padding area...
-    if (get_horizontal_ticks(image->rows[H-1], W, transparent, false, &image->info9Patch.paddingLeft,
-                             &image->info9Patch.paddingRight, &errorMsg, NULL, false) != NO_ERROR) {
-        errorPixel = image->info9Patch.paddingLeft;
-        errorEdge = "bottom";
-        goto getout;
-    }
-
-    // Find top and bottom of padding area...
-    if (get_vertical_ticks(image->rows, (W-1)*4, H, transparent, false, &image->info9Patch.paddingTop,
-                           &image->info9Patch.paddingBottom, &errorMsg, NULL, false) != NO_ERROR) {
-        errorPixel = image->info9Patch.paddingTop;
-        errorEdge = "right";
-        goto getout;
-    }
-
-    // Find left and right of layout padding...
-    get_horizontal_layout_bounds_ticks(image->rows[H-1], W, transparent, false,
-                                        &image->layoutBoundsLeft,
-                                        &image->layoutBoundsRight, &errorMsg);
-
-    get_vertical_layout_bounds_ticks(image->rows, (W-1)*4, H, transparent, false,
-                                        &image->layoutBoundsTop,
-                                        &image->layoutBoundsBottom, &errorMsg);
-
-    image->haveLayoutBounds = image->layoutBoundsLeft != 0
-                               || image->layoutBoundsRight != 0
-                               || image->layoutBoundsTop != 0
-                               || image->layoutBoundsBottom != 0;
-
-    if (image->haveLayoutBounds) {
-        NOISY(printf("layoutBounds=%d %d %d %d\n", image->layoutBoundsLeft, image->layoutBoundsTop,
-                image->layoutBoundsRight, image->layoutBoundsBottom));
-    }
-
-    // Copy patch data into image
-    image->info9Patch.numXDivs = numXDivs;
-    image->info9Patch.numYDivs = numYDivs;
-    image->info9Patch.xDivs = xDivs;
-    image->info9Patch.yDivs = yDivs;
-
-    // If padding is not yet specified, take values from size.
-    if (image->info9Patch.paddingLeft < 0) {
-        image->info9Patch.paddingLeft = xDivs[0];
-        image->info9Patch.paddingRight = W - 2 - xDivs[1];
-    } else {
-        // Adjust value to be correct!
-        image->info9Patch.paddingRight = W - 2 - image->info9Patch.paddingRight;
-    }
-    if (image->info9Patch.paddingTop < 0) {
-        image->info9Patch.paddingTop = yDivs[0];
-        image->info9Patch.paddingBottom = H - 2 - yDivs[1];
-    } else {
-        // Adjust value to be correct!
-        image->info9Patch.paddingBottom = H - 2 - image->info9Patch.paddingBottom;
-    }
-
-    NOISY(printf("Size ticks for %s: x0=%d, x1=%d, y0=%d, y1=%d\n", imageName,
-                 image->info9Patch.xDivs[0], image->info9Patch.xDivs[1],
-                 image->info9Patch.yDivs[0], image->info9Patch.yDivs[1]));
-    NOISY(printf("padding ticks for %s: l=%d, r=%d, t=%d, b=%d\n", imageName,
-                 image->info9Patch.paddingLeft, image->info9Patch.paddingRight,
-                 image->info9Patch.paddingTop, image->info9Patch.paddingBottom));
-
-    // Remove frame from image.
-    image->rows = (png_bytepp)malloc((H-2) * png_sizeof(png_bytep));
-    for (i=0; i<(H-2); i++) {
-        image->rows[i] = image->allocRows[i+1];
-        memmove(image->rows[i], image->rows[i]+4, (W-2)*4);
-    }
-    image->width -= 2;
-    W = image->width;
-    image->height -= 2;
-    H = image->height;
-
-    // Figure out the number of rows and columns in the N-patch
-    numCols = numXDivs + 1;
-    if (xDivs[0] == 0) {  // Column 1 is strechable
-        numCols--;
-    }
-    if (xDivs[numXDivs - 1] == W) {
-        numCols--;
-    }
-    numRows = numYDivs + 1;
-    if (yDivs[0] == 0) {  // Row 1 is strechable
-        numRows--;
-    }
-    if (yDivs[numYDivs - 1] == H) {
-        numRows--;
-    }
-
-    // Make sure the amount of rows and columns will fit in the number of
-    // colors we can use in the 9-patch format.
-    if (numRows * numCols > 0x7F) {
-        errorMsg = "Too many rows and columns in 9-patch perimeter";
-        goto getout;
-    }
-
-    numColors = numRows * numCols;
-    image->info9Patch.numColors = numColors;
-    image->info9Patch.colors = (uint32_t*)malloc(numColors * sizeof(uint32_t));
-
-    // Fill in color information for each patch.
-
-    uint32_t c;
-    top = 0;
-
-    // The first row always starts with the top being at y=0 and the bottom
-    // being either yDivs[1] (if yDivs[0]=0) of yDivs[0].  In the former case
-    // the first row is stretchable along the Y axis, otherwise it is fixed.
-    // The last row always ends with the bottom being bitmap.height and the top
-    // being either yDivs[numYDivs-2] (if yDivs[numYDivs-1]=bitmap.height) or
-    // yDivs[numYDivs-1]. In the former case the last row is stretchable along
-    // the Y axis, otherwise it is fixed.
-    //
-    // The first and last columns are similarly treated with respect to the X
-    // axis.
-    //
-    // The above is to help explain some of the special casing that goes on the
-    // code below.
-
-    // The initial yDiv and whether the first row is considered stretchable or
-    // not depends on whether yDiv[0] was zero or not.
-    for (j = (yDivs[0] == 0 ? 1 : 0);
-          j <= numYDivs && top < H;
-          j++) {
-        if (j == numYDivs) {
-            bottom = H;
-        } else {
-            bottom = yDivs[j];
-        }
-        left = 0;
-        // The initial xDiv and whether the first column is considered
-        // stretchable or not depends on whether xDiv[0] was zero or not.
-        for (i = xDivs[0] == 0 ? 1 : 0;
-              i <= numXDivs && left < W;
-              i++) {
-            if (i == numXDivs) {
-                right = W;
-            } else {
-                right = xDivs[i];
-            }
-            c = get_color(image->rows, left, top, right - 1, bottom - 1);
-            image->info9Patch.colors[colorIndex++] = c;
-            NOISY(if (c != Res_png_9patch::NO_COLOR) hasColor = true);
-            left = right;
-        }
-        top = bottom;
-    }
-
-    assert(colorIndex == numColors);
-
-    for (i=0; i<numColors; i++) {
-        if (hasColor) {
-            if (i == 0) printf("Colors in %s:\n ", imageName);
-            printf(" #%08x", image->info9Patch.colors[i]);
-            if (i == numColors - 1) printf("\n");
-        }
-    }
-
-    image->is9Patch = true;
-    image->info9Patch.deviceToFile();
-
-getout:
-    if (errorMsg) {
-        fprintf(stderr,
-            "ERROR: 9-patch image %s malformed.\n"
-            "       %s.\n", imageName, errorMsg);
-        if (errorEdge != NULL) {
-            if (errorPixel >= 0) {
-                fprintf(stderr,
-                    "       Found at pixel #%d along %s edge.\n", errorPixel, errorEdge);
-            } else {
-                fprintf(stderr,
-                    "       Found along %s edge.\n", errorEdge);
-            }
-        }
-        return UNKNOWN_ERROR;
-    }
-    return NO_ERROR;
-}
-
-static void checkNinePatchSerialization(Res_png_9patch* inPatch,  void * data)
-{
-    if (sizeof(void*) != sizeof(int32_t)) {
-        // can't deserialize on a non-32 bit system
-        return;
-    }
-    size_t patchSize = inPatch->serializedSize();
-    void * newData = malloc(patchSize);
-    memcpy(newData, data, patchSize);
-    Res_png_9patch* outPatch = inPatch->deserialize(newData);
-    // deserialization is done in place, so outPatch == newData
-    assert(outPatch == newData);
-    assert(outPatch->numXDivs == inPatch->numXDivs);
-    assert(outPatch->numYDivs == inPatch->numYDivs);
-    assert(outPatch->paddingLeft == inPatch->paddingLeft);
-    assert(outPatch->paddingRight == inPatch->paddingRight);
-    assert(outPatch->paddingTop == inPatch->paddingTop);
-    assert(outPatch->paddingBottom == inPatch->paddingBottom);
-    for (int i = 0; i < outPatch->numXDivs; i++) {
-        assert(outPatch->xDivs[i] == inPatch->xDivs[i]);
-    }
-    for (int i = 0; i < outPatch->numYDivs; i++) {
-        assert(outPatch->yDivs[i] == inPatch->yDivs[i]);
-    }
-    for (int i = 0; i < outPatch->numColors; i++) {
-        assert(outPatch->colors[i] == inPatch->colors[i]);
-    }
-    free(newData);
-}
-
-static bool patch_equals(Res_png_9patch& patch1, Res_png_9patch& patch2) {
-    if (!(patch1.numXDivs == patch2.numXDivs &&
-          patch1.numYDivs == patch2.numYDivs &&
-          patch1.numColors == patch2.numColors &&
-          patch1.paddingLeft == patch2.paddingLeft &&
-          patch1.paddingRight == patch2.paddingRight &&
-          patch1.paddingTop == patch2.paddingTop &&
-          patch1.paddingBottom == patch2.paddingBottom)) {
-            return false;
-    }
-    for (int i = 0; i < patch1.numColors; i++) {
-        if (patch1.colors[i] != patch2.colors[i]) {
-            return false;
-        }
-    }
-    for (int i = 0; i < patch1.numXDivs; i++) {
-        if (patch1.xDivs[i] != patch2.xDivs[i]) {
-            return false;
-        }
-    }
-    for (int i = 0; i < patch1.numYDivs; i++) {
-        if (patch1.yDivs[i] != patch2.yDivs[i]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-static void dump_image(int w, int h, png_bytepp rows, int color_type)
-{
-    int i, j, rr, gg, bb, aa;
-
-    int bpp;
-    if (color_type == PNG_COLOR_TYPE_PALETTE || color_type == PNG_COLOR_TYPE_GRAY) {
-        bpp = 1;
-    } else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
-        bpp = 2;
-    } else if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
-        // We use a padding byte even when there is no alpha
-        bpp = 4;
-    } else {
-        printf("Unknown color type %d.\n", color_type);
-    }
-
-    for (j = 0; j < h; j++) {
-        png_bytep row = rows[j];
-        for (i = 0; i < w; i++) {
-            rr = row[0];
-            gg = row[1];
-            bb = row[2];
-            aa = row[3];
-            row += bpp;
-
-            if (i == 0) {
-                printf("Row %d:", j);
-            }
-            switch (bpp) {
-            case 1:
-                printf(" (%d)", rr);
-                break;
-            case 2:
-                printf(" (%d %d", rr, gg);
-                break;
-            case 3:
-                printf(" (%d %d %d)", rr, gg, bb);
-                break;
-            case 4:
-                printf(" (%d %d %d %d)", rr, gg, bb, aa);
-                break;
-            }
-            if (i == (w - 1)) {
-                NOISY(printf("\n"));
-            }
-        }
-    }
-}
-
-#define MAX(a,b) ((a)>(b)?(a):(b))
-#define ABS(a)   ((a)<0?-(a):(a))
-
-static void analyze_image(const char *imageName, image_info &imageInfo, int grayscaleTolerance,
-                          png_colorp rgbPalette, png_bytep alphaPalette,
-                          int *paletteEntries, bool *hasTransparency, int *colorType,
-                          png_bytepp outRows)
-{
-    int w = imageInfo.width;
-    int h = imageInfo.height;
-    int i, j, rr, gg, bb, aa, idx;
-    uint32_t colors[256], col;
-    int num_colors = 0;
-    int maxGrayDeviation = 0;
-
-    bool isOpaque = true;
-    bool isPalette = true;
-    bool isGrayscale = true;
-
-    // Scan the entire image and determine if:
-    // 1. Every pixel has R == G == B (grayscale)
-    // 2. Every pixel has A == 255 (opaque)
-    // 3. There are no more than 256 distinct RGBA colors
-
-    // NOISY(printf("Initial image data:\n"));
-    // dump_image(w, h, imageInfo.rows, PNG_COLOR_TYPE_RGB_ALPHA);
-
-    for (j = 0; j < h; j++) {
-        png_bytep row = imageInfo.rows[j];
-        png_bytep out = outRows[j];
-        for (i = 0; i < w; i++) {
-            rr = *row++;
-            gg = *row++;
-            bb = *row++;
-            aa = *row++;
-
-            int odev = maxGrayDeviation;
-            maxGrayDeviation = MAX(ABS(rr - gg), maxGrayDeviation);
-            maxGrayDeviation = MAX(ABS(gg - bb), maxGrayDeviation);
-            maxGrayDeviation = MAX(ABS(bb - rr), maxGrayDeviation);
-            if (maxGrayDeviation > odev) {
-                NOISY(printf("New max dev. = %d at pixel (%d, %d) = (%d %d %d %d)\n",
-                             maxGrayDeviation, i, j, rr, gg, bb, aa));
-            }
-
-            // Check if image is really grayscale
-            if (isGrayscale) {
-                if (rr != gg || rr != bb) {
-                     NOISY(printf("Found a non-gray pixel at %d, %d = (%d %d %d %d)\n",
-                                  i, j, rr, gg, bb, aa));
-                    isGrayscale = false;
-                }
-            }
-
-            // Check if image is really opaque
-            if (isOpaque) {
-                if (aa != 0xff) {
-                    NOISY(printf("Found a non-opaque pixel at %d, %d = (%d %d %d %d)\n",
-                                 i, j, rr, gg, bb, aa));
-                    isOpaque = false;
-                }
-            }
-
-            // Check if image is really <= 256 colors
-            if (isPalette) {
-                col = (uint32_t) ((rr << 24) | (gg << 16) | (bb << 8) | aa);
-                bool match = false;
-                for (idx = 0; idx < num_colors; idx++) {
-                    if (colors[idx] == col) {
-                        match = true;
-                        break;
-                    }
-                }
-
-                // Write the palette index for the pixel to outRows optimistically
-                // We might overwrite it later if we decide to encode as gray or
-                // gray + alpha
-                *out++ = idx;
-                if (!match) {
-                    if (num_colors == 256) {
-                        NOISY(printf("Found 257th color at %d, %d\n", i, j));
-                        isPalette = false;
-                    } else {
-                        colors[num_colors++] = col;
-                    }
-                }
-            }
-        }
-    }
-
-    *paletteEntries = 0;
-    *hasTransparency = !isOpaque;
-    int bpp = isOpaque ? 3 : 4;
-    int paletteSize = w * h + bpp * num_colors;
-
-    NOISY(printf("isGrayscale = %s\n", isGrayscale ? "true" : "false"));
-    NOISY(printf("isOpaque = %s\n", isOpaque ? "true" : "false"));
-    NOISY(printf("isPalette = %s\n", isPalette ? "true" : "false"));
-    NOISY(printf("Size w/ palette = %d, gray+alpha = %d, rgb(a) = %d\n",
-                 paletteSize, 2 * w * h, bpp * w * h));
-    NOISY(printf("Max gray deviation = %d, tolerance = %d\n", maxGrayDeviation, grayscaleTolerance));
-
-    // Choose the best color type for the image.
-    // 1. Opaque gray - use COLOR_TYPE_GRAY at 1 byte/pixel
-    // 2. Gray + alpha - use COLOR_TYPE_PALETTE if the number of distinct combinations
-    //     is sufficiently small, otherwise use COLOR_TYPE_GRAY_ALPHA
-    // 3. RGB(A) - use COLOR_TYPE_PALETTE if the number of distinct colors is sufficiently
-    //     small, otherwise use COLOR_TYPE_RGB{_ALPHA}
-    if (isGrayscale) {
-        if (isOpaque) {
-            *colorType = PNG_COLOR_TYPE_GRAY; // 1 byte/pixel
-        } else {
-            // Use a simple heuristic to determine whether using a palette will
-            // save space versus using gray + alpha for each pixel.
-            // This doesn't take into account chunk overhead, filtering, LZ
-            // compression, etc.
-            if (isPalette && (paletteSize < 2 * w * h)) {
-                *colorType = PNG_COLOR_TYPE_PALETTE; // 1 byte/pixel + 4 bytes/color
-            } else {
-                *colorType = PNG_COLOR_TYPE_GRAY_ALPHA; // 2 bytes per pixel
-            }
-        }
-    } else if (isPalette && (paletteSize < bpp * w * h)) {
-        *colorType = PNG_COLOR_TYPE_PALETTE;
-    } else {
-        if (maxGrayDeviation <= grayscaleTolerance) {
-            printf("%s: forcing image to gray (max deviation = %d)\n", imageName, maxGrayDeviation);
-            *colorType = isOpaque ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_GRAY_ALPHA;
-        } else {
-            *colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
-        }
-    }
-
-    // Perform postprocessing of the image or palette data based on the final
-    // color type chosen
-
-    if (*colorType == PNG_COLOR_TYPE_PALETTE) {
-        // Create separate RGB and Alpha palettes and set the number of colors
-        *paletteEntries = num_colors;
-
-        // Create the RGB and alpha palettes
-        for (int idx = 0; idx < num_colors; idx++) {
-            col = colors[idx];
-            rgbPalette[idx].red   = (png_byte) ((col >> 24) & 0xff);
-            rgbPalette[idx].green = (png_byte) ((col >> 16) & 0xff);
-            rgbPalette[idx].blue  = (png_byte) ((col >>  8) & 0xff);
-            alphaPalette[idx]     = (png_byte)  (col        & 0xff);
-        }
-    } else if (*colorType == PNG_COLOR_TYPE_GRAY || *colorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
-        // If the image is gray or gray + alpha, compact the pixels into outRows
-        for (j = 0; j < h; j++) {
-            png_bytep row = imageInfo.rows[j];
-            png_bytep out = outRows[j];
-            for (i = 0; i < w; i++) {
-                rr = *row++;
-                gg = *row++;
-                bb = *row++;
-                aa = *row++;
-                
-                if (isGrayscale) {
-                    *out++ = rr;
-                } else {
-                    *out++ = (png_byte) (rr * 0.2126f + gg * 0.7152f + bb * 0.0722f);
-                }
-                if (!isOpaque) {
-                    *out++ = aa;
-                }
-           }
-        }
-    }
-}
-
-
-static void write_png(const char* imageName,
-                      png_structp write_ptr, png_infop write_info,
-                      image_info& imageInfo, int grayscaleTolerance)
-{
-    bool optimize = true;
-    png_uint_32 width, height;
-    int color_type;
-    int bit_depth, interlace_type, compression_type;
-    int i;
-
-    png_unknown_chunk unknowns[2];
-    unknowns[0].data = NULL;
-    unknowns[1].data = NULL;
-
-    png_bytepp outRows = (png_bytepp) malloc((int) imageInfo.height * png_sizeof(png_bytep));
-    if (outRows == (png_bytepp) 0) {
-        printf("Can't allocate output buffer!\n");
-        exit(1);
-    }
-    for (i = 0; i < (int) imageInfo.height; i++) {
-        outRows[i] = (png_bytep) malloc(2 * (int) imageInfo.width);
-        if (outRows[i] == (png_bytep) 0) {
-            printf("Can't allocate output buffer!\n");
-            exit(1);
-        }
-    }
-
-    png_set_compression_level(write_ptr, Z_BEST_COMPRESSION);
-
-    NOISY(printf("Writing image %s: w = %d, h = %d\n", imageName,
-          (int) imageInfo.width, (int) imageInfo.height));
-
-    png_color rgbPalette[256];
-    png_byte alphaPalette[256];
-    bool hasTransparency;
-    int paletteEntries;
-
-    analyze_image(imageName, imageInfo, grayscaleTolerance, rgbPalette, alphaPalette,
-                  &paletteEntries, &hasTransparency, &color_type, outRows);
-
-    // If the image is a 9-patch, we need to preserve it as a ARGB file to make
-    // sure the pixels will not be pre-dithered/clamped until we decide they are
-    if (imageInfo.is9Patch && (color_type == PNG_COLOR_TYPE_RGB ||
-            color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE)) {
-        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
-    }
-
-    switch (color_type) {
-    case PNG_COLOR_TYPE_PALETTE:
-        NOISY(printf("Image %s has %d colors%s, using PNG_COLOR_TYPE_PALETTE\n",
-                     imageName, paletteEntries,
-                     hasTransparency ? " (with alpha)" : ""));
-        break;
-    case PNG_COLOR_TYPE_GRAY:
-        NOISY(printf("Image %s is opaque gray, using PNG_COLOR_TYPE_GRAY\n", imageName));
-        break;
-    case PNG_COLOR_TYPE_GRAY_ALPHA:
-        NOISY(printf("Image %s is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA\n", imageName));
-        break;
-    case PNG_COLOR_TYPE_RGB:
-        NOISY(printf("Image %s is opaque RGB, using PNG_COLOR_TYPE_RGB\n", imageName));
-        break;
-    case PNG_COLOR_TYPE_RGB_ALPHA:
-        NOISY(printf("Image %s is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA\n", imageName));
-        break;
-    }
-
-    png_set_IHDR(write_ptr, write_info, imageInfo.width, imageInfo.height,
-                 8, color_type, PNG_INTERLACE_NONE,
-                 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-
-    if (color_type == PNG_COLOR_TYPE_PALETTE) {
-        png_set_PLTE(write_ptr, write_info, rgbPalette, paletteEntries);
-        if (hasTransparency) {
-            png_set_tRNS(write_ptr, write_info, alphaPalette, paletteEntries, (png_color_16p) 0);
-        }
-       png_set_filter(write_ptr, 0, PNG_NO_FILTERS);
-    } else {
-       png_set_filter(write_ptr, 0, PNG_ALL_FILTERS);
-    }
-
-    if (imageInfo.is9Patch) {
-        int chunk_count = 1 + (imageInfo.haveLayoutBounds ? 1 : 0);
-        int p_index = imageInfo.haveLayoutBounds ? 1 : 0;
-        int b_index = 0;
-        png_byte *chunk_names = imageInfo.haveLayoutBounds
-                ? (png_byte*)"npLb\0npTc\0"
-                : (png_byte*)"npTc";
-        NOISY(printf("Adding 9-patch info...\n"));
-        strcpy((char*)unknowns[p_index].name, "npTc");
-        unknowns[p_index].data = (png_byte*)imageInfo.info9Patch.serialize();
-        unknowns[p_index].size = imageInfo.info9Patch.serializedSize();
-        // TODO: remove the check below when everything works
-        checkNinePatchSerialization(&imageInfo.info9Patch, unknowns[p_index].data);
-
-        if (imageInfo.haveLayoutBounds) {
-            int chunk_size = sizeof(png_uint_32) * 4;
-            strcpy((char*)unknowns[b_index].name, "npLb");
-            unknowns[b_index].data = (png_byte*) calloc(chunk_size, 1);
-            memcpy(unknowns[b_index].data, &imageInfo.layoutBoundsLeft, chunk_size);
-            unknowns[b_index].size = chunk_size;
-        }
-
-        png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS,
-                                    chunk_names, chunk_count);
-        png_set_unknown_chunks(write_ptr, write_info, unknowns, chunk_count);
-        // XXX I can't get this to work without forcibly changing
-        // the location to what I want...  which apparently is supposed
-        // to be a private API, but everything else I have tried results
-        // in the location being set to what I -last- wrote so I never
-        // get written. :p
-        png_set_unknown_chunk_location(write_ptr, write_info, 0, PNG_HAVE_PLTE);
-        if (imageInfo.haveLayoutBounds) {
-            png_set_unknown_chunk_location(write_ptr, write_info, 1, PNG_HAVE_PLTE);
-        }
-    }
-
-
-    png_write_info(write_ptr, write_info);
-
-    png_bytepp rows;
-    if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
-        png_set_filler(write_ptr, 0, PNG_FILLER_AFTER);
-        rows = imageInfo.rows;
-    } else {
-        rows = outRows;
-    }
-    png_write_image(write_ptr, rows);
-
-//     NOISY(printf("Final image data:\n"));
-//     dump_image(imageInfo.width, imageInfo.height, rows, color_type);
-
-    png_write_end(write_ptr, write_info);
-
-    for (i = 0; i < (int) imageInfo.height; i++) {
-        free(outRows[i]);
-    }
-    free(outRows);
-    free(unknowns[0].data);
-    free(unknowns[1].data);
-
-    png_get_IHDR(write_ptr, write_info, &width, &height,
-       &bit_depth, &color_type, &interlace_type,
-       &compression_type, NULL);
-
-    NOISY(printf("Image written: w=%d, h=%d, d=%d, colors=%d, inter=%d, comp=%d\n",
-                 (int)width, (int)height, bit_depth, color_type, interlace_type,
-                 compression_type));
-}
-
-status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,
-                         const sp<AaptFile>& file, String8* outNewLeafName)
-{
-    String8 ext(file->getPath().getPathExtension());
-
-    // We currently only process PNG images.
-    if (strcmp(ext.string(), ".png") != 0) {
-        return NO_ERROR;
-    }
-
-    // Example of renaming a file:
-    //*outNewLeafName = file->getPath().getBasePath().getFileName();
-    //outNewLeafName->append(".nupng");
-
-    String8 printableName(file->getPrintableSource());
-
-    if (bundle->getVerbose()) {
-        printf("Processing image: %s\n", printableName.string());
-    }
-
-    png_structp read_ptr = NULL;
-    png_infop read_info = NULL;
-    FILE* fp;
-
-    image_info imageInfo;
-
-    png_structp write_ptr = NULL;
-    png_infop write_info = NULL;
-
-    status_t error = UNKNOWN_ERROR;
-
-    const size_t nameLen = file->getPath().length();
-
-    fp = fopen(file->getSourceFile().string(), "rb");
-    if (fp == NULL) {
-        fprintf(stderr, "%s: ERROR: Unable to open PNG file\n", printableName.string());
-        goto bail;
-    }
-
-    read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, (png_error_ptr)NULL,
-                                        (png_error_ptr)NULL);
-    if (!read_ptr) {
-        goto bail;
-    }
-
-    read_info = png_create_info_struct(read_ptr);
-    if (!read_info) {
-        goto bail;
-    }
-
-    if (setjmp(png_jmpbuf(read_ptr))) {
-        goto bail;
-    }
-
-    png_init_io(read_ptr, fp);
-
-    read_png(printableName.string(), read_ptr, read_info, &imageInfo);
-
-    if (nameLen > 6) {
-        const char* name = file->getPath().string();
-        if (name[nameLen-5] == '9' && name[nameLen-6] == '.') {
-            if (do_9patch(printableName.string(), &imageInfo) != NO_ERROR) {
-                goto bail;
-            }
-        }
-    }
-
-    write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, (png_error_ptr)NULL,
-                                        (png_error_ptr)NULL);
-    if (!write_ptr)
-    {
-        goto bail;
-    }
-
-    write_info = png_create_info_struct(write_ptr);
-    if (!write_info)
-    {
-        goto bail;
-    }
-
-    png_set_write_fn(write_ptr, (void*)file.get(),
-                     png_write_aapt_file, png_flush_aapt_file);
-
-    if (setjmp(png_jmpbuf(write_ptr)))
-    {
-        goto bail;
-    }
-
-    write_png(printableName.string(), write_ptr, write_info, imageInfo,
-              bundle->getGrayscaleTolerance());
-
-    error = NO_ERROR;
-
-    if (bundle->getVerbose()) {
-        fseek(fp, 0, SEEK_END);
-        size_t oldSize = (size_t)ftell(fp);
-        size_t newSize = file->getSize();
-        float factor = ((float)newSize)/oldSize;
-        int percent = (int)(factor*100);
-        printf("    (processed image %s: %d%% size of source)\n", printableName.string(), percent);
-    }
-
-bail:
-    if (read_ptr) {
-        png_destroy_read_struct(&read_ptr, &read_info, (png_infopp)NULL);
-    }
-    if (fp) {
-        fclose(fp);
-    }
-    if (write_ptr) {
-        png_destroy_write_struct(&write_ptr, &write_info);
-    }
-
-    if (error != NO_ERROR) {
-        fprintf(stderr, "ERROR: Failure processing PNG image %s\n",
-                file->getPrintableSource().string());
-    }
-    return error;
-}
-
-status_t preProcessImageToCache(const Bundle* bundle, const String8& source, const String8& dest)
-{
-    png_structp read_ptr = NULL;
-    png_infop read_info = NULL;
-
-    FILE* fp;
-
-    image_info imageInfo;
-
-    png_structp write_ptr = NULL;
-    png_infop write_info = NULL;
-
-    status_t error = UNKNOWN_ERROR;
-
-    if (bundle->getVerbose()) {
-        printf("Processing image to cache: %s => %s\n", source.string(), dest.string());
-    }
-
-    // Get a file handler to read from
-    fp = fopen(source.string(),"rb");
-    if (fp == NULL) {
-        fprintf(stderr, "%s ERROR: Unable to open PNG file\n", source.string());
-        return error;
-    }
-
-    // Call libpng to get a struct to read image data into
-    read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-    if (!read_ptr) {
-        fclose(fp);
-        png_destroy_read_struct(&read_ptr, &read_info,NULL);
-        return error;
-    }
-
-    // Call libpng to get a struct to read image info into
-    read_info = png_create_info_struct(read_ptr);
-    if (!read_info) {
-        fclose(fp);
-        png_destroy_read_struct(&read_ptr, &read_info,NULL);
-        return error;
-    }
-
-    // Set a jump point for libpng to long jump back to on error
-    if (setjmp(png_jmpbuf(read_ptr))) {
-        fclose(fp);
-        png_destroy_read_struct(&read_ptr, &read_info,NULL);
-        return error;
-    }
-
-    // Set up libpng to read from our file.
-    png_init_io(read_ptr,fp);
-
-    // Actually read data from the file
-    read_png(source.string(), read_ptr, read_info, &imageInfo);
-
-    // We're done reading so we can clean up
-    // Find old file size before releasing handle
-    fseek(fp, 0, SEEK_END);
-    size_t oldSize = (size_t)ftell(fp);
-    fclose(fp);
-    png_destroy_read_struct(&read_ptr, &read_info,NULL);
-
-    // Check to see if we're dealing with a 9-patch
-    // If we are, process appropriately
-    if (source.getBasePath().getPathExtension() == ".9")  {
-        if (do_9patch(source.string(), &imageInfo) != NO_ERROR) {
-            return error;
-        }
-    }
-
-    // Call libpng to create a structure to hold the processed image data
-    // that can be written to disk
-    write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-    if (!write_ptr) {
-        png_destroy_write_struct(&write_ptr, &write_info);
-        return error;
-    }
-
-    // Call libpng to create a structure to hold processed image info that can
-    // be written to disk
-    write_info = png_create_info_struct(write_ptr);
-    if (!write_info) {
-        png_destroy_write_struct(&write_ptr, &write_info);
-        return error;
-    }
-
-    // Open up our destination file for writing
-    fp = fopen(dest.string(), "wb");
-    if (!fp) {
-        fprintf(stderr, "%s ERROR: Unable to open PNG file\n", dest.string());
-        png_destroy_write_struct(&write_ptr, &write_info);
-        return error;
-    }
-
-    // Set up libpng to write to our file
-    png_init_io(write_ptr, fp);
-
-    // Set up a jump for libpng to long jump back on on errors
-    if (setjmp(png_jmpbuf(write_ptr))) {
-        fclose(fp);
-        png_destroy_write_struct(&write_ptr, &write_info);
-        return error;
-    }
-
-    // Actually write out to the new png
-    write_png(dest.string(), write_ptr, write_info, imageInfo,
-              bundle->getGrayscaleTolerance());
-
-    if (bundle->getVerbose()) {
-        // Find the size of our new file
-        FILE* reader = fopen(dest.string(), "rb");
-        fseek(reader, 0, SEEK_END);
-        size_t newSize = (size_t)ftell(reader);
-        fclose(reader);
-
-        float factor = ((float)newSize)/oldSize;
-        int percent = (int)(factor*100);
-        printf("  (processed image to cache entry %s: %d%% size of source)\n",
-               dest.string(), percent);
-    }
-
-    //Clean up
-    fclose(fp);
-    png_destroy_write_struct(&write_ptr, &write_info);
-
-    return NO_ERROR;
-}
-
-status_t postProcessImage(const sp<AaptAssets>& assets,
-                          ResourceTable* table, const sp<AaptFile>& file)
-{
-    String8 ext(file->getPath().getPathExtension());
-
-    // At this point, now that we have all the resource data, all we need to
-    // do is compile XML files.
-    if (strcmp(ext.string(), ".xml") == 0) {
-        return compileXmlFile(assets, file, table);
-    }
-
-    return NO_ERROR;
-}
diff --git a/tools/aapt/Images.h b/tools/aapt/Images.h
deleted file mode 100644
index 91b6554..0000000
--- a/tools/aapt/Images.h
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Build resource files from raw assets.
-//
-
-#ifndef IMAGES_H
-#define IMAGES_H
-
-#include "ResourceTable.h"
-#include "Bundle.h"
-
-#include <utils/String8.h>
-#include <utils/RefBase.h>
-
-using android::String8;
-
-status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,
-                         const sp<AaptFile>& file, String8* outNewLeafName);
-
-status_t preProcessImageToCache(const Bundle* bundle, const String8& source, const String8& dest);
-
-status_t postProcessImage(const sp<AaptAssets>& assets,
-                          ResourceTable* table, const sp<AaptFile>& file);
-
-#endif
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
deleted file mode 100644
index 977226b..0000000
--- a/tools/aapt/Main.cpp
+++ /dev/null
@@ -1,651 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Android Asset Packaging Tool main entry point.
-//
-#include "Main.h"
-#include "Bundle.h"
-
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <utils/List.h>
-#include <utils/Errors.h>
-
-#include <stdlib.h>
-#include <getopt.h>
-#include <assert.h>
-
-using namespace android;
-
-static const char* gProgName = "aapt";
-
-/*
- * When running under Cygwin on Windows, this will convert slash-based
- * paths into back-slash-based ones. Otherwise the ApptAssets file comparisons
- * fail later as they use back-slash separators under Windows.
- *
- * This operates in-place on the path string.
- */
-void convertPath(char *path) {
-  if (path != NULL && OS_PATH_SEPARATOR != '/') {
-    for (; *path; path++) {
-      if (*path == '/') {
-        *path = OS_PATH_SEPARATOR;
-      }
-    }
-  }
-}
-
-/*
- * Print usage info.
- */
-void usage(void)
-{
-    fprintf(stderr, "Android Asset Packaging Tool\n\n");
-    fprintf(stderr, "Usage:\n");
-    fprintf(stderr,
-        " %s l[ist] [-v] [-a] file.{zip,jar,apk}\n"
-        "   List contents of Zip-compatible archive.\n\n", gProgName);
-    fprintf(stderr,
-        " %s d[ump] [--values] WHAT file.{apk} [asset [asset ...]]\n"
-        "   strings          Print the contents of the resource table string pool in the APK.\n"
-        "   badging          Print the label and icon for the app declared in APK.\n"
-        "   permissions      Print the permissions from the APK.\n"
-        "   resources        Print the resource table from the APK.\n"
-        "   configurations   Print the configurations in the APK.\n"
-        "   xmltree          Print the compiled xmls in the given assets.\n"
-        "   xmlstrings       Print the strings of the given compiled xml assets.\n\n", gProgName);
-    fprintf(stderr,
-        " %s p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \\\n"
-        "        [-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \\\n"
-        "        [--debug-mode] [--min-sdk-version VAL] [--target-sdk-version VAL] \\\n"
-        "        [--app-version VAL] [--app-version-name TEXT] [--custom-package VAL] \\\n"
-        "        [--rename-manifest-package PACKAGE] \\\n"
-        "        [--rename-instrumentation-target-package PACKAGE] \\\n"
-        "        [--utf16] [--auto-add-overlay] \\\n"
-        "        [--max-res-version VAL] \\\n"
-        "        [-I base-package [-I base-package ...]] \\\n"
-        "        [-A asset-source-dir]  [-G class-list-file] [-P public-definitions-file] \\\n"
-        "        [-S resource-sources [-S resource-sources ...]] \\\n"
-        "        [-F apk-file] [-J R-file-dir] \\\n"
-        "        [--product product1,product2,...] \\\n"
-        "        [-c CONFIGS] [--preferred-configurations CONFIGS] \\\n"
-        "        [raw-files-dir [raw-files-dir] ...] \\\n"
-        "        [--output-text-symbols DIR]\n"
-        "\n"
-        "   Package the android resources.  It will read assets and resources that are\n"
-        "   supplied with the -M -A -S or raw-files-dir arguments.  The -J -P -F and -R\n"
-        "   options control which files are output.\n\n"
-        , gProgName);
-    fprintf(stderr,
-        " %s r[emove] [-v] file.{zip,jar,apk} file1 [file2 ...]\n"
-        "   Delete specified files from Zip-compatible archive.\n\n",
-        gProgName);
-    fprintf(stderr,
-        " %s a[dd] [-v] file.{zip,jar,apk} file1 [file2 ...]\n"
-        "   Add specified files to Zip-compatible archive.\n\n", gProgName);
-    fprintf(stderr,
-        " %s c[runch] [-v] -S resource-sources ... -C output-folder ...\n"
-        "   Do PNG preprocessing on one or several resource folders\n"
-        "   and store the results in the output folder.\n\n", gProgName);
-    fprintf(stderr,
-        " %s s[ingleCrunch] [-v] -i input-file -o outputfile\n"
-        "   Do PNG preprocessing on a single file.\n\n", gProgName);
-    fprintf(stderr,
-        " %s v[ersion]\n"
-        "   Print program version.\n\n", gProgName);
-    fprintf(stderr,
-        " Modifiers:\n"
-        "   -a  print Android-specific data (resources, manifest) when listing\n"
-        "   -c  specify which configurations to include.  The default is all\n"
-        "       configurations.  The value of the parameter should be a comma\n"
-        "       separated list of configuration values.  Locales should be specified\n"
-        "       as either a language or language-region pair.  Some examples:\n"
-        "            en\n"
-        "            port,en\n"
-        "            port,land,en_US\n"
-        "       If you put the special locale, zz_ZZ on the list, it will perform\n"
-        "       pseudolocalization on the default locale, modifying all of the\n"
-        "       strings so you can look for strings that missed the\n"
-        "       internationalization process.  For example:\n"
-        "            port,land,zz_ZZ\n"
-        "   -d  one or more device assets to include, separated by commas\n"
-        "   -f  force overwrite of existing files\n"
-        "   -g  specify a pixel tolerance to force images to grayscale, default 0\n"
-        "   -j  specify a jar or zip file containing classes to include\n"
-        "   -k  junk path of file(s) added\n"
-        "   -m  make package directories under location specified by -J\n"
-#if 0
-        "   -p  pseudolocalize the default configuration\n"
-#endif
-        "   -u  update existing packages (add new, replace older, remove deleted files)\n"
-        "   -v  verbose output\n"
-        "   -x  create extending (non-application) resource IDs\n"
-        "   -z  require localization of resource attributes marked with\n"
-        "       localization=\"suggested\"\n"
-        "   -A  additional directory in which to find raw asset files\n"
-        "   -G  A file to output proguard options into.\n"
-        "   -F  specify the apk file to output\n"
-        "   -I  add an existing package to base include set\n"
-        "   -J  specify where to output R.java resource constant definitions\n"
-        "   -M  specify full path to AndroidManifest.xml to include in zip\n"
-        "   -P  specify where to output public resource definitions\n"
-        "   -S  directory in which to find resources.  Multiple directories will be scanned\n"
-        "       and the first match found (left to right) will take precedence.\n"
-        "   -0  specifies an additional extension for which such files will not\n"
-        "       be stored compressed in the .apk.  An empty string means to not\n"
-        "       compress any files at all.\n"
-        "   --debug-mode\n"
-        "       inserts android:debuggable=\"true\" in to the application node of the\n"
-        "       manifest, making the application debuggable even on production devices.\n"
-        "   --min-sdk-version\n"
-        "       inserts android:minSdkVersion in to manifest.  If the version is 7 or\n"
-        "       higher, the default encoding for resources will be in UTF-8.\n"
-        "   --target-sdk-version\n"
-        "       inserts android:targetSdkVersion in to manifest.\n"
-        "   --max-res-version\n"
-        "       ignores versioned resource directories above the given value.\n"
-        "   --values\n"
-        "       when used with \"dump resources\" also includes resource values.\n"
-        "   --version-code\n"
-        "       inserts android:versionCode in to manifest.\n"
-        "   --version-name\n"
-        "       inserts android:versionName in to manifest.\n"
-        "   --custom-package\n"
-        "       generates R.java into a different package.\n"
-        "   --extra-packages\n"
-        "       generate R.java for libraries. Separate libraries with ':'.\n"
-        "   --generate-dependencies\n"
-        "       generate dependency files in the same directories for R.java and resource package\n"
-        "   --auto-add-overlay\n"
-        "       Automatically add resources that are only in overlays.\n"
-        "   --preferred-configurations\n"
-        "       Like the -c option for filtering out unneeded configurations, but\n"
-        "       only expresses a preference.  If there is no resource available with\n"
-        "       the preferred configuration then it will not be stripped.\n"
-        "   --rename-manifest-package\n"
-        "       Rewrite the manifest so that its package name is the package name\n"
-        "       given here.  Relative class names (for example .Foo) will be\n"
-        "       changed to absolute names with the old package so that the code\n"
-        "       does not need to change.\n"
-        "   --rename-instrumentation-target-package\n"
-        "       Rewrite the manifest so that all of its instrumentation\n"
-        "       components target the given package.  Useful when used in\n"
-        "       conjunction with --rename-manifest-package to fix tests against\n"
-        "       a package that has been renamed.\n"
-        "   --product\n"
-        "       Specifies which variant to choose for strings that have\n"
-        "       product variants\n"
-        "   --utf16\n"
-        "       changes default encoding for resources to UTF-16.  Only useful when API\n"
-        "       level is set to 7 or higher where the default encoding is UTF-8.\n"
-        "   --non-constant-id\n"
-        "       Make the resources ID non constant. This is required to make an R java class\n"
-        "       that does not contain the final value but is used to make reusable compiled\n"
-        "       libraries that need to access resources.\n"
-        "   --error-on-failed-insert\n"
-        "       Forces aapt to return an error if it fails to insert values into the manifest\n"
-        "       with --debug-mode, --min-sdk-version, --target-sdk-version --version-code\n"
-        "       and --version-name.\n"
-        "       Insertion typically fails if the manifest already defines the attribute.\n"
-        "   --output-text-symbols\n"
-        "       Generates a text file containing the resource symbols of the R class in the\n"
-        "       specified folder.\n"
-        "   --ignore-assets\n"
-        "       Assets to be ignored. Default pattern is:\n"
-        "       %s\n",
-        gDefaultIgnoreAssets);
-}
-
-/*
- * Dispatch the command.
- */
-int handleCommand(Bundle* bundle)
-{
-    //printf("--- command %d (verbose=%d force=%d):\n",
-    //    bundle->getCommand(), bundle->getVerbose(), bundle->getForce());
-    //for (int i = 0; i < bundle->getFileSpecCount(); i++)
-    //    printf("  %d: '%s'\n", i, bundle->getFileSpecEntry(i));
-
-    switch (bundle->getCommand()) {
-    case kCommandVersion:      return doVersion(bundle);
-    case kCommandList:         return doList(bundle);
-    case kCommandDump:         return doDump(bundle);
-    case kCommandAdd:          return doAdd(bundle);
-    case kCommandRemove:       return doRemove(bundle);
-    case kCommandPackage:      return doPackage(bundle);
-    case kCommandCrunch:       return doCrunch(bundle);
-    case kCommandSingleCrunch: return doSingleCrunch(bundle);
-    default:
-        fprintf(stderr, "%s: requested command not yet supported\n", gProgName);
-        return 1;
-    }
-}
-
-/*
- * Parse args.
- */
-int main(int argc, char* const argv[])
-{
-    char *prog = argv[0];
-    Bundle bundle;
-    bool wantUsage = false;
-    int result = 1;    // pessimistically assume an error.
-    int tolerance = 0;
-
-    /* default to compression */
-    bundle.setCompressionMethod(ZipEntry::kCompressDeflated);
-
-    if (argc < 2) {
-        wantUsage = true;
-        goto bail;
-    }
-
-    if (argv[1][0] == 'v')
-        bundle.setCommand(kCommandVersion);
-    else if (argv[1][0] == 'd')
-        bundle.setCommand(kCommandDump);
-    else if (argv[1][0] == 'l')
-        bundle.setCommand(kCommandList);
-    else if (argv[1][0] == 'a')
-        bundle.setCommand(kCommandAdd);
-    else if (argv[1][0] == 'r')
-        bundle.setCommand(kCommandRemove);
-    else if (argv[1][0] == 'p')
-        bundle.setCommand(kCommandPackage);
-    else if (argv[1][0] == 'c')
-        bundle.setCommand(kCommandCrunch);
-    else if (argv[1][0] == 's')
-        bundle.setCommand(kCommandSingleCrunch);
-    else {
-        fprintf(stderr, "ERROR: Unknown command '%s'\n", argv[1]);
-        wantUsage = true;
-        goto bail;
-    }
-    argc -= 2;
-    argv += 2;
-
-    /*
-     * Pull out flags.  We support "-fv" and "-f -v".
-     */
-    while (argc && argv[0][0] == '-') {
-        /* flag(s) found */
-        const char* cp = argv[0] +1;
-
-        while (*cp != '\0') {
-            switch (*cp) {
-            case 'v':
-                bundle.setVerbose(true);
-                break;
-            case 'a':
-                bundle.setAndroidList(true);
-                break;
-            case 'c':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-c' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                bundle.addConfigurations(argv[0]);
-                break;
-            case 'f':
-                bundle.setForce(true);
-                break;
-            case 'g':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-g' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                tolerance = atoi(argv[0]);
-                bundle.setGrayscaleTolerance(tolerance);
-                printf("%s: Images with deviation <= %d will be forced to grayscale.\n", prog, tolerance);
-                break;
-            case 'k':
-                bundle.setJunkPath(true);
-                break;
-            case 'm':
-                bundle.setMakePackageDirs(true);
-                break;
-#if 0
-            case 'p':
-                bundle.setPseudolocalize(true);
-                break;
-#endif
-            case 'u':
-                bundle.setUpdate(true);
-                break;
-            case 'x':
-                bundle.setExtending(true);
-                break;
-            case 'z':
-                bundle.setRequireLocalization(true);
-                break;
-            case 'j':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-j' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                convertPath(argv[0]);
-                bundle.addJarFile(argv[0]);
-                break;
-            case 'A':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-A' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                convertPath(argv[0]);
-                bundle.setAssetSourceDir(argv[0]);
-                break;
-            case 'G':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-G' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                convertPath(argv[0]);
-                bundle.setProguardFile(argv[0]);
-                break;
-            case 'I':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-I' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                convertPath(argv[0]);
-                bundle.addPackageInclude(argv[0]);
-                break;
-            case 'F':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-F' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                convertPath(argv[0]);
-                bundle.setOutputAPKFile(argv[0]);
-                break;
-            case 'J':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-J' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                convertPath(argv[0]);
-                bundle.setRClassDir(argv[0]);
-                break;
-            case 'M':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-M' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                convertPath(argv[0]);
-                bundle.setAndroidManifestFile(argv[0]);
-                break;
-            case 'P':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-P' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                convertPath(argv[0]);
-                bundle.setPublicOutputFile(argv[0]);
-                break;
-            case 'S':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-S' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                convertPath(argv[0]);
-                bundle.addResourceSourceDir(argv[0]);
-                break;
-            case 'C':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-C' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                convertPath(argv[0]);
-                bundle.setCrunchedOutputDir(argv[0]);
-                break;
-            case 'i':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-i' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                convertPath(argv[0]);
-                bundle.setSingleCrunchInputFile(argv[0]);
-                break;
-            case 'o':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-o' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                convertPath(argv[0]);
-                bundle.setSingleCrunchOutputFile(argv[0]);
-                break;
-            case '0':
-                argc--;
-                argv++;
-                if (!argc) {
-                    fprintf(stderr, "ERROR: No argument supplied for '-e' option\n");
-                    wantUsage = true;
-                    goto bail;
-                }
-                if (argv[0][0] != 0) {
-                    bundle.addNoCompressExtension(argv[0]);
-                } else {
-                    bundle.setCompressionMethod(ZipEntry::kCompressStored);
-                }
-                break;
-            case '-':
-                if (strcmp(cp, "-debug-mode") == 0) {
-                    bundle.setDebugMode(true);
-                } else if (strcmp(cp, "-min-sdk-version") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--min-sdk-version' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.setMinSdkVersion(argv[0]);
-                } else if (strcmp(cp, "-target-sdk-version") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--target-sdk-version' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.setTargetSdkVersion(argv[0]);
-                } else if (strcmp(cp, "-max-sdk-version") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--max-sdk-version' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.setMaxSdkVersion(argv[0]);
-                } else if (strcmp(cp, "-max-res-version") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--max-res-version' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.setMaxResVersion(argv[0]);
-                } else if (strcmp(cp, "-version-code") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--version-code' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.setVersionCode(argv[0]);
-                } else if (strcmp(cp, "-version-name") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--version-name' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.setVersionName(argv[0]);
-                } else if (strcmp(cp, "-values") == 0) {
-                    bundle.setValues(true);
-                } else if (strcmp(cp, "-custom-package") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--custom-package' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.setCustomPackage(argv[0]);
-                } else if (strcmp(cp, "-extra-packages") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--extra-packages' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.setExtraPackages(argv[0]);
-                } else if (strcmp(cp, "-generate-dependencies") == 0) {
-                    bundle.setGenDependencies(true);
-                } else if (strcmp(cp, "-utf16") == 0) {
-                    bundle.setWantUTF16(true);
-                } else if (strcmp(cp, "-preferred-configurations") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--preferred-configurations' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.addPreferredConfigurations(argv[0]);
-                } else if (strcmp(cp, "-rename-manifest-package") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--rename-manifest-package' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.setManifestPackageNameOverride(argv[0]);
-                } else if (strcmp(cp, "-rename-instrumentation-target-package") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--rename-instrumentation-target-package' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.setInstrumentationPackageNameOverride(argv[0]);
-                } else if (strcmp(cp, "-auto-add-overlay") == 0) {
-                    bundle.setAutoAddOverlay(true);
-                } else if (strcmp(cp, "-error-on-failed-insert") == 0) {
-                    bundle.setErrorOnFailedInsert(true);
-                } else if (strcmp(cp, "-output-text-symbols") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '-output-text-symbols' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.setOutputTextSymbols(argv[0]);
-                } else if (strcmp(cp, "-product") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--product' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    bundle.setProduct(argv[0]);
-                } else if (strcmp(cp, "-non-constant-id") == 0) {
-                    bundle.setNonConstantId(true);
-                } else if (strcmp(cp, "-no-crunch") == 0) {
-                    bundle.setUseCrunchCache(true);
-                } else if (strcmp(cp, "-ignore-assets") == 0) {
-                    argc--;
-                    argv++;
-                    if (!argc) {
-                        fprintf(stderr, "ERROR: No argument supplied for '--ignore-assets' option\n");
-                        wantUsage = true;
-                        goto bail;
-                    }
-                    gUserIgnoreAssets = argv[0];
-                } else {
-                    fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp);
-                    wantUsage = true;
-                    goto bail;
-                }
-                cp += strlen(cp) - 1;
-                break;
-            default:
-                fprintf(stderr, "ERROR: Unknown flag '-%c'\n", *cp);
-                wantUsage = true;
-                goto bail;
-            }
-
-            cp++;
-        }
-        argc--;
-        argv++;
-    }
-
-    /*
-     * We're past the flags.  The rest all goes straight in.
-     */
-    bundle.setFileSpec(argv, argc);
-
-    result = handleCommand(&bundle);
-
-bail:
-    if (wantUsage) {
-        usage();
-        result = 2;
-    }
-
-    //printf("--> returning %d\n", result);
-    return result;
-}
diff --git a/tools/aapt/Main.h b/tools/aapt/Main.h
deleted file mode 100644
index a6b39ac..0000000
--- a/tools/aapt/Main.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Some global defines that don't really merit their own header.
-//
-#ifndef __MAIN_H
-#define __MAIN_H
-
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <utils/List.h>
-#include <utils/Errors.h>
-#include "Bundle.h"
-#include "AaptAssets.h"
-#include "ZipFile.h"
-
-
-/* Benchmarking Flag */
-//#define BENCHMARK 1
-
-#if BENCHMARK
-    #include <time.h>
-#endif /* BENCHMARK */
-
-extern int doVersion(Bundle* bundle);
-extern int doList(Bundle* bundle);
-extern int doDump(Bundle* bundle);
-extern int doAdd(Bundle* bundle);
-extern int doRemove(Bundle* bundle);
-extern int doPackage(Bundle* bundle);
-extern int doCrunch(Bundle* bundle);
-extern int doSingleCrunch(Bundle* bundle);
-
-extern int calcPercent(long uncompressedLen, long compressedLen);
-
-extern android::status_t writeAPK(Bundle* bundle,
-    const sp<AaptAssets>& assets,
-    const android::String8& outputFile);
-
-extern android::status_t updatePreProcessedCache(Bundle* bundle);
-
-extern android::status_t buildResources(Bundle* bundle,
-    const sp<AaptAssets>& assets);
-
-extern android::status_t writeResourceSymbols(Bundle* bundle,
-    const sp<AaptAssets>& assets, const String8& pkgName, bool includePrivate);
-
-extern android::status_t writeProguardFile(Bundle* bundle, const sp<AaptAssets>& assets);
-
-extern bool isValidResourceType(const String8& type);
-
-ssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<AaptAssets>& assets);
-
-extern status_t filterResources(Bundle* bundle, const sp<AaptAssets>& assets);
-
-int dumpResources(Bundle* bundle);
-
-String8 getAttribute(const ResXMLTree& tree, const char* ns,
-                            const char* attr, String8* outError);
-
-status_t writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets,
-                                FILE* fp, bool includeRaw);
-#endif // __MAIN_H
diff --git a/tools/aapt/NOTICE b/tools/aapt/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/tools/aapt/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-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.
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp
deleted file mode 100644
index 872d95c..0000000
--- a/tools/aapt/Package.cpp
+++ /dev/null
@@ -1,505 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Package assets into Zip files.
-//
-#include "Main.h"
-#include "AaptAssets.h"
-#include "ResourceTable.h"
-#include "ResourceFilter.h"
-
-#include <androidfw/misc.h>
-
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <utils/List.h>
-#include <utils/Errors.h>
-#include <utils/misc.h>
-
-#include <sys/types.h>
-#include <dirent.h>
-#include <ctype.h>
-#include <errno.h>
-
-using namespace android;
-
-static const char* kExcludeExtension = ".EXCLUDE";
-
-/* these formats are already compressed, or don't compress well */
-static const char* kNoCompressExt[] = {
-    ".jpg", ".jpeg", ".png", ".gif",
-    ".wav", ".mp2", ".mp3", ".ogg", ".aac",
-    ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
-    ".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
-    ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
-    ".amr", ".awb", ".wma", ".wmv"
-};
-
-/* fwd decls, so I can write this downward */
-ssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<AaptAssets>& assets);
-ssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<AaptDir>& dir,
-                        const AaptGroupEntry& ge, const ResourceFilter* filter);
-bool processFile(Bundle* bundle, ZipFile* zip,
-                        const sp<AaptGroup>& group, const sp<AaptFile>& file);
-bool okayToCompress(Bundle* bundle, const String8& pathName);
-ssize_t processJarFiles(Bundle* bundle, ZipFile* zip);
-
-/*
- * The directory hierarchy looks like this:
- * "outputDir" and "assetRoot" are existing directories.
- *
- * On success, "bundle->numPackages" will be the number of Zip packages
- * we created.
- */
-status_t writeAPK(Bundle* bundle, const sp<AaptAssets>& assets,
-                       const String8& outputFile)
-{
-    #if BENCHMARK
-    fprintf(stdout, "BENCHMARK: Starting APK Bundling \n");
-    long startAPKTime = clock();
-    #endif /* BENCHMARK */
-
-    status_t result = NO_ERROR;
-    ZipFile* zip = NULL;
-    int count;
-
-    //bundle->setPackageCount(0);
-
-    /*
-     * Prep the Zip archive.
-     *
-     * If the file already exists, fail unless "update" or "force" is set.
-     * If "update" is set, update the contents of the existing archive.
-     * Else, if "force" is set, remove the existing archive.
-     */
-    FileType fileType = getFileType(outputFile.string());
-    if (fileType == kFileTypeNonexistent) {
-        // okay, create it below
-    } else if (fileType == kFileTypeRegular) {
-        if (bundle->getUpdate()) {
-            // okay, open it below
-        } else if (bundle->getForce()) {
-            if (unlink(outputFile.string()) != 0) {
-                fprintf(stderr, "ERROR: unable to remove '%s': %s\n", outputFile.string(),
-                        strerror(errno));
-                goto bail;
-            }
-        } else {
-            fprintf(stderr, "ERROR: '%s' exists (use '-f' to force overwrite)\n",
-                    outputFile.string());
-            goto bail;
-        }
-    } else {
-        fprintf(stderr, "ERROR: '%s' exists and is not a regular file\n", outputFile.string());
-        goto bail;
-    }
-
-    if (bundle->getVerbose()) {
-        printf("%s '%s'\n", (fileType == kFileTypeNonexistent) ? "Creating" : "Opening",
-                outputFile.string());
-    }
-
-    status_t status;
-    zip = new ZipFile;
-    status = zip->open(outputFile.string(), ZipFile::kOpenReadWrite | ZipFile::kOpenCreate);
-    if (status != NO_ERROR) {
-        fprintf(stderr, "ERROR: unable to open '%s' as Zip file for writing\n",
-                outputFile.string());
-        goto bail;
-    }
-
-    if (bundle->getVerbose()) {
-        printf("Writing all files...\n");
-    }
-
-    count = processAssets(bundle, zip, assets);
-    if (count < 0) {
-        fprintf(stderr, "ERROR: unable to process assets while packaging '%s'\n",
-                outputFile.string());
-        result = count;
-        goto bail;
-    }
-
-    if (bundle->getVerbose()) {
-        printf("Generated %d file%s\n", count, (count==1) ? "" : "s");
-    }
-    
-    count = processJarFiles(bundle, zip);
-    if (count < 0) {
-        fprintf(stderr, "ERROR: unable to process jar files while packaging '%s'\n",
-                outputFile.string());
-        result = count;
-        goto bail;
-    }
-    
-    if (bundle->getVerbose())
-        printf("Included %d file%s from jar/zip files.\n", count, (count==1) ? "" : "s");
-    
-    result = NO_ERROR;
-
-    /*
-     * Check for cruft.  We set the "marked" flag on all entries we created
-     * or decided not to update.  If the entry isn't already slated for
-     * deletion, remove it now.
-     */
-    {
-        if (bundle->getVerbose())
-            printf("Checking for deleted files\n");
-        int i, removed = 0;
-        for (i = 0; i < zip->getNumEntries(); i++) {
-            ZipEntry* entry = zip->getEntryByIndex(i);
-
-            if (!entry->getMarked() && entry->getDeleted()) {
-                if (bundle->getVerbose()) {
-                    printf("      (removing crufty '%s')\n",
-                        entry->getFileName());
-                }
-                zip->remove(entry);
-                removed++;
-            }
-        }
-        if (bundle->getVerbose() && removed > 0)
-            printf("Removed %d file%s\n", removed, (removed==1) ? "" : "s");
-    }
-
-    /* tell Zip lib to process deletions and other pending changes */
-    result = zip->flush();
-    if (result != NO_ERROR) {
-        fprintf(stderr, "ERROR: Zip flush failed, archive may be hosed\n");
-        goto bail;
-    }
-
-    /* anything here? */
-    if (zip->getNumEntries() == 0) {
-        if (bundle->getVerbose()) {
-            printf("Archive is empty -- removing %s\n", outputFile.getPathLeaf().string());
-        }
-        delete zip;        // close the file so we can remove it in Win32
-        zip = NULL;
-        if (unlink(outputFile.string()) != 0) {
-            fprintf(stderr, "warning: could not unlink '%s'\n", outputFile.string());
-        }
-    }
-
-    // If we've been asked to generate a dependency file for the .ap_ package,
-    // do so here
-    if (bundle->getGenDependencies()) {
-        // The dependency file gets output to the same directory
-        // as the specified output file with an additional .d extension.
-        // e.g. bin/resources.ap_.d
-        String8 dependencyFile = outputFile;
-        dependencyFile.append(".d");
-
-        FILE* fp = fopen(dependencyFile.string(), "a");
-        // Add this file to the dependency file
-        fprintf(fp, "%s \\\n", outputFile.string());
-        fclose(fp);
-    }
-
-    assert(result == NO_ERROR);
-
-bail:
-    delete zip;        // must close before remove in Win32
-    if (result != NO_ERROR) {
-        if (bundle->getVerbose()) {
-            printf("Removing %s due to earlier failures\n", outputFile.string());
-        }
-        if (unlink(outputFile.string()) != 0) {
-            fprintf(stderr, "warning: could not unlink '%s'\n", outputFile.string());
-        }
-    }
-
-    if (result == NO_ERROR && bundle->getVerbose())
-        printf("Done!\n");
-
-    #if BENCHMARK
-    fprintf(stdout, "BENCHMARK: End APK Bundling. Time Elapsed: %f ms \n",(clock() - startAPKTime)/1000.0);
-    #endif /* BENCHMARK */
-    return result;
-}
-
-ssize_t processAssets(Bundle* bundle, ZipFile* zip,
-                      const sp<AaptAssets>& assets)
-{
-    ResourceFilter filter;
-    status_t status = filter.parse(bundle->getConfigurations());
-    if (status != NO_ERROR) {
-        return -1;
-    }
-
-    ssize_t count = 0;
-
-    const size_t N = assets->getGroupEntries().size();
-    for (size_t i=0; i<N; i++) {
-        const AaptGroupEntry& ge = assets->getGroupEntries()[i];
-
-        ssize_t res = processAssets(bundle, zip, assets, ge, &filter);
-        if (res < 0) {
-            return res;
-        }
-
-        count += res;
-    }
-
-    return count;
-}
-
-ssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<AaptDir>& dir,
-        const AaptGroupEntry& ge, const ResourceFilter* filter)
-{
-    ssize_t count = 0;
-
-    const size_t ND = dir->getDirs().size();
-    size_t i;
-    for (i=0; i<ND; i++) {
-        const sp<AaptDir>& subDir = dir->getDirs().valueAt(i);
-
-        const bool filterable = filter != NULL && subDir->getLeaf().find("mipmap-") != 0;
-
-        if (filterable && subDir->getLeaf() != subDir->getPath() && !filter->match(ge.toParams())) {
-            continue;
-        }
-
-        ssize_t res = processAssets(bundle, zip, subDir, ge, filterable ? filter : NULL);
-        if (res < 0) {
-            return res;
-        }
-        count += res;
-    }
-
-    if (filter != NULL && !filter->match(ge.toParams())) {
-        return count;
-    }
-
-    const size_t NF = dir->getFiles().size();
-    for (i=0; i<NF; i++) {
-        sp<AaptGroup> gp = dir->getFiles().valueAt(i);
-        ssize_t fi = gp->getFiles().indexOfKey(ge);
-        if (fi >= 0) {
-            sp<AaptFile> fl = gp->getFiles().valueAt(fi);
-            if (!processFile(bundle, zip, gp, fl)) {
-                return UNKNOWN_ERROR;
-            }
-            count++;
-        }
-    }
-
-    return count;
-}
-
-/*
- * Process a regular file, adding it to the archive if appropriate.
- *
- * If we're in "update" mode, and the file already exists in the archive,
- * delete the existing entry before adding the new one.
- */
-bool processFile(Bundle* bundle, ZipFile* zip,
-                 const sp<AaptGroup>& group, const sp<AaptFile>& file)
-{
-    const bool hasData = file->hasData();
-
-    String8 storageName(group->getPath());
-    storageName.convertToResPath();
-    ZipEntry* entry;
-    bool fromGzip = false;
-    status_t result;
-
-    /*
-     * See if the filename ends in ".EXCLUDE".  We can't use
-     * String8::getPathExtension() because the length of what it considers
-     * to be an extension is capped.
-     *
-     * The Asset Manager doesn't check for ".EXCLUDE" in Zip archives,
-     * so there's no value in adding them (and it makes life easier on
-     * the AssetManager lib if we don't).
-     *
-     * NOTE: this restriction has been removed.  If you're in this code, you
-     * should clean this up, but I'm in here getting rid of Path Name, and I
-     * don't want to make other potentially breaking changes --joeo
-     */
-    int fileNameLen = storageName.length();
-    int excludeExtensionLen = strlen(kExcludeExtension);
-    if (fileNameLen > excludeExtensionLen
-            && (0 == strcmp(storageName.string() + (fileNameLen - excludeExtensionLen),
-                            kExcludeExtension))) {
-        fprintf(stderr, "warning: '%s' not added to Zip\n", storageName.string());
-        return true;
-    }
-
-    if (strcasecmp(storageName.getPathExtension().string(), ".gz") == 0) {
-        fromGzip = true;
-        storageName = storageName.getBasePath();
-    }
-
-    if (bundle->getUpdate()) {
-        entry = zip->getEntryByName(storageName.string());
-        if (entry != NULL) {
-            /* file already exists in archive; there can be only one */
-            if (entry->getMarked()) {
-                fprintf(stderr,
-                        "ERROR: '%s' exists twice (check for with & w/o '.gz'?)\n",
-                        file->getPrintableSource().string());
-                return false;
-            }
-            if (!hasData) {
-                const String8& srcName = file->getSourceFile();
-                time_t fileModWhen;
-                fileModWhen = getFileModDate(srcName.string());
-                if (fileModWhen == (time_t) -1) { // file existence tested earlier,
-                    return false;                 //  not expecting an error here
-                }
-    
-                if (fileModWhen > entry->getModWhen()) {
-                    // mark as deleted so add() will succeed
-                    if (bundle->getVerbose()) {
-                        printf("      (removing old '%s')\n", storageName.string());
-                    }
-    
-                    zip->remove(entry);
-                } else {
-                    // version in archive is newer
-                    if (bundle->getVerbose()) {
-                        printf("      (not updating '%s')\n", storageName.string());
-                    }
-                    entry->setMarked(true);
-                    return true;
-                }
-            } else {
-                // Generated files are always replaced.
-                zip->remove(entry);
-            }
-        }
-    }
-
-    //android_setMinPriority(NULL, ANDROID_LOG_VERBOSE);
-
-    if (fromGzip) {
-        result = zip->addGzip(file->getSourceFile().string(), storageName.string(), &entry);
-    } else if (!hasData) {
-        /* don't compress certain files, e.g. PNGs */
-        int compressionMethod = bundle->getCompressionMethod();
-        if (!okayToCompress(bundle, storageName)) {
-            compressionMethod = ZipEntry::kCompressStored;
-        }
-        result = zip->add(file->getSourceFile().string(), storageName.string(), compressionMethod,
-                            &entry);
-    } else {
-        result = zip->add(file->getData(), file->getSize(), storageName.string(),
-                           file->getCompressionMethod(), &entry);
-    }
-    if (result == NO_ERROR) {
-        if (bundle->getVerbose()) {
-            printf("      '%s'%s", storageName.string(), fromGzip ? " (from .gz)" : "");
-            if (entry->getCompressionMethod() == ZipEntry::kCompressStored) {
-                printf(" (not compressed)\n");
-            } else {
-                printf(" (compressed %d%%)\n", calcPercent(entry->getUncompressedLen(),
-                            entry->getCompressedLen()));
-            }
-        }
-        entry->setMarked(true);
-    } else {
-        if (result == ALREADY_EXISTS) {
-            fprintf(stderr, "      Unable to add '%s': file already in archive (try '-u'?)\n",
-                    file->getPrintableSource().string());
-        } else {
-            fprintf(stderr, "      Unable to add '%s': Zip add failed\n", 
-                    file->getPrintableSource().string());
-        }
-        return false;
-    }
-
-    return true;
-}
-
-/*
- * Determine whether or not we want to try to compress this file based
- * on the file extension.
- */
-bool okayToCompress(Bundle* bundle, const String8& pathName)
-{
-    String8 ext = pathName.getPathExtension();
-    int i;
-
-    if (ext.length() == 0)
-        return true;
-
-    for (i = 0; i < NELEM(kNoCompressExt); i++) {
-        if (strcasecmp(ext.string(), kNoCompressExt[i]) == 0)
-            return false;
-    }
-
-    const android::Vector<const char*>& others(bundle->getNoCompressExtensions());
-    for (i = 0; i < (int)others.size(); i++) {
-        const char* str = others[i];
-        int pos = pathName.length() - strlen(str);
-        if (pos < 0) {
-            continue;
-        }
-        const char* path = pathName.string();
-        if (strcasecmp(path + pos, str) == 0) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool endsWith(const char* haystack, const char* needle)
-{
-    size_t a = strlen(haystack);
-    size_t b = strlen(needle);
-    if (a < b) return false;
-    return strcasecmp(haystack+(a-b), needle) == 0;
-}
-
-ssize_t processJarFile(ZipFile* jar, ZipFile* out)
-{
-    status_t err;
-    size_t N = jar->getNumEntries();
-    size_t count = 0;
-    for (size_t i=0; i<N; i++) {
-        ZipEntry* entry = jar->getEntryByIndex(i);
-        const char* storageName = entry->getFileName();
-        if (endsWith(storageName, ".class")) {
-            int compressionMethod = entry->getCompressionMethod();
-            size_t size = entry->getUncompressedLen();
-            const void* data = jar->uncompress(entry);
-            if (data == NULL) {
-                fprintf(stderr, "ERROR: unable to uncompress entry '%s'\n",
-                    storageName);
-                return -1;
-            }
-            out->add(data, size, storageName, compressionMethod, NULL);
-            free((void*)data);
-        }
-        count++;
-    }
-    return count;
-}
-
-ssize_t processJarFiles(Bundle* bundle, ZipFile* zip)
-{
-    status_t err;
-    ssize_t count = 0;
-    const android::Vector<const char*>& jars = bundle->getJarFiles();
-
-    size_t N = jars.size();
-    for (size_t i=0; i<N; i++) {
-        ZipFile jar;
-        err = jar.open(jars[i], ZipFile::kOpenReadOnly);
-        if (err != 0) {
-            fprintf(stderr, "ERROR: unable to open '%s' as a zip file: %d\n",
-                jars[i], err);
-            return err;
-        }
-        err += processJarFile(&jar, zip);
-        if (err < 0) {
-            fprintf(stderr, "ERROR: unable to process '%s'\n", jars[i]);
-            return err;
-        }
-        count += err;
-    }
-
-    return count;
-}
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
deleted file mode 100644
index 08ad7a0..0000000
--- a/tools/aapt/Resource.cpp
+++ /dev/null
@@ -1,2651 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Build resource files from raw assets.
-//
-#include "Main.h"
-#include "AaptAssets.h"
-#include "StringPool.h"
-#include "XMLNode.h"
-#include "ResourceTable.h"
-#include "Images.h"
-
-#include "CrunchCache.h"
-#include "FileFinder.h"
-#include "CacheUpdater.h"
-
-#include "WorkQueue.h"
-
-#if HAVE_PRINTF_ZD
-#  define ZD "%zd"
-#  define ZD_TYPE ssize_t
-#else
-#  define ZD "%ld"
-#  define ZD_TYPE long
-#endif
-
-#define NOISY(x) // x
-
-// Number of threads to use for preprocessing images.
-static const size_t MAX_THREADS = 4;
-
-// ==========================================================================
-// ==========================================================================
-// ==========================================================================
-
-class PackageInfo
-{
-public:
-    PackageInfo()
-    {
-    }
-    ~PackageInfo()
-    {
-    }
-
-    status_t parsePackage(const sp<AaptGroup>& grp);
-};
-
-// ==========================================================================
-// ==========================================================================
-// ==========================================================================
-
-static String8 parseResourceName(const String8& leaf)
-{
-    const char* firstDot = strchr(leaf.string(), '.');
-    const char* str = leaf.string();
-
-    if (firstDot) {
-        return String8(str, firstDot-str);
-    } else {
-        return String8(str);
-    }
-}
-
-ResourceTypeSet::ResourceTypeSet()
-    :RefBase(),
-     KeyedVector<String8,sp<AaptGroup> >()
-{
-}
-
-FilePathStore::FilePathStore()
-    :RefBase(),
-     Vector<String8>()
-{
-}
-
-class ResourceDirIterator
-{
-public:
-    ResourceDirIterator(const sp<ResourceTypeSet>& set, const String8& resType)
-        : mResType(resType), mSet(set), mSetPos(0), mGroupPos(0)
-    {
-    }
-
-    inline const sp<AaptGroup>& getGroup() const { return mGroup; }
-    inline const sp<AaptFile>& getFile() const { return mFile; }
-
-    inline const String8& getBaseName() const { return mBaseName; }
-    inline const String8& getLeafName() const { return mLeafName; }
-    inline String8 getPath() const { return mPath; }
-    inline const ResTable_config& getParams() const { return mParams; }
-
-    enum {
-        EOD = 1
-    };
-
-    ssize_t next()
-    {
-        while (true) {
-            sp<AaptGroup> group;
-            sp<AaptFile> file;
-
-            // Try to get next file in this current group.
-            if (mGroup != NULL && mGroupPos < mGroup->getFiles().size()) {
-                group = mGroup;
-                file = group->getFiles().valueAt(mGroupPos++);
-
-            // Try to get the next group/file in this directory
-            } else if (mSetPos < mSet->size()) {
-                mGroup = group = mSet->valueAt(mSetPos++);
-                if (group->getFiles().size() < 1) {
-                    continue;
-                }
-                file = group->getFiles().valueAt(0);
-                mGroupPos = 1;
-
-            // All done!
-            } else {
-                return EOD;
-            }
-
-            mFile = file;
-
-            String8 leaf(group->getLeaf());
-            mLeafName = String8(leaf);
-            mParams = file->getGroupEntry().toParams();
-            NOISY(printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d ui=%d density=%d touch=%d key=%d inp=%d nav=%d\n",
-                   group->getPath().string(), mParams.mcc, mParams.mnc,
-                   mParams.language[0] ? mParams.language[0] : '-',
-                   mParams.language[1] ? mParams.language[1] : '-',
-                   mParams.country[0] ? mParams.country[0] : '-',
-                   mParams.country[1] ? mParams.country[1] : '-',
-                   mParams.orientation, mParams.uiMode,
-                   mParams.density, mParams.touchscreen, mParams.keyboard,
-                   mParams.inputFlags, mParams.navigation));
-            mPath = "res";
-            mPath.appendPath(file->getGroupEntry().toDirName(mResType));
-            mPath.appendPath(leaf);
-            mBaseName = parseResourceName(leaf);
-            if (mBaseName == "") {
-                fprintf(stderr, "Error: malformed resource filename %s\n",
-                        file->getPrintableSource().string());
-                return UNKNOWN_ERROR;
-            }
-
-            NOISY(printf("file name=%s\n", mBaseName.string()));
-
-            return NO_ERROR;
-        }
-    }
-
-private:
-    String8 mResType;
-
-    const sp<ResourceTypeSet> mSet;
-    size_t mSetPos;
-
-    sp<AaptGroup> mGroup;
-    size_t mGroupPos;
-
-    sp<AaptFile> mFile;
-    String8 mBaseName;
-    String8 mLeafName;
-    String8 mPath;
-    ResTable_config mParams;
-};
-
-// ==========================================================================
-// ==========================================================================
-// ==========================================================================
-
-bool isValidResourceType(const String8& type)
-{
-    return type == "anim" || type == "animator" || type == "interpolator"
-        || type == "transition"
-        || type == "drawable" || type == "layout"
-        || type == "values" || type == "xml" || type == "raw"
-        || type == "color" || type == "menu" || type == "mipmap";
-}
-
-static sp<AaptFile> getResourceFile(const sp<AaptAssets>& assets, bool makeIfNecessary=true)
-{
-    sp<AaptGroup> group = assets->getFiles().valueFor(String8("resources.arsc"));
-    sp<AaptFile> file;
-    if (group != NULL) {
-        file = group->getFiles().valueFor(AaptGroupEntry());
-        if (file != NULL) {
-            return file;
-        }
-    }
-
-    if (!makeIfNecessary) {
-        return NULL;
-    }
-    return assets->addFile(String8("resources.arsc"), AaptGroupEntry(), String8(),
-                            NULL, String8());
-}
-
-static status_t parsePackage(Bundle* bundle, const sp<AaptAssets>& assets,
-    const sp<AaptGroup>& grp)
-{
-    if (grp->getFiles().size() != 1) {
-        fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n",
-                grp->getFiles().valueAt(0)->getPrintableSource().string());
-    }
-
-    sp<AaptFile> file = grp->getFiles().valueAt(0);
-
-    ResXMLTree block;
-    status_t err = parseXMLResource(file, &block);
-    if (err != NO_ERROR) {
-        return err;
-    }
-    //printXMLBlock(&block);
-
-    ResXMLTree::event_code_t code;
-    while ((code=block.next()) != ResXMLTree::START_TAG
-           && code != ResXMLTree::END_DOCUMENT
-           && code != ResXMLTree::BAD_DOCUMENT) {
-    }
-
-    size_t len;
-    if (code != ResXMLTree::START_TAG) {
-        fprintf(stderr, "%s:%d: No start tag found\n",
-                file->getPrintableSource().string(), block.getLineNumber());
-        return UNKNOWN_ERROR;
-    }
-    if (strcmp16(block.getElementName(&len), String16("manifest").string()) != 0) {
-        fprintf(stderr, "%s:%d: Invalid start tag %s, expected <manifest>\n",
-                file->getPrintableSource().string(), block.getLineNumber(),
-                String8(block.getElementName(&len)).string());
-        return UNKNOWN_ERROR;
-    }
-
-    ssize_t nameIndex = block.indexOfAttribute(NULL, "package");
-    if (nameIndex < 0) {
-        fprintf(stderr, "%s:%d: <manifest> does not have package attribute.\n",
-                file->getPrintableSource().string(), block.getLineNumber());
-        return UNKNOWN_ERROR;
-    }
-
-    assets->setPackage(String8(block.getAttributeStringValue(nameIndex, &len)));
-
-    String16 uses_sdk16("uses-sdk");
-    while ((code=block.next()) != ResXMLTree::END_DOCUMENT
-           && code != ResXMLTree::BAD_DOCUMENT) {
-        if (code == ResXMLTree::START_TAG) {
-            if (strcmp16(block.getElementName(&len), uses_sdk16.string()) == 0) {
-                ssize_t minSdkIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE,
-                                                             "minSdkVersion");
-                if (minSdkIndex >= 0) {
-                    const uint16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len);
-                    const char* minSdk8 = strdup(String8(minSdk16).string());
-                    bundle->setManifestMinSdkVersion(minSdk8);
-                }
-            }
-        }
-    }
-
-    return NO_ERROR;
-}
-
-// ==========================================================================
-// ==========================================================================
-// ==========================================================================
-
-static status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets,
-                                  ResourceTable* table,
-                                  const sp<ResourceTypeSet>& set,
-                                  const char* resType)
-{
-    String8 type8(resType);
-    String16 type16(resType);
-
-    bool hasErrors = false;
-
-    ResourceDirIterator it(set, String8(resType));
-    ssize_t res;
-    while ((res=it.next()) == NO_ERROR) {
-        if (bundle->getVerbose()) {
-            printf("    (new resource id %s from %s)\n",
-                   it.getBaseName().string(), it.getFile()->getPrintableSource().string());
-        }
-        String16 baseName(it.getBaseName());
-        const char16_t* str = baseName.string();
-        const char16_t* const end = str + baseName.size();
-        while (str < end) {
-            if (!((*str >= 'a' && *str <= 'z')
-                    || (*str >= '0' && *str <= '9')
-                    || *str == '_' || *str == '.')) {
-                fprintf(stderr, "%s: Invalid file name: must contain only [a-z0-9_.]\n",
-                        it.getPath().string());
-                hasErrors = true;
-            }
-            str++;
-        }
-        String8 resPath = it.getPath();
-        resPath.convertToResPath();
-        table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),
-                        type16,
-                        baseName,
-                        String16(resPath),
-                        NULL,
-                        &it.getParams());
-        assets->addResource(it.getLeafName(), resPath, it.getFile(), type8);
-    }
-
-    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
-}
-
-class PreProcessImageWorkUnit : public WorkQueue::WorkUnit {
-public:
-    PreProcessImageWorkUnit(const Bundle* bundle, const sp<AaptAssets>& assets,
-            const sp<AaptFile>& file, volatile bool* hasErrors) :
-            mBundle(bundle), mAssets(assets), mFile(file), mHasErrors(hasErrors) {
-    }
-
-    virtual bool run() {
-        status_t status = preProcessImage(mBundle, mAssets, mFile, NULL);
-        if (status) {
-            *mHasErrors = true;
-        }
-        return true; // continue even if there are errors
-    }
-
-private:
-    const Bundle* mBundle;
-    sp<AaptAssets> mAssets;
-    sp<AaptFile> mFile;
-    volatile bool* mHasErrors;
-};
-
-static status_t preProcessImages(const Bundle* bundle, const sp<AaptAssets>& assets,
-                          const sp<ResourceTypeSet>& set, const char* type)
-{
-    volatile bool hasErrors = false;
-    ssize_t res = NO_ERROR;
-    if (bundle->getUseCrunchCache() == false) {
-        WorkQueue wq(MAX_THREADS, false);
-        ResourceDirIterator it(set, String8(type));
-        while ((res=it.next()) == NO_ERROR) {
-            PreProcessImageWorkUnit* w = new PreProcessImageWorkUnit(
-                    bundle, assets, it.getFile(), &hasErrors);
-            status_t status = wq.schedule(w);
-            if (status) {
-                fprintf(stderr, "preProcessImages failed: schedule() returned %d\n", status);
-                hasErrors = true;
-                delete w;
-                break;
-            }
-        }
-        status_t status = wq.finish();
-        if (status) {
-            fprintf(stderr, "preProcessImages failed: finish() returned %d\n", status);
-            hasErrors = true;
-        }
-    }
-    return (hasErrors || (res < NO_ERROR)) ? UNKNOWN_ERROR : NO_ERROR;
-}
-
-status_t postProcessImages(const sp<AaptAssets>& assets,
-                           ResourceTable* table,
-                           const sp<ResourceTypeSet>& set)
-{
-    ResourceDirIterator it(set, String8("drawable"));
-    bool hasErrors = false;
-    ssize_t res;
-    while ((res=it.next()) == NO_ERROR) {
-        res = postProcessImage(assets, table, it.getFile());
-        if (res < NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    return (hasErrors || (res < NO_ERROR)) ? UNKNOWN_ERROR : NO_ERROR;
-}
-
-static void collect_files(const sp<AaptDir>& dir,
-        KeyedVector<String8, sp<ResourceTypeSet> >* resources)
-{
-    const DefaultKeyedVector<String8, sp<AaptGroup> >& groups = dir->getFiles();
-    int N = groups.size();
-    for (int i=0; i<N; i++) {
-        String8 leafName = groups.keyAt(i);
-        const sp<AaptGroup>& group = groups.valueAt(i);
-
-        const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files
-                = group->getFiles();
-
-        if (files.size() == 0) {
-            continue;
-        }
-
-        String8 resType = files.valueAt(0)->getResourceType();
-
-        ssize_t index = resources->indexOfKey(resType);
-
-        if (index < 0) {
-            sp<ResourceTypeSet> set = new ResourceTypeSet();
-            NOISY(printf("Creating new resource type set for leaf %s with group %s (%p)\n",
-                    leafName.string(), group->getPath().string(), group.get()));
-            set->add(leafName, group);
-            resources->add(resType, set);
-        } else {
-            sp<ResourceTypeSet> set = resources->valueAt(index);
-            index = set->indexOfKey(leafName);
-            if (index < 0) {
-                NOISY(printf("Adding to resource type set for leaf %s group %s (%p)\n",
-                        leafName.string(), group->getPath().string(), group.get()));
-                set->add(leafName, group);
-            } else {
-                sp<AaptGroup> existingGroup = set->valueAt(index);
-                NOISY(printf("Extending to resource type set for leaf %s group %s (%p)\n",
-                        leafName.string(), group->getPath().string(), group.get()));
-                for (size_t j=0; j<files.size(); j++) {
-                    NOISY(printf("Adding file %s in group %s resType %s\n",
-                        files.valueAt(j)->getSourceFile().string(),
-                        files.keyAt(j).toDirName(String8()).string(),
-                        resType.string()));
-                    status_t err = existingGroup->addFile(files.valueAt(j));
-                }
-            }
-        }
-    }
-}
-
-static void collect_files(const sp<AaptAssets>& ass,
-        KeyedVector<String8, sp<ResourceTypeSet> >* resources)
-{
-    const Vector<sp<AaptDir> >& dirs = ass->resDirs();
-    int N = dirs.size();
-
-    for (int i=0; i<N; i++) {
-        sp<AaptDir> d = dirs.itemAt(i);
-        NOISY(printf("Collecting dir #%d %p: %s, leaf %s\n", i, d.get(), d->getPath().string(),
-                d->getLeaf().string()));
-        collect_files(d, resources);
-
-        // don't try to include the res dir
-        NOISY(printf("Removing dir leaf %s\n", d->getLeaf().string()));
-        ass->removeDir(d->getLeaf());
-    }
-}
-
-enum {
-    ATTR_OKAY = -1,
-    ATTR_NOT_FOUND = -2,
-    ATTR_LEADING_SPACES = -3,
-    ATTR_TRAILING_SPACES = -4
-};
-static int validateAttr(const String8& path, const ResTable& table,
-        const ResXMLParser& parser,
-        const char* ns, const char* attr, const char* validChars, bool required)
-{
-    size_t len;
-
-    ssize_t index = parser.indexOfAttribute(ns, attr);
-    const uint16_t* str;
-    Res_value value;
-    if (index >= 0 && parser.getAttributeValue(index, &value) >= 0) {
-        const ResStringPool* pool = &parser.getStrings();
-        if (value.dataType == Res_value::TYPE_REFERENCE) {
-            uint32_t specFlags = 0;
-            int strIdx;
-            if ((strIdx=table.resolveReference(&value, 0x10000000, NULL, &specFlags)) < 0) {
-                fprintf(stderr, "%s:%d: Tag <%s> attribute %s references unknown resid 0x%08x.\n",
-                        path.string(), parser.getLineNumber(),
-                        String8(parser.getElementName(&len)).string(), attr,
-                        value.data);
-                return ATTR_NOT_FOUND;
-            }
-            
-            pool = table.getTableStringBlock(strIdx);
-            #if 0
-            if (pool != NULL) {
-                str = pool->stringAt(value.data, &len);
-            }
-            printf("***** RES ATTR: %s specFlags=0x%x strIdx=%d: %s\n", attr,
-                    specFlags, strIdx, str != NULL ? String8(str).string() : "???");
-            #endif
-            if ((specFlags&~ResTable_typeSpec::SPEC_PUBLIC) != 0 && false) {
-                fprintf(stderr, "%s:%d: Tag <%s> attribute %s varies by configurations 0x%x.\n",
-                        path.string(), parser.getLineNumber(),
-                        String8(parser.getElementName(&len)).string(), attr,
-                        specFlags);
-                return ATTR_NOT_FOUND;
-            }
-        }
-        if (value.dataType == Res_value::TYPE_STRING) {
-            if (pool == NULL) {
-                fprintf(stderr, "%s:%d: Tag <%s> attribute %s has no string block.\n",
-                        path.string(), parser.getLineNumber(),
-                        String8(parser.getElementName(&len)).string(), attr);
-                return ATTR_NOT_FOUND;
-            }
-            if ((str=pool->stringAt(value.data, &len)) == NULL) {
-                fprintf(stderr, "%s:%d: Tag <%s> attribute %s has corrupt string value.\n",
-                        path.string(), parser.getLineNumber(),
-                        String8(parser.getElementName(&len)).string(), attr);
-                return ATTR_NOT_FOUND;
-            }
-        } else {
-            fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid type %d.\n",
-                    path.string(), parser.getLineNumber(),
-                    String8(parser.getElementName(&len)).string(), attr,
-                    value.dataType);
-            return ATTR_NOT_FOUND;
-        }
-        if (validChars) {
-            for (size_t i=0; i<len; i++) {
-                uint16_t c = str[i];
-                const char* p = validChars;
-                bool okay = false;
-                while (*p) {
-                    if (c == *p) {
-                        okay = true;
-                        break;
-                    }
-                    p++;
-                }
-                if (!okay) {
-                    fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid character '%c'.\n",
-                            path.string(), parser.getLineNumber(),
-                            String8(parser.getElementName(&len)).string(), attr, (char)str[i]);
-                    return (int)i;
-                }
-            }
-        }
-        if (*str == ' ') {
-            fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not start with a space.\n",
-                    path.string(), parser.getLineNumber(),
-                    String8(parser.getElementName(&len)).string(), attr);
-            return ATTR_LEADING_SPACES;
-        }
-        if (str[len-1] == ' ') {
-            fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not end with a space.\n",
-                    path.string(), parser.getLineNumber(),
-                    String8(parser.getElementName(&len)).string(), attr);
-            return ATTR_TRAILING_SPACES;
-        }
-        return ATTR_OKAY;
-    }
-    if (required) {
-        fprintf(stderr, "%s:%d: Tag <%s> missing required attribute %s.\n",
-                path.string(), parser.getLineNumber(),
-                String8(parser.getElementName(&len)).string(), attr);
-        return ATTR_NOT_FOUND;
-    }
-    return ATTR_OKAY;
-}
-
-static void checkForIds(const String8& path, ResXMLParser& parser)
-{
-    ResXMLTree::event_code_t code;
-    while ((code=parser.next()) != ResXMLTree::END_DOCUMENT
-           && code > ResXMLTree::BAD_DOCUMENT) {
-        if (code == ResXMLTree::START_TAG) {
-            ssize_t index = parser.indexOfAttribute(NULL, "id");
-            if (index >= 0) {
-                fprintf(stderr, "%s:%d: warning: found plain 'id' attribute; did you mean the new 'android:id' name?\n",
-                        path.string(), parser.getLineNumber());
-            }
-        }
-    }
-}
-
-static bool applyFileOverlay(Bundle *bundle,
-                             const sp<AaptAssets>& assets,
-                             sp<ResourceTypeSet> *baseSet,
-                             const char *resType)
-{
-    if (bundle->getVerbose()) {
-        printf("applyFileOverlay for %s\n", resType);
-    }
-
-    // Replace any base level files in this category with any found from the overlay
-    // Also add any found only in the overlay.
-    sp<AaptAssets> overlay = assets->getOverlay();
-    String8 resTypeString(resType);
-
-    // work through the linked list of overlays
-    while (overlay.get()) {
-        KeyedVector<String8, sp<ResourceTypeSet> >* overlayRes = overlay->getResources();
-
-        // get the overlay resources of the requested type
-        ssize_t index = overlayRes->indexOfKey(resTypeString);
-        if (index >= 0) {
-            sp<ResourceTypeSet> overlaySet = overlayRes->valueAt(index);
-
-            // for each of the resources, check for a match in the previously built
-            // non-overlay "baseset".
-            size_t overlayCount = overlaySet->size();
-            for (size_t overlayIndex=0; overlayIndex<overlayCount; overlayIndex++) {
-                if (bundle->getVerbose()) {
-                    printf("trying overlaySet Key=%s\n",overlaySet->keyAt(overlayIndex).string());
-                }
-                size_t baseIndex = UNKNOWN_ERROR;
-                if (baseSet->get() != NULL) {
-                    baseIndex = (*baseSet)->indexOfKey(overlaySet->keyAt(overlayIndex));
-                }
-                if (baseIndex < UNKNOWN_ERROR) {
-                    // look for same flavor.  For a given file (strings.xml, for example)
-                    // there may be a locale specific or other flavors - we want to match
-                    // the same flavor.
-                    sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);
-                    sp<AaptGroup> baseGroup = (*baseSet)->valueAt(baseIndex);
-
-                    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =
-                            overlayGroup->getFiles();
-                    if (bundle->getVerbose()) {
-                        DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles =
-                                baseGroup->getFiles();
-                        for (size_t i=0; i < baseFiles.size(); i++) {
-                            printf("baseFile " ZD " has flavor %s\n", (ZD_TYPE) i,
-                                    baseFiles.keyAt(i).toString().string());
-                        }
-                        for (size_t i=0; i < overlayFiles.size(); i++) {
-                            printf("overlayFile " ZD " has flavor %s\n", (ZD_TYPE) i,
-                                    overlayFiles.keyAt(i).toString().string());
-                        }
-                    }
-
-                    size_t overlayGroupSize = overlayFiles.size();
-                    for (size_t overlayGroupIndex = 0;
-                            overlayGroupIndex<overlayGroupSize;
-                            overlayGroupIndex++) {
-                        size_t baseFileIndex =
-                                baseGroup->getFiles().indexOfKey(overlayFiles.
-                                keyAt(overlayGroupIndex));
-                        if (baseFileIndex < UNKNOWN_ERROR) {
-                            if (bundle->getVerbose()) {
-                                printf("found a match (" ZD ") for overlay file %s, for flavor %s\n",
-                                        (ZD_TYPE) baseFileIndex,
-                                        overlayGroup->getLeaf().string(),
-                                        overlayFiles.keyAt(overlayGroupIndex).toString().string());
-                            }
-                            baseGroup->removeFile(baseFileIndex);
-                        } else {
-                            // didn't find a match fall through and add it..
-                            if (true || bundle->getVerbose()) {
-                                printf("nothing matches overlay file %s, for flavor %s\n",
-                                        overlayGroup->getLeaf().string(),
-                                        overlayFiles.keyAt(overlayGroupIndex).toString().string());
-                            }
-                        }
-                        baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex));
-                        assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));
-                    }
-                } else {
-                    if (baseSet->get() == NULL) {
-                        *baseSet = new ResourceTypeSet();
-                        assets->getResources()->add(String8(resType), *baseSet);
-                    }
-                    // this group doesn't exist (a file that's only in the overlay)
-                    (*baseSet)->add(overlaySet->keyAt(overlayIndex),
-                            overlaySet->valueAt(overlayIndex));
-                    // make sure all flavors are defined in the resources.
-                    sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);
-                    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =
-                            overlayGroup->getFiles();
-                    size_t overlayGroupSize = overlayFiles.size();
-                    for (size_t overlayGroupIndex = 0;
-                            overlayGroupIndex<overlayGroupSize;
-                            overlayGroupIndex++) {
-                        assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));
-                    }
-                }
-            }
-            // this overlay didn't have resources for this type
-        }
-        // try next overlay
-        overlay = overlay->getOverlay();
-    }
-    return true;
-}
-
-/*
- * Inserts an attribute in a given node, only if the attribute does not
- * exist.
- * If errorOnFailedInsert is true, and the attribute already exists, returns false.
- * Returns true otherwise, even if the attribute already exists.
- */
-bool addTagAttribute(const sp<XMLNode>& node, const char* ns8,
-        const char* attr8, const char* value, bool errorOnFailedInsert)
-{
-    if (value == NULL) {
-        return true;
-    }
-
-    const String16 ns(ns8);
-    const String16 attr(attr8);
-
-    if (node->getAttribute(ns, attr) != NULL) {
-        if (errorOnFailedInsert) {
-            fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);"
-                            " cannot insert new value %s.\n",
-                    String8(attr).string(), String8(ns).string(), value);
-            return false;
-        }
-
-        fprintf(stderr, "Warning: AndroidManifest.xml already defines %s (in %s);"
-                        " using existing value in manifest.\n",
-                String8(attr).string(), String8(ns).string());
-
-        // don't stop the build.
-        return true;
-    }
-    
-    node->addAttribute(ns, attr, String16(value));
-    return true;
-}
-
-static void fullyQualifyClassName(const String8& package, sp<XMLNode> node,
-        const String16& attrName) {
-    XMLNode::attribute_entry* attr = node->editAttribute(
-            String16("http://schemas.android.com/apk/res/android"), attrName);
-    if (attr != NULL) {
-        String8 name(attr->string);
-
-        // asdf     --> package.asdf
-        // .asdf  .a.b  --> package.asdf package.a.b
-        // asdf.adsf --> asdf.asdf
-        String8 className;
-        const char* p = name.string();
-        const char* q = strchr(p, '.');
-        if (p == q) {
-            className += package;
-            className += name;
-        } else if (q == NULL) {
-            className += package;
-            className += ".";
-            className += name;
-        } else {
-            className += name;
-        }
-        NOISY(printf("Qualifying class '%s' to '%s'", name.string(), className.string()));
-        attr->string.setTo(String16(className));
-    }
-}
-
-status_t massageManifest(Bundle* bundle, sp<XMLNode> root)
-{
-    root = root->searchElement(String16(), String16("manifest"));
-    if (root == NULL) {
-        fprintf(stderr, "No <manifest> tag.\n");
-        return UNKNOWN_ERROR;
-    }
-
-    bool errorOnFailedInsert = bundle->getErrorOnFailedInsert();
-
-    if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode",
-            bundle->getVersionCode(), errorOnFailedInsert)) {
-        return UNKNOWN_ERROR;
-    }
-    if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName",
-            bundle->getVersionName(), errorOnFailedInsert)) {
-        return UNKNOWN_ERROR;
-    }
-    
-    if (bundle->getMinSdkVersion() != NULL
-            || bundle->getTargetSdkVersion() != NULL
-            || bundle->getMaxSdkVersion() != NULL) {
-        sp<XMLNode> vers = root->getChildElement(String16(), String16("uses-sdk"));
-        if (vers == NULL) {
-            vers = XMLNode::newElement(root->getFilename(), String16(), String16("uses-sdk"));
-            root->insertChildAt(vers, 0);
-        }
-        
-        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "minSdkVersion",
-                bundle->getMinSdkVersion(), errorOnFailedInsert)) {
-            return UNKNOWN_ERROR;
-        }
-        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "targetSdkVersion",
-                bundle->getTargetSdkVersion(), errorOnFailedInsert)) {
-            return UNKNOWN_ERROR;
-        }
-        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion",
-                bundle->getMaxSdkVersion(), errorOnFailedInsert)) {
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    if (bundle->getDebugMode()) {
-        sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
-        if (application != NULL) {
-            if (!addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, "debuggable", "true",
-                    errorOnFailedInsert)) {
-                return UNKNOWN_ERROR;
-            }
-        }
-    }
-
-    // Deal with manifest package name overrides
-    const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();
-    if (manifestPackageNameOverride != NULL) {
-        // Update the actual package name
-        XMLNode::attribute_entry* attr = root->editAttribute(String16(), String16("package"));
-        if (attr == NULL) {
-            fprintf(stderr, "package name is required with --rename-manifest-package.\n");
-            return UNKNOWN_ERROR;
-        }
-        String8 origPackage(attr->string);
-        attr->string.setTo(String16(manifestPackageNameOverride));
-        NOISY(printf("Overriding package '%s' to be '%s'\n", origPackage.string(), manifestPackageNameOverride));
-
-        // Make class names fully qualified
-        sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
-        if (application != NULL) {
-            fullyQualifyClassName(origPackage, application, String16("name"));
-            fullyQualifyClassName(origPackage, application, String16("backupAgent"));
-
-            Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(application->getChildren());
-            for (size_t i = 0; i < children.size(); i++) {
-                sp<XMLNode> child = children.editItemAt(i);
-                String8 tag(child->getElementName());
-                if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") {
-                    fullyQualifyClassName(origPackage, child, String16("name"));
-                } else if (tag == "activity-alias") {
-                    fullyQualifyClassName(origPackage, child, String16("name"));
-                    fullyQualifyClassName(origPackage, child, String16("targetActivity"));
-                }
-            }
-        }
-    }
-
-    // Deal with manifest package name overrides
-    const char* instrumentationPackageNameOverride = bundle->getInstrumentationPackageNameOverride();
-    if (instrumentationPackageNameOverride != NULL) {
-        // Fix up instrumentation targets.
-        Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(root->getChildren());
-        for (size_t i = 0; i < children.size(); i++) {
-            sp<XMLNode> child = children.editItemAt(i);
-            String8 tag(child->getElementName());
-            if (tag == "instrumentation") {
-                XMLNode::attribute_entry* attr = child->editAttribute(
-                        String16("http://schemas.android.com/apk/res/android"), String16("targetPackage"));
-                if (attr != NULL) {
-                    attr->string.setTo(String16(instrumentationPackageNameOverride));
-                }
-            }
-        }
-    }
-    
-    return NO_ERROR;
-}
-
-#define ASSIGN_IT(n) \
-        do { \
-            ssize_t index = resources->indexOfKey(String8(#n)); \
-            if (index >= 0) { \
-                n ## s = resources->valueAt(index); \
-            } \
-        } while (0)
-
-status_t updatePreProcessedCache(Bundle* bundle)
-{
-    #if BENCHMARK
-    fprintf(stdout, "BENCHMARK: Starting PNG PreProcessing \n");
-    long startPNGTime = clock();
-    #endif /* BENCHMARK */
-
-    String8 source(bundle->getResourceSourceDirs()[0]);
-    String8 dest(bundle->getCrunchedOutputDir());
-
-    FileFinder* ff = new SystemFileFinder();
-    CrunchCache cc(source,dest,ff);
-
-    CacheUpdater* cu = new SystemCacheUpdater(bundle);
-    size_t numFiles = cc.crunch(cu);
-
-    if (bundle->getVerbose())
-        fprintf(stdout, "Crunched %d PNG files to update cache\n", (int)numFiles);
-
-    delete ff;
-    delete cu;
-
-    #if BENCHMARK
-    fprintf(stdout, "BENCHMARK: End PNG PreProcessing. Time Elapsed: %f ms \n"
-            ,(clock() - startPNGTime)/1000.0);
-    #endif /* BENCHMARK */
-    return 0;
-}
-
-status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets)
-{
-    // First, look for a package file to parse.  This is required to
-    // be able to generate the resource information.
-    sp<AaptGroup> androidManifestFile =
-            assets->getFiles().valueFor(String8("AndroidManifest.xml"));
-    if (androidManifestFile == NULL) {
-        fprintf(stderr, "ERROR: No AndroidManifest.xml file found.\n");
-        return UNKNOWN_ERROR;
-    }
-
-    status_t err = parsePackage(bundle, assets, androidManifestFile);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    NOISY(printf("Creating resources for package %s\n",
-                 assets->getPackage().string()));
-
-    ResourceTable table(bundle, String16(assets->getPackage()));
-    err = table.addIncludedResources(bundle, assets);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    NOISY(printf("Found %d included resource packages\n", (int)table.size()));
-
-    // Standard flags for compiled XML and optional UTF-8 encoding
-    int xmlFlags = XML_COMPILE_STANDARD_RESOURCE;
-
-    /* Only enable UTF-8 if the caller of aapt didn't specifically
-     * request UTF-16 encoding and the parameters of this package
-     * allow UTF-8 to be used.
-     */
-    if (!bundle->getUTF16StringsOption()) {
-        xmlFlags |= XML_COMPILE_UTF8;
-    }
-
-    // --------------------------------------------------------------
-    // First, gather all resource information.
-    // --------------------------------------------------------------
-
-    // resType -> leafName -> group
-    KeyedVector<String8, sp<ResourceTypeSet> > *resources = 
-            new KeyedVector<String8, sp<ResourceTypeSet> >;
-    collect_files(assets, resources);
-
-    sp<ResourceTypeSet> drawables;
-    sp<ResourceTypeSet> layouts;
-    sp<ResourceTypeSet> anims;
-    sp<ResourceTypeSet> animators;
-    sp<ResourceTypeSet> interpolators;
-    sp<ResourceTypeSet> transitions;
-    sp<ResourceTypeSet> xmls;
-    sp<ResourceTypeSet> raws;
-    sp<ResourceTypeSet> colors;
-    sp<ResourceTypeSet> menus;
-    sp<ResourceTypeSet> mipmaps;
-
-    ASSIGN_IT(drawable);
-    ASSIGN_IT(layout);
-    ASSIGN_IT(anim);
-    ASSIGN_IT(animator);
-    ASSIGN_IT(interpolator);
-    ASSIGN_IT(transition);
-    ASSIGN_IT(xml);
-    ASSIGN_IT(raw);
-    ASSIGN_IT(color);
-    ASSIGN_IT(menu);
-    ASSIGN_IT(mipmap);
-
-    assets->setResources(resources);
-    // now go through any resource overlays and collect their files
-    sp<AaptAssets> current = assets->getOverlay();
-    while(current.get()) {
-        KeyedVector<String8, sp<ResourceTypeSet> > *resources = 
-                new KeyedVector<String8, sp<ResourceTypeSet> >;
-        current->setResources(resources);
-        collect_files(current, resources);
-        current = current->getOverlay();
-    }
-    // apply the overlay files to the base set
-    if (!applyFileOverlay(bundle, assets, &drawables, "drawable") ||
-            !applyFileOverlay(bundle, assets, &layouts, "layout") ||
-            !applyFileOverlay(bundle, assets, &anims, "anim") ||
-            !applyFileOverlay(bundle, assets, &animators, "animator") ||
-            !applyFileOverlay(bundle, assets, &interpolators, "interpolator") ||
-            !applyFileOverlay(bundle, assets, &transitions, "transition") ||
-            !applyFileOverlay(bundle, assets, &xmls, "xml") ||
-            !applyFileOverlay(bundle, assets, &raws, "raw") ||
-            !applyFileOverlay(bundle, assets, &colors, "color") ||
-            !applyFileOverlay(bundle, assets, &menus, "menu") ||
-            !applyFileOverlay(bundle, assets, &mipmaps, "mipmap")) {
-        return UNKNOWN_ERROR;
-    }
-
-    bool hasErrors = false;
-
-    if (drawables != NULL) {
-        if (bundle->getOutputAPKFile() != NULL) {
-            err = preProcessImages(bundle, assets, drawables, "drawable");
-        }
-        if (err == NO_ERROR) {
-            err = makeFileResources(bundle, assets, &table, drawables, "drawable");
-            if (err != NO_ERROR) {
-                hasErrors = true;
-            }
-        } else {
-            hasErrors = true;
-        }
-    }
-
-    if (mipmaps != NULL) {
-        if (bundle->getOutputAPKFile() != NULL) {
-            err = preProcessImages(bundle, assets, mipmaps, "mipmap");
-        }
-        if (err == NO_ERROR) {
-            err = makeFileResources(bundle, assets, &table, mipmaps, "mipmap");
-            if (err != NO_ERROR) {
-                hasErrors = true;
-            }
-        } else {
-            hasErrors = true;
-        }
-    }
-
-    if (layouts != NULL) {
-        err = makeFileResources(bundle, assets, &table, layouts, "layout");
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    if (anims != NULL) {
-        err = makeFileResources(bundle, assets, &table, anims, "anim");
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    if (animators != NULL) {
-        err = makeFileResources(bundle, assets, &table, animators, "animator");
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    if (transitions != NULL) {
-        err = makeFileResources(bundle, assets, &table, transitions, "transition");
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    if (interpolators != NULL) {
-        err = makeFileResources(bundle, assets, &table, interpolators, "interpolator");
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    if (xmls != NULL) {
-        err = makeFileResources(bundle, assets, &table, xmls, "xml");
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    if (raws != NULL) {
-        err = makeFileResources(bundle, assets, &table, raws, "raw");
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    // compile resources
-    current = assets;
-    while(current.get()) {
-        KeyedVector<String8, sp<ResourceTypeSet> > *resources = 
-                current->getResources();
-
-        ssize_t index = resources->indexOfKey(String8("values"));
-        if (index >= 0) {
-            ResourceDirIterator it(resources->valueAt(index), String8("values"));
-            ssize_t res;
-            while ((res=it.next()) == NO_ERROR) {
-                sp<AaptFile> file = it.getFile();
-                res = compileResourceFile(bundle, assets, file, it.getParams(), 
-                                          (current!=assets), &table);
-                if (res != NO_ERROR) {
-                    hasErrors = true;
-                }
-            }
-        }
-        current = current->getOverlay();
-    }
-
-    if (colors != NULL) {
-        err = makeFileResources(bundle, assets, &table, colors, "color");
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    if (menus != NULL) {
-        err = makeFileResources(bundle, assets, &table, menus, "menu");
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    // --------------------------------------------------------------------
-    // Assignment of resource IDs and initial generation of resource table.
-    // --------------------------------------------------------------------
-
-    if (table.hasResources()) {
-        sp<AaptFile> resFile(getResourceFile(assets));
-        if (resFile == NULL) {
-            fprintf(stderr, "Error: unable to generate entry for resource data\n");
-            return UNKNOWN_ERROR;
-        }
-
-        err = table.assignResourceIds();
-        if (err < NO_ERROR) {
-            return err;
-        }
-    }
-
-    // --------------------------------------------------------------
-    // Finally, we can now we can compile XML files, which may reference
-    // resources.
-    // --------------------------------------------------------------
-
-    if (layouts != NULL) {
-        ResourceDirIterator it(layouts, String8("layout"));
-        while ((err=it.next()) == NO_ERROR) {
-            String8 src = it.getFile()->getPrintableSource();
-            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
-            if (err == NO_ERROR) {
-                ResXMLTree block;
-                block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);
-                checkForIds(src, block);
-            } else {
-                hasErrors = true;
-            }
-        }
-
-        if (err < NO_ERROR) {
-            hasErrors = true;
-        }
-        err = NO_ERROR;
-    }
-
-    if (anims != NULL) {
-        ResourceDirIterator it(anims, String8("anim"));
-        while ((err=it.next()) == NO_ERROR) {
-            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
-            if (err != NO_ERROR) {
-                hasErrors = true;
-            }
-        }
-
-        if (err < NO_ERROR) {
-            hasErrors = true;
-        }
-        err = NO_ERROR;
-    }
-
-    if (animators != NULL) {
-        ResourceDirIterator it(animators, String8("animator"));
-        while ((err=it.next()) == NO_ERROR) {
-            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
-            if (err != NO_ERROR) {
-                hasErrors = true;
-            }
-        }
-
-        if (err < NO_ERROR) {
-            hasErrors = true;
-        }
-        err = NO_ERROR;
-    }
-
-    if (interpolators != NULL) {
-        ResourceDirIterator it(interpolators, String8("interpolator"));
-        while ((err=it.next()) == NO_ERROR) {
-            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
-            if (err != NO_ERROR) {
-                hasErrors = true;
-            }
-        }
-
-        if (err < NO_ERROR) {
-            hasErrors = true;
-        }
-        err = NO_ERROR;
-    }
-
-    if (transitions != NULL) {
-        ResourceDirIterator it(transitions, String8("transition"));
-        while ((err=it.next()) == NO_ERROR) {
-            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
-            if (err != NO_ERROR) {
-                hasErrors = true;
-            }
-        }
-
-        if (err < NO_ERROR) {
-            hasErrors = true;
-        }
-        err = NO_ERROR;
-    }
-
-    if (xmls != NULL) {
-        ResourceDirIterator it(xmls, String8("xml"));
-        while ((err=it.next()) == NO_ERROR) {
-            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
-            if (err != NO_ERROR) {
-                hasErrors = true;
-            }
-        }
-
-        if (err < NO_ERROR) {
-            hasErrors = true;
-        }
-        err = NO_ERROR;
-    }
-
-    if (drawables != NULL) {
-        err = postProcessImages(assets, &table, drawables);
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    if (colors != NULL) {
-        ResourceDirIterator it(colors, String8("color"));
-        while ((err=it.next()) == NO_ERROR) {
-          err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
-            if (err != NO_ERROR) {
-                hasErrors = true;
-            }
-        }
-
-        if (err < NO_ERROR) {
-            hasErrors = true;
-        }
-        err = NO_ERROR;
-    }
-
-    if (menus != NULL) {
-        ResourceDirIterator it(menus, String8("menu"));
-        while ((err=it.next()) == NO_ERROR) {
-            String8 src = it.getFile()->getPrintableSource();
-            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
-            if (err != NO_ERROR) {
-                hasErrors = true;
-            }
-            ResXMLTree block;
-            block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);
-            checkForIds(src, block);
-        }
-
-        if (err < NO_ERROR) {
-            hasErrors = true;
-        }
-        err = NO_ERROR;
-    }
-
-    if (table.validateLocalizations()) {
-        hasErrors = true;
-    }
-    
-    if (hasErrors) {
-        return UNKNOWN_ERROR;
-    }
-
-    const sp<AaptFile> manifestFile(androidManifestFile->getFiles().valueAt(0));
-    String8 manifestPath(manifestFile->getPrintableSource());
-
-    // Generate final compiled manifest file.
-    manifestFile->clearData();
-    sp<XMLNode> manifestTree = XMLNode::parse(manifestFile);
-    if (manifestTree == NULL) {
-        return UNKNOWN_ERROR;
-    }
-    err = massageManifest(bundle, manifestTree);
-    if (err < NO_ERROR) {
-        return err;
-    }
-    err = compileXmlFile(assets, manifestTree, manifestFile, &table);
-    if (err < NO_ERROR) {
-        return err;
-    }
-
-    //block.restart();
-    //printXMLBlock(&block);
-
-    // --------------------------------------------------------------
-    // Generate the final resource table.
-    // Re-flatten because we may have added new resource IDs
-    // --------------------------------------------------------------
-
-    ResTable finalResTable;
-    sp<AaptFile> resFile;
-    
-    if (table.hasResources()) {
-        sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
-        err = table.addSymbols(symbols);
-        if (err < NO_ERROR) {
-            return err;
-        }
-
-        resFile = getResourceFile(assets);
-        if (resFile == NULL) {
-            fprintf(stderr, "Error: unable to generate entry for resource data\n");
-            return UNKNOWN_ERROR;
-        }
-
-        err = table.flatten(bundle, resFile);
-        if (err < NO_ERROR) {
-            return err;
-        }
-
-        if (bundle->getPublicOutputFile()) {
-            FILE* fp = fopen(bundle->getPublicOutputFile(), "w+");
-            if (fp == NULL) {
-                fprintf(stderr, "ERROR: Unable to open public definitions output file %s: %s\n",
-                        (const char*)bundle->getPublicOutputFile(), strerror(errno));
-                return UNKNOWN_ERROR;
-            }
-            if (bundle->getVerbose()) {
-                printf("  Writing public definitions to %s.\n", bundle->getPublicOutputFile());
-            }
-            table.writePublicDefinitions(String16(assets->getPackage()), fp);
-            fclose(fp);
-        }
-        
-        // Read resources back in,
-        finalResTable.add(resFile->getData(), resFile->getSize(), NULL);
-        
-#if 0
-        NOISY(
-              printf("Generated resources:\n");
-              finalResTable.print();
-        )
-#endif
-    }
-    
-    // Perform a basic validation of the manifest file.  This time we
-    // parse it with the comments intact, so that we can use them to
-    // generate java docs...  so we are not going to write this one
-    // back out to the final manifest data.
-    sp<AaptFile> outManifestFile = new AaptFile(manifestFile->getSourceFile(),
-            manifestFile->getGroupEntry(),
-            manifestFile->getResourceType());
-    err = compileXmlFile(assets, manifestFile,
-            outManifestFile, &table,
-            XML_COMPILE_ASSIGN_ATTRIBUTE_IDS
-            | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES);
-    if (err < NO_ERROR) {
-        return err;
-    }
-    ResXMLTree block;
-    block.setTo(outManifestFile->getData(), outManifestFile->getSize(), true);
-    String16 manifest16("manifest");
-    String16 permission16("permission");
-    String16 permission_group16("permission-group");
-    String16 uses_permission16("uses-permission");
-    String16 instrumentation16("instrumentation");
-    String16 application16("application");
-    String16 provider16("provider");
-    String16 service16("service");
-    String16 receiver16("receiver");
-    String16 activity16("activity");
-    String16 action16("action");
-    String16 category16("category");
-    String16 data16("scheme");
-    const char* packageIdentChars = "abcdefghijklmnopqrstuvwxyz"
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789";
-    const char* packageIdentCharsWithTheStupid = "abcdefghijklmnopqrstuvwxyz"
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-";
-    const char* classIdentChars = "abcdefghijklmnopqrstuvwxyz"
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789$";
-    const char* processIdentChars = "abcdefghijklmnopqrstuvwxyz"
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:";
-    const char* authoritiesIdentChars = "abcdefghijklmnopqrstuvwxyz"
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-:;";
-    const char* typeIdentChars = "abcdefghijklmnopqrstuvwxyz"
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:-/*+";
-    const char* schemeIdentChars = "abcdefghijklmnopqrstuvwxyz"
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-";
-    ResXMLTree::event_code_t code;
-    sp<AaptSymbols> permissionSymbols;
-    sp<AaptSymbols> permissionGroupSymbols;
-    while ((code=block.next()) != ResXMLTree::END_DOCUMENT
-           && code > ResXMLTree::BAD_DOCUMENT) {
-        if (code == ResXMLTree::START_TAG) {
-            size_t len;
-            if (block.getElementNamespace(&len) != NULL) {
-                continue;
-            }
-            if (strcmp16(block.getElementName(&len), manifest16.string()) == 0) {
-                if (validateAttr(manifestPath, finalResTable, block, NULL, "package",
-                                 packageIdentChars, true) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
-                                 "sharedUserId", packageIdentChars, false) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-            } else if (strcmp16(block.getElementName(&len), permission16.string()) == 0
-                    || strcmp16(block.getElementName(&len), permission_group16.string()) == 0) {
-                const bool isGroup = strcmp16(block.getElementName(&len),
-                        permission_group16.string()) == 0;
-                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
-                                 "name", isGroup ? packageIdentCharsWithTheStupid
-                                 : packageIdentChars, true) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                SourcePos srcPos(manifestPath, block.getLineNumber());
-                sp<AaptSymbols> syms;
-                if (!isGroup) {
-                    syms = permissionSymbols;
-                    if (syms == NULL) {
-                        sp<AaptSymbols> symbols =
-                                assets->getSymbolsFor(String8("Manifest"));
-                        syms = permissionSymbols = symbols->addNestedSymbol(
-                                String8("permission"), srcPos);
-                    }
-                } else {
-                    syms = permissionGroupSymbols;
-                    if (syms == NULL) {
-                        sp<AaptSymbols> symbols =
-                                assets->getSymbolsFor(String8("Manifest"));
-                        syms = permissionGroupSymbols = symbols->addNestedSymbol(
-                                String8("permission_group"), srcPos);
-                    }
-                }
-                size_t len;
-                ssize_t index = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "name");
-                const uint16_t* id = block.getAttributeStringValue(index, &len);
-                if (id == NULL) {
-                    fprintf(stderr, "%s:%d: missing name attribute in element <%s>.\n", 
-                            manifestPath.string(), block.getLineNumber(),
-                            String8(block.getElementName(&len)).string());
-                    hasErrors = true;
-                    break;
-                }
-                String8 idStr(id);
-                char* p = idStr.lockBuffer(idStr.size());
-                char* e = p + idStr.size();
-                bool begins_with_digit = true;  // init to true so an empty string fails
-                while (e > p) {
-                    e--;
-                    if (*e >= '0' && *e <= '9') {
-                      begins_with_digit = true;
-                      continue;
-                    }
-                    if ((*e >= 'a' && *e <= 'z') ||
-                        (*e >= 'A' && *e <= 'Z') ||
-                        (*e == '_')) {
-                      begins_with_digit = false;
-                      continue;
-                    }
-                    if (isGroup && (*e == '-')) {
-                        *e = '_';
-                        begins_with_digit = false;
-                        continue;
-                    }
-                    e++;
-                    break;
-                }
-                idStr.unlockBuffer();
-                // verify that we stopped because we hit a period or
-                // the beginning of the string, and that the
-                // identifier didn't begin with a digit.
-                if (begins_with_digit || (e != p && *(e-1) != '.')) {
-                  fprintf(stderr,
-                          "%s:%d: Permission name <%s> is not a valid Java symbol\n",
-                          manifestPath.string(), block.getLineNumber(), idStr.string());
-                  hasErrors = true;
-                }
-                syms->addStringSymbol(String8(e), idStr, srcPos);
-                const uint16_t* cmt = block.getComment(&len);
-                if (cmt != NULL && *cmt != 0) {
-                    //printf("Comment of %s: %s\n", String8(e).string(),
-                    //        String8(cmt).string());
-                    syms->appendComment(String8(e), String16(cmt), srcPos);
-                } else {
-                    //printf("No comment for %s\n", String8(e).string());
-                }
-                syms->makeSymbolPublic(String8(e), srcPos);
-            } else if (strcmp16(block.getElementName(&len), uses_permission16.string()) == 0) {
-                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
-                                 "name", packageIdentChars, true) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-            } else if (strcmp16(block.getElementName(&len), instrumentation16.string()) == 0) {
-                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
-                                 "name", classIdentChars, true) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "targetPackage",
-                                 packageIdentChars, true) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-            } else if (strcmp16(block.getElementName(&len), application16.string()) == 0) {
-                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
-                                 "name", classIdentChars, false) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "permission",
-                                 packageIdentChars, false) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "process",
-                                 processIdentChars, false) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "taskAffinity",
-                                 processIdentChars, false) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-            } else if (strcmp16(block.getElementName(&len), provider16.string()) == 0) {
-                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
-                                 "name", classIdentChars, true) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "authorities",
-                                 authoritiesIdentChars, true) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "permission",
-                                 packageIdentChars, false) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "process",
-                                 processIdentChars, false) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-            } else if (strcmp16(block.getElementName(&len), service16.string()) == 0
-                       || strcmp16(block.getElementName(&len), receiver16.string()) == 0
-                       || strcmp16(block.getElementName(&len), activity16.string()) == 0) {
-                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
-                                 "name", classIdentChars, true) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "permission",
-                                 packageIdentChars, false) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "process",
-                                 processIdentChars, false) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "taskAffinity",
-                                 processIdentChars, false) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-            } else if (strcmp16(block.getElementName(&len), action16.string()) == 0
-                       || strcmp16(block.getElementName(&len), category16.string()) == 0) {
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "name",
-                                 packageIdentChars, true) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-            } else if (strcmp16(block.getElementName(&len), data16.string()) == 0) {
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "mimeType",
-                                 typeIdentChars, true) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-                if (validateAttr(manifestPath, finalResTable, block,
-                                 RESOURCES_ANDROID_NAMESPACE, "scheme",
-                                 schemeIdentChars, true) != ATTR_OKAY) {
-                    hasErrors = true;
-                }
-            }
-        }
-    }
-
-    if (resFile != NULL) {
-        // These resources are now considered to be a part of the included
-        // resources, for others to reference.
-        err = assets->addIncludedResources(resFile);
-        if (err < NO_ERROR) {
-            fprintf(stderr, "ERROR: Unable to parse generated resources, aborting.\n");
-            return err;
-        }
-    }
-    
-    return err;
-}
-
-static const char* getIndentSpace(int indent)
-{
-static const char whitespace[] =
-"                                                                                       ";
-
-    return whitespace + sizeof(whitespace) - 1 - indent*4;
-}
-
-static String8 flattenSymbol(const String8& symbol) {
-    String8 result(symbol);
-    ssize_t first;
-    if ((first = symbol.find(":", 0)) >= 0
-            || (first = symbol.find(".", 0)) >= 0) {
-        size_t size = symbol.size();
-        char* buf = result.lockBuffer(size);
-        for (size_t i = first; i < size; i++) {
-            if (buf[i] == ':' || buf[i] == '.') {
-                buf[i] = '_';
-            }
-        }
-        result.unlockBuffer(size);
-    }
-    return result;
-}
-
-static String8 getSymbolPackage(const String8& symbol, const sp<AaptAssets>& assets, bool pub) {
-    ssize_t colon = symbol.find(":", 0);
-    if (colon >= 0) {
-        return String8(symbol.string(), colon);
-    }
-    return pub ? assets->getPackage() : assets->getSymbolsPrivatePackage();
-}
-
-static String8 getSymbolName(const String8& symbol) {
-    ssize_t colon = symbol.find(":", 0);
-    if (colon >= 0) {
-        return String8(symbol.string() + colon + 1);
-    }
-    return symbol;
-}
-
-static String16 getAttributeComment(const sp<AaptAssets>& assets,
-                                    const String8& name,
-                                    String16* outTypeComment = NULL)
-{
-    sp<AaptSymbols> asym = assets->getSymbolsFor(String8("R"));
-    if (asym != NULL) {
-        //printf("Got R symbols!\n");
-        asym = asym->getNestedSymbols().valueFor(String8("attr"));
-        if (asym != NULL) {
-            //printf("Got attrs symbols! comment %s=%s\n",
-            //     name.string(), String8(asym->getComment(name)).string());
-            if (outTypeComment != NULL) {
-                *outTypeComment = asym->getTypeComment(name);
-            }
-            return asym->getComment(name);
-        }
-    }
-    return String16();
-}
-
-static status_t writeLayoutClasses(
-    FILE* fp, const sp<AaptAssets>& assets,
-    const sp<AaptSymbols>& symbols, int indent, bool includePrivate)
-{
-    const char* indentStr = getIndentSpace(indent);
-    if (!includePrivate) {
-        fprintf(fp, "%s/** @doconly */\n", indentStr);
-    }
-    fprintf(fp, "%spublic static final class styleable {\n", indentStr);
-    indent++;
-
-    String16 attr16("attr");
-    String16 package16(assets->getPackage());
-
-    indentStr = getIndentSpace(indent);
-    bool hasErrors = false;
-
-    size_t i;
-    size_t N = symbols->getNestedSymbols().size();
-    for (i=0; i<N; i++) {
-        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
-        String8 realClassName(symbols->getNestedSymbols().keyAt(i));
-        String8 nclassName(flattenSymbol(realClassName));
-
-        SortedVector<uint32_t> idents;
-        Vector<uint32_t> origOrder;
-        Vector<bool> publicFlags;
-
-        size_t a;
-        size_t NA = nsymbols->getSymbols().size();
-        for (a=0; a<NA; a++) {
-            const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a));
-            int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32
-                    ? sym.int32Val : 0;
-            bool isPublic = true;
-            if (code == 0) {
-                String16 name16(sym.name);
-                uint32_t typeSpecFlags;
-                code = assets->getIncludedResources().identifierForName(
-                    name16.string(), name16.size(),
-                    attr16.string(), attr16.size(),
-                    package16.string(), package16.size(), &typeSpecFlags);
-                if (code == 0) {
-                    fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n",
-                            nclassName.string(), sym.name.string());
-                    hasErrors = true;
-                }
-                isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
-            }
-            idents.add(code);
-            origOrder.add(code);
-            publicFlags.add(isPublic);
-        }
-
-        NA = idents.size();
-
-        bool deprecated = false;
-        
-        String16 comment = symbols->getComment(realClassName);
-        fprintf(fp, "%s/** ", indentStr);
-        if (comment.size() > 0) {
-            String8 cmt(comment);
-            fprintf(fp, "%s\n", cmt.string());
-            if (strstr(cmt.string(), "@deprecated") != NULL) {
-                deprecated = true;
-            }
-        } else {
-            fprintf(fp, "Attributes that can be used with a %s.\n", nclassName.string());
-        }
-        bool hasTable = false;
-        for (a=0; a<NA; a++) {
-            ssize_t pos = idents.indexOf(origOrder.itemAt(a));
-            if (pos >= 0) {
-                if (!hasTable) {
-                    hasTable = true;
-                    fprintf(fp,
-                            "%s   <p>Includes the following attributes:</p>\n"
-                            "%s   <table>\n"
-                            "%s   <colgroup align=\"left\" />\n"
-                            "%s   <colgroup align=\"left\" />\n"
-                            "%s   <tr><th>Attribute</th><th>Description</th></tr>\n",
-                            indentStr,
-                            indentStr,
-                            indentStr,
-                            indentStr,
-                            indentStr);
-                }
-                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);
-                if (!publicFlags.itemAt(a) && !includePrivate) {
-                    continue;
-                }
-                String8 name8(sym.name);
-                String16 comment(sym.comment);
-                if (comment.size() <= 0) {
-                    comment = getAttributeComment(assets, name8);
-                }
-                if (comment.size() > 0) {
-                    const char16_t* p = comment.string();
-                    while (*p != 0 && *p != '.') {
-                        if (*p == '{') {
-                            while (*p != 0 && *p != '}') {
-                                p++;
-                            }
-                        } else {
-                            p++;
-                        }
-                    }
-                    if (*p == '.') {
-                        p++;
-                    }
-                    comment = String16(comment.string(), p-comment.string());
-                }
-                fprintf(fp, "%s   <tr><td><code>{@link #%s_%s %s:%s}</code></td><td>%s</td></tr>\n",
-                        indentStr, nclassName.string(),
-                        flattenSymbol(name8).string(),
-                        getSymbolPackage(name8, assets, true).string(),
-                        getSymbolName(name8).string(),
-                        String8(comment).string());
-            }
-        }
-        if (hasTable) {
-            fprintf(fp, "%s   </table>\n", indentStr);
-        }
-        for (a=0; a<NA; a++) {
-            ssize_t pos = idents.indexOf(origOrder.itemAt(a));
-            if (pos >= 0) {
-                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);
-                if (!publicFlags.itemAt(a) && !includePrivate) {
-                    continue;
-                }
-                fprintf(fp, "%s   @see #%s_%s\n",
-                        indentStr, nclassName.string(),
-                        flattenSymbol(sym.name).string());
-            }
-        }
-        fprintf(fp, "%s */\n", getIndentSpace(indent));
-
-        if (deprecated) {
-            fprintf(fp, "%s@Deprecated\n", indentStr);
-        }
-        
-        fprintf(fp,
-                "%spublic static final int[] %s = {\n"
-                "%s",
-                indentStr, nclassName.string(),
-                getIndentSpace(indent+1));
-
-        for (a=0; a<NA; a++) {
-            if (a != 0) {
-                if ((a&3) == 0) {
-                    fprintf(fp, ",\n%s", getIndentSpace(indent+1));
-                } else {
-                    fprintf(fp, ", ");
-                }
-            }
-            fprintf(fp, "0x%08x", idents[a]);
-        }
-
-        fprintf(fp, "\n%s};\n", indentStr);
-
-        for (a=0; a<NA; a++) {
-            ssize_t pos = idents.indexOf(origOrder.itemAt(a));
-            if (pos >= 0) {
-                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);
-                if (!publicFlags.itemAt(a) && !includePrivate) {
-                    continue;
-                }
-                String8 name8(sym.name);
-                String16 comment(sym.comment);
-                String16 typeComment;
-                if (comment.size() <= 0) {
-                    comment = getAttributeComment(assets, name8, &typeComment);
-                } else {
-                    getAttributeComment(assets, name8, &typeComment);
-                }
-
-                uint32_t typeSpecFlags = 0;
-                String16 name16(sym.name);
-                assets->getIncludedResources().identifierForName(
-                    name16.string(), name16.size(),
-                    attr16.string(), attr16.size(),
-                    package16.string(), package16.size(), &typeSpecFlags);
-                //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(),
-                //    String8(attr16).string(), String8(name16).string(), typeSpecFlags);
-                const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
-                
-                bool deprecated = false;
-                
-                fprintf(fp, "%s/**\n", indentStr);
-                if (comment.size() > 0) {
-                    String8 cmt(comment);
-                    fprintf(fp, "%s  <p>\n%s  @attr description\n", indentStr, indentStr);
-                    fprintf(fp, "%s  %s\n", indentStr, cmt.string());
-                    if (strstr(cmt.string(), "@deprecated") != NULL) {
-                        deprecated = true;
-                    }
-                } else {
-                    fprintf(fp,
-                            "%s  <p>This symbol is the offset where the {@link %s.R.attr#%s}\n"
-                            "%s  attribute's value can be found in the {@link #%s} array.\n",
-                            indentStr,
-                            getSymbolPackage(name8, assets, pub).string(),
-                            getSymbolName(name8).string(),
-                            indentStr, nclassName.string());
-                }
-                if (typeComment.size() > 0) {
-                    String8 cmt(typeComment);
-                    fprintf(fp, "\n\n%s  %s\n", indentStr, cmt.string());
-                    if (strstr(cmt.string(), "@deprecated") != NULL) {
-                        deprecated = true;
-                    }
-                }
-                if (comment.size() > 0) {
-                    if (pub) {
-                        fprintf(fp,
-                                "%s  <p>This corresponds to the global attribute\n"
-                                "%s  resource symbol {@link %s.R.attr#%s}.\n",
-                                indentStr, indentStr,
-                                getSymbolPackage(name8, assets, true).string(),
-                                getSymbolName(name8).string());
-                    } else {
-                        fprintf(fp,
-                                "%s  <p>This is a private symbol.\n", indentStr);
-                    }
-                }
-                fprintf(fp, "%s  @attr name %s:%s\n", indentStr,
-                        getSymbolPackage(name8, assets, pub).string(),
-                        getSymbolName(name8).string());
-                fprintf(fp, "%s*/\n", indentStr);
-                if (deprecated) {
-                    fprintf(fp, "%s@Deprecated\n", indentStr);
-                }
-                fprintf(fp,
-                        "%spublic static final int %s_%s = %d;\n",
-                        indentStr, nclassName.string(),
-                        flattenSymbol(name8).string(), (int)pos);
-            }
-        }
-    }
-
-    indent--;
-    fprintf(fp, "%s};\n", getIndentSpace(indent));
-    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
-}
-
-static status_t writeTextLayoutClasses(
-    FILE* fp, const sp<AaptAssets>& assets,
-    const sp<AaptSymbols>& symbols, bool includePrivate)
-{
-    String16 attr16("attr");
-    String16 package16(assets->getPackage());
-
-    bool hasErrors = false;
-
-    size_t i;
-    size_t N = symbols->getNestedSymbols().size();
-    for (i=0; i<N; i++) {
-        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
-        String8 realClassName(symbols->getNestedSymbols().keyAt(i));
-        String8 nclassName(flattenSymbol(realClassName));
-
-        SortedVector<uint32_t> idents;
-        Vector<uint32_t> origOrder;
-        Vector<bool> publicFlags;
-
-        size_t a;
-        size_t NA = nsymbols->getSymbols().size();
-        for (a=0; a<NA; a++) {
-            const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a));
-            int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32
-                    ? sym.int32Val : 0;
-            bool isPublic = true;
-            if (code == 0) {
-                String16 name16(sym.name);
-                uint32_t typeSpecFlags;
-                code = assets->getIncludedResources().identifierForName(
-                    name16.string(), name16.size(),
-                    attr16.string(), attr16.size(),
-                    package16.string(), package16.size(), &typeSpecFlags);
-                if (code == 0) {
-                    fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n",
-                            nclassName.string(), sym.name.string());
-                    hasErrors = true;
-                }
-                isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
-            }
-            idents.add(code);
-            origOrder.add(code);
-            publicFlags.add(isPublic);
-        }
-
-        NA = idents.size();
-
-        fprintf(fp, "int[] styleable %s {", nclassName.string());
-
-        for (a=0; a<NA; a++) {
-            if (a != 0) {
-                fprintf(fp, ",");
-            }
-            fprintf(fp, " 0x%08x", idents[a]);
-        }
-
-        fprintf(fp, " }\n");
-
-        for (a=0; a<NA; a++) {
-            ssize_t pos = idents.indexOf(origOrder.itemAt(a));
-            if (pos >= 0) {
-                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);
-                if (!publicFlags.itemAt(a) && !includePrivate) {
-                    continue;
-                }
-                String8 name8(sym.name);
-                String16 comment(sym.comment);
-                String16 typeComment;
-                if (comment.size() <= 0) {
-                    comment = getAttributeComment(assets, name8, &typeComment);
-                } else {
-                    getAttributeComment(assets, name8, &typeComment);
-                }
-
-                uint32_t typeSpecFlags = 0;
-                String16 name16(sym.name);
-                assets->getIncludedResources().identifierForName(
-                    name16.string(), name16.size(),
-                    attr16.string(), attr16.size(),
-                    package16.string(), package16.size(), &typeSpecFlags);
-                //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(),
-                //    String8(attr16).string(), String8(name16).string(), typeSpecFlags);
-                const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
-
-                fprintf(fp,
-                        "int styleable %s_%s %d\n",
-                        nclassName.string(),
-                        flattenSymbol(name8).string(), (int)pos);
-            }
-        }
-    }
-
-    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
-}
-
-static status_t writeSymbolClass(
-    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
-    const sp<AaptSymbols>& symbols, const String8& className, int indent,
-    bool nonConstantId)
-{
-    fprintf(fp, "%spublic %sfinal class %s {\n",
-            getIndentSpace(indent),
-            indent != 0 ? "static " : "", className.string());
-    indent++;
-
-    size_t i;
-    status_t err = NO_ERROR;
-
-    const char * id_format = nonConstantId ?
-            "%spublic static int %s=0x%08x;\n" :
-            "%spublic static final int %s=0x%08x;\n";
-
-    size_t N = symbols->getSymbols().size();
-    for (i=0; i<N; i++) {
-        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
-        if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) {
-            continue;
-        }
-        if (!assets->isJavaSymbol(sym, includePrivate)) {
-            continue;
-        }
-        String8 name8(sym.name);
-        String16 comment(sym.comment);
-        bool haveComment = false;
-        bool deprecated = false;
-        if (comment.size() > 0) {
-            haveComment = true;
-            String8 cmt(comment);
-            fprintf(fp,
-                    "%s/** %s\n",
-                    getIndentSpace(indent), cmt.string());
-            if (strstr(cmt.string(), "@deprecated") != NULL) {
-                deprecated = true;
-            }
-        } else if (sym.isPublic && !includePrivate) {
-            sym.sourcePos.warning("No comment for public symbol %s:%s/%s",
-                assets->getPackage().string(), className.string(),
-                String8(sym.name).string());
-        }
-        String16 typeComment(sym.typeComment);
-        if (typeComment.size() > 0) {
-            String8 cmt(typeComment);
-            if (!haveComment) {
-                haveComment = true;
-                fprintf(fp,
-                        "%s/** %s\n", getIndentSpace(indent), cmt.string());
-            } else {
-                fprintf(fp,
-                        "%s %s\n", getIndentSpace(indent), cmt.string());
-            }
-            if (strstr(cmt.string(), "@deprecated") != NULL) {
-                deprecated = true;
-            }
-        }
-        if (haveComment) {
-            fprintf(fp,"%s */\n", getIndentSpace(indent));
-        }
-        if (deprecated) {
-            fprintf(fp, "%s@Deprecated\n", getIndentSpace(indent));
-        }
-        fprintf(fp, id_format,
-                getIndentSpace(indent),
-                flattenSymbol(name8).string(), (int)sym.int32Val);
-    }
-
-    for (i=0; i<N; i++) {
-        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
-        if (sym.typeCode != AaptSymbolEntry::TYPE_STRING) {
-            continue;
-        }
-        if (!assets->isJavaSymbol(sym, includePrivate)) {
-            continue;
-        }
-        String8 name8(sym.name);
-        String16 comment(sym.comment);
-        bool deprecated = false;
-        if (comment.size() > 0) {
-            String8 cmt(comment);
-            fprintf(fp,
-                    "%s/** %s\n"
-                     "%s */\n",
-                    getIndentSpace(indent), cmt.string(),
-                    getIndentSpace(indent));
-            if (strstr(cmt.string(), "@deprecated") != NULL) {
-                deprecated = true;
-            }
-        } else if (sym.isPublic && !includePrivate) {
-            sym.sourcePos.warning("No comment for public symbol %s:%s/%s",
-                assets->getPackage().string(), className.string(),
-                String8(sym.name).string());
-        }
-        if (deprecated) {
-            fprintf(fp, "%s@Deprecated\n", getIndentSpace(indent));
-        }
-        fprintf(fp, "%spublic static final String %s=\"%s\";\n",
-                getIndentSpace(indent),
-                flattenSymbol(name8).string(), sym.stringVal.string());
-    }
-
-    sp<AaptSymbols> styleableSymbols;
-
-    N = symbols->getNestedSymbols().size();
-    for (i=0; i<N; i++) {
-        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
-        String8 nclassName(symbols->getNestedSymbols().keyAt(i));
-        if (nclassName == "styleable") {
-            styleableSymbols = nsymbols;
-        } else {
-            err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName, indent, nonConstantId);
-        }
-        if (err != NO_ERROR) {
-            return err;
-        }
-    }
-
-    if (styleableSymbols != NULL) {
-        err = writeLayoutClasses(fp, assets, styleableSymbols, indent, includePrivate);
-        if (err != NO_ERROR) {
-            return err;
-        }
-    }
-
-    indent--;
-    fprintf(fp, "%s}\n", getIndentSpace(indent));
-    return NO_ERROR;
-}
-
-static status_t writeTextSymbolClass(
-    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
-    const sp<AaptSymbols>& symbols, const String8& className)
-{
-    size_t i;
-    status_t err = NO_ERROR;
-
-    size_t N = symbols->getSymbols().size();
-    for (i=0; i<N; i++) {
-        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
-        if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) {
-            continue;
-        }
-
-        if (!assets->isJavaSymbol(sym, includePrivate)) {
-            continue;
-        }
-
-        String8 name8(sym.name);
-        fprintf(fp, "int %s %s 0x%08x\n",
-                className.string(),
-                flattenSymbol(name8).string(), (int)sym.int32Val);
-    }
-
-    N = symbols->getNestedSymbols().size();
-    for (i=0; i<N; i++) {
-        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
-        String8 nclassName(symbols->getNestedSymbols().keyAt(i));
-        if (nclassName == "styleable") {
-            err = writeTextLayoutClasses(fp, assets, nsymbols, includePrivate);
-        } else {
-            err = writeTextSymbolClass(fp, assets, includePrivate, nsymbols, nclassName);
-        }
-        if (err != NO_ERROR) {
-            return err;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets,
-    const String8& package, bool includePrivate)
-{
-    if (!bundle->getRClassDir()) {
-        return NO_ERROR;
-    }
-
-    const char* textSymbolsDest = bundle->getOutputTextSymbols();
-
-    String8 R("R");
-    const size_t N = assets->getSymbols().size();
-    for (size_t i=0; i<N; i++) {
-        sp<AaptSymbols> symbols = assets->getSymbols().valueAt(i);
-        String8 className(assets->getSymbols().keyAt(i));
-        String8 dest(bundle->getRClassDir());
-
-        if (bundle->getMakePackageDirs()) {
-            String8 pkg(package);
-            const char* last = pkg.string();
-            const char* s = last-1;
-            do {
-                s++;
-                if (s > last && (*s == '.' || *s == 0)) {
-                    String8 part(last, s-last);
-                    dest.appendPath(part);
-#ifdef HAVE_MS_C_RUNTIME
-                    _mkdir(dest.string());
-#else
-                    mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
-#endif
-                    last = s+1;
-                }
-            } while (*s);
-        }
-        dest.appendPath(className);
-        dest.append(".java");
-        FILE* fp = fopen(dest.string(), "w+");
-        if (fp == NULL) {
-            fprintf(stderr, "ERROR: Unable to open class file %s: %s\n",
-                    dest.string(), strerror(errno));
-            return UNKNOWN_ERROR;
-        }
-        if (bundle->getVerbose()) {
-            printf("  Writing symbols for class %s.\n", className.string());
-        }
-
-        fprintf(fp,
-            "/* AUTO-GENERATED FILE.  DO NOT MODIFY.\n"
-            " *\n"
-            " * This class was automatically generated by the\n"
-            " * aapt tool from the resource data it found.  It\n"
-            " * should not be modified by hand.\n"
-            " */\n"
-            "\n"
-            "package %s;\n\n", package.string());
-
-        status_t err = writeSymbolClass(fp, assets, includePrivate, symbols,
-                className, 0, bundle->getNonConstantId());
-        if (err != NO_ERROR) {
-            return err;
-        }
-        fclose(fp);
-
-        if (textSymbolsDest != NULL && R == className) {
-            String8 textDest(textSymbolsDest);
-            textDest.appendPath(className);
-            textDest.append(".txt");
-
-            FILE* fp = fopen(textDest.string(), "w+");
-            if (fp == NULL) {
-                fprintf(stderr, "ERROR: Unable to open text symbol file %s: %s\n",
-                        textDest.string(), strerror(errno));
-                return UNKNOWN_ERROR;
-            }
-            if (bundle->getVerbose()) {
-                printf("  Writing text symbols for class %s.\n", className.string());
-            }
-
-            status_t err = writeTextSymbolClass(fp, assets, includePrivate, symbols,
-                    className);
-            if (err != NO_ERROR) {
-                return err;
-            }
-            fclose(fp);
-        }
-
-        // If we were asked to generate a dependency file, we'll go ahead and add this R.java
-        // as a target in the dependency file right next to it.
-        if (bundle->getGenDependencies() && R == className) {
-            // Add this R.java to the dependency file
-            String8 dependencyFile(bundle->getRClassDir());
-            dependencyFile.appendPath("R.java.d");
-
-            FILE *fp = fopen(dependencyFile.string(), "a");
-            fprintf(fp,"%s \\\n", dest.string());
-            fclose(fp);
-        }
-    }
-
-    return NO_ERROR;
-}
-
-
-class ProguardKeepSet
-{
-public:
-    // { rule --> { file locations } }
-    KeyedVector<String8, SortedVector<String8> > rules;
-
-    void add(const String8& rule, const String8& where);
-};
-
-void ProguardKeepSet::add(const String8& rule, const String8& where)
-{
-    ssize_t index = rules.indexOfKey(rule);
-    if (index < 0) {
-        index = rules.add(rule, SortedVector<String8>());
-    }
-    rules.editValueAt(index).add(where);
-}
-
-void
-addProguardKeepRule(ProguardKeepSet* keep, const String8& inClassName,
-        const char* pkg, const String8& srcName, int line)
-{
-    String8 className(inClassName);
-    if (pkg != NULL) {
-        // asdf     --> package.asdf
-        // .asdf  .a.b  --> package.asdf package.a.b
-        // asdf.adsf --> asdf.asdf
-        const char* p = className.string();
-        const char* q = strchr(p, '.');
-        if (p == q) {
-            className = pkg;
-            className.append(inClassName);
-        } else if (q == NULL) {
-            className = pkg;
-            className.append(".");
-            className.append(inClassName);
-        }
-    }
-
-    String8 rule("-keep class ");
-    rule += className;
-    rule += " { <init>(...); }";
-
-    String8 location("view ");
-    location += srcName;
-    char lineno[20];
-    sprintf(lineno, ":%d", line);
-    location += lineno;
-
-    keep->add(rule, location);
-}
-
-void
-addProguardKeepMethodRule(ProguardKeepSet* keep, const String8& memberName,
-        const char* pkg, const String8& srcName, int line)
-{
-    String8 rule("-keepclassmembers class * { *** ");
-    rule += memberName;
-    rule += "(...); }";
-
-    String8 location("onClick ");
-    location += srcName;
-    char lineno[20];
-    sprintf(lineno, ":%d", line);
-    location += lineno;
-
-    keep->add(rule, location);
-}
-
-status_t
-writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& assets)
-{
-    status_t err;
-    ResXMLTree tree;
-    size_t len;
-    ResXMLTree::event_code_t code;
-    int depth = 0;
-    bool inApplication = false;
-    String8 error;
-    sp<AaptGroup> assGroup;
-    sp<AaptFile> assFile;
-    String8 pkg;
-
-    // First, look for a package file to parse.  This is required to
-    // be able to generate the resource information.
-    assGroup = assets->getFiles().valueFor(String8("AndroidManifest.xml"));
-    if (assGroup == NULL) {
-        fprintf(stderr, "ERROR: No AndroidManifest.xml file found.\n");
-        return -1;
-    }
-
-    if (assGroup->getFiles().size() != 1) {
-        fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n",
-                assGroup->getFiles().valueAt(0)->getPrintableSource().string());
-    }
-
-    assFile = assGroup->getFiles().valueAt(0);
-
-    err = parseXMLResource(assFile, &tree);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    tree.restart();
-
-    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-        if (code == ResXMLTree::END_TAG) {
-            if (/* name == "Application" && */ depth == 2) {
-                inApplication = false;
-            }
-            depth--;
-            continue;
-        }
-        if (code != ResXMLTree::START_TAG) {
-            continue;
-        }
-        depth++;
-        String8 tag(tree.getElementName(&len));
-        // printf("Depth %d tag %s\n", depth, tag.string());
-        bool keepTag = false;
-        if (depth == 1) {
-            if (tag != "manifest") {
-                fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n");
-                return -1;
-            }
-            pkg = getAttribute(tree, NULL, "package", NULL);
-        } else if (depth == 2) {
-            if (tag == "application") {
-                inApplication = true;
-                keepTag = true;
-
-                String8 agent = getAttribute(tree, "http://schemas.android.com/apk/res/android",
-                        "backupAgent", &error);
-                if (agent.length() > 0) {
-                    addProguardKeepRule(keep, agent, pkg.string(),
-                            assFile->getPrintableSource(), tree.getLineNumber());
-                }
-            } else if (tag == "instrumentation") {
-                keepTag = true;
-            }
-        }
-        if (!keepTag && inApplication && depth == 3) {
-            if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") {
-                keepTag = true;
-            }
-        }
-        if (keepTag) {
-            String8 name = getAttribute(tree, "http://schemas.android.com/apk/res/android",
-                    "name", &error);
-            if (error != "") {
-                fprintf(stderr, "ERROR: %s\n", error.string());
-                return -1;
-            }
-            if (name.length() > 0) {
-                addProguardKeepRule(keep, name, pkg.string(),
-                        assFile->getPrintableSource(), tree.getLineNumber());
-            }
-        }
-    }
-
-    return NO_ERROR;
-}
-
-struct NamespaceAttributePair {
-    const char* ns;
-    const char* attr;
-
-    NamespaceAttributePair(const char* n, const char* a) : ns(n), attr(a) {}
-    NamespaceAttributePair() : ns(NULL), attr(NULL) {}
-};
-
-status_t
-writeProguardForXml(ProguardKeepSet* keep, const sp<AaptFile>& layoutFile,
-        const char* startTag, const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs)
-{
-    status_t err;
-    ResXMLTree tree;
-    size_t len;
-    ResXMLTree::event_code_t code;
-
-    err = parseXMLResource(layoutFile, &tree);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    tree.restart();
-
-    if (startTag != NULL) {
-        bool haveStart = false;
-        while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-            if (code != ResXMLTree::START_TAG) {
-                continue;
-            }
-            String8 tag(tree.getElementName(&len));
-            if (tag == startTag) {
-                haveStart = true;
-            }
-            break;
-        }
-        if (!haveStart) {
-            return NO_ERROR;
-        }
-    }
-
-    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-        if (code != ResXMLTree::START_TAG) {
-            continue;
-        }
-        String8 tag(tree.getElementName(&len));
-
-        // If there is no '.', we'll assume that it's one of the built in names.
-        if (strchr(tag.string(), '.')) {
-            addProguardKeepRule(keep, tag, NULL,
-                    layoutFile->getPrintableSource(), tree.getLineNumber());
-        } else if (tagAttrPairs != NULL) {
-            ssize_t tagIndex = tagAttrPairs->indexOfKey(tag);
-            if (tagIndex >= 0) {
-                const Vector<NamespaceAttributePair>& nsAttrVector = tagAttrPairs->valueAt(tagIndex);
-                for (size_t i = 0; i < nsAttrVector.size(); i++) {
-                    const NamespaceAttributePair& nsAttr = nsAttrVector[i];
-
-                    ssize_t attrIndex = tree.indexOfAttribute(nsAttr.ns, nsAttr.attr);
-                    if (attrIndex < 0) {
-                        // fprintf(stderr, "%s:%d: <%s> does not have attribute %s:%s.\n",
-                        //        layoutFile->getPrintableSource().string(), tree.getLineNumber(),
-                        //        tag.string(), nsAttr.ns, nsAttr.attr);
-                    } else {
-                        size_t len;
-                        addProguardKeepRule(keep,
-                                            String8(tree.getAttributeStringValue(attrIndex, &len)), NULL,
-                                            layoutFile->getPrintableSource(), tree.getLineNumber());
-                    }
-                }
-            }
-        }
-        ssize_t attrIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "onClick");
-        if (attrIndex >= 0) {
-            size_t len;
-            addProguardKeepMethodRule(keep,
-                                String8(tree.getAttributeStringValue(attrIndex, &len)), NULL,
-                                layoutFile->getPrintableSource(), tree.getLineNumber());
-        }
-    }
-
-    return NO_ERROR;
-}
-
-static void addTagAttrPair(KeyedVector<String8, Vector<NamespaceAttributePair> >* dest,
-        const char* tag, const char* ns, const char* attr) {
-    String8 tagStr(tag);
-    ssize_t index = dest->indexOfKey(tagStr);
-
-    if (index < 0) {
-        Vector<NamespaceAttributePair> vector;
-        vector.add(NamespaceAttributePair(ns, attr));
-        dest->add(tagStr, vector);
-    } else {
-        dest->editValueAt(index).add(NamespaceAttributePair(ns, attr));
-    }
-}
-
-status_t
-writeProguardForLayouts(ProguardKeepSet* keep, const sp<AaptAssets>& assets)
-{
-    status_t err;
-
-    // tag:attribute pairs that should be checked in layout files.
-    KeyedVector<String8, Vector<NamespaceAttributePair> > kLayoutTagAttrPairs;
-    addTagAttrPair(&kLayoutTagAttrPairs, "view", NULL, "class");
-    addTagAttrPair(&kLayoutTagAttrPairs, "fragment", NULL, "class");
-    addTagAttrPair(&kLayoutTagAttrPairs, "fragment", RESOURCES_ANDROID_NAMESPACE, "name");
-
-    // tag:attribute pairs that should be checked in xml files.
-    KeyedVector<String8, Vector<NamespaceAttributePair> > kXmlTagAttrPairs;
-    addTagAttrPair(&kXmlTagAttrPairs, "PreferenceScreen", RESOURCES_ANDROID_NAMESPACE, "fragment");
-    addTagAttrPair(&kXmlTagAttrPairs, "header", RESOURCES_ANDROID_NAMESPACE, "fragment");
-
-    const Vector<sp<AaptDir> >& dirs = assets->resDirs();
-    const size_t K = dirs.size();
-    for (size_t k=0; k<K; k++) {
-        const sp<AaptDir>& d = dirs.itemAt(k);
-        const String8& dirName = d->getLeaf();
-        const char* startTag = NULL;
-        const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs = NULL;
-        if ((dirName == String8("layout")) || (strncmp(dirName.string(), "layout-", 7) == 0)) {
-            tagAttrPairs = &kLayoutTagAttrPairs;
-        } else if ((dirName == String8("xml")) || (strncmp(dirName.string(), "xml-", 4) == 0)) {
-            startTag = "PreferenceScreen";
-            tagAttrPairs = &kXmlTagAttrPairs;
-        } else if ((dirName == String8("menu")) || (strncmp(dirName.string(), "menu-", 5) == 0)) {
-            startTag = "menu";
-            tagAttrPairs = NULL;
-        } else {
-            continue;
-        }
-
-        const KeyedVector<String8,sp<AaptGroup> > groups = d->getFiles();
-        const size_t N = groups.size();
-        for (size_t i=0; i<N; i++) {
-            const sp<AaptGroup>& group = groups.valueAt(i);
-            const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files = group->getFiles();
-            const size_t M = files.size();
-            for (size_t j=0; j<M; j++) {
-                err = writeProguardForXml(keep, files.valueAt(j), startTag, tagAttrPairs);
-                if (err < 0) {
-                    return err;
-                }
-            }
-        }
-    }
-    // Handle the overlays
-    sp<AaptAssets> overlay = assets->getOverlay();
-    if (overlay.get()) {
-        return writeProguardForLayouts(keep, overlay);
-    }
-
-    return NO_ERROR;
-}
-
-status_t
-writeProguardFile(Bundle* bundle, const sp<AaptAssets>& assets)
-{
-    status_t err = -1;
-
-    if (!bundle->getProguardFile()) {
-        return NO_ERROR;
-    }
-
-    ProguardKeepSet keep;
-
-    err = writeProguardForAndroidManifest(&keep, assets);
-    if (err < 0) {
-        return err;
-    }
-
-    err = writeProguardForLayouts(&keep, assets);
-    if (err < 0) {
-        return err;
-    }
-
-    FILE* fp = fopen(bundle->getProguardFile(), "w+");
-    if (fp == NULL) {
-        fprintf(stderr, "ERROR: Unable to open class file %s: %s\n",
-                bundle->getProguardFile(), strerror(errno));
-        return UNKNOWN_ERROR;
-    }
-
-    const KeyedVector<String8, SortedVector<String8> >& rules = keep.rules;
-    const size_t N = rules.size();
-    for (size_t i=0; i<N; i++) {
-        const SortedVector<String8>& locations = rules.valueAt(i);
-        const size_t M = locations.size();
-        for (size_t j=0; j<M; j++) {
-            fprintf(fp, "# %s\n", locations.itemAt(j).string());
-        }
-        fprintf(fp, "%s\n\n", rules.keyAt(i).string());
-    }
-    fclose(fp);
-
-    return err;
-}
-
-// Loops through the string paths and writes them to the file pointer
-// Each file path is written on its own line with a terminating backslash.
-status_t writePathsToFile(const sp<FilePathStore>& files, FILE* fp)
-{
-    status_t deps = -1;
-    for (size_t file_i = 0; file_i < files->size(); ++file_i) {
-        // Add the full file path to the dependency file
-        fprintf(fp, "%s \\\n", files->itemAt(file_i).string());
-        deps++;
-    }
-    return deps;
-}
-
-status_t
-writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets, FILE* fp, bool includeRaw)
-{
-    status_t deps = -1;
-    deps += writePathsToFile(assets->getFullResPaths(), fp);
-    if (includeRaw) {
-        deps += writePathsToFile(assets->getFullAssetPaths(), fp);
-    }
-    return deps;
-}
diff --git a/tools/aapt/ResourceFilter.cpp b/tools/aapt/ResourceFilter.cpp
deleted file mode 100644
index 8cfd2a5..0000000
--- a/tools/aapt/ResourceFilter.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-// Build resource files from raw assets.
-//
-
-#include "ResourceFilter.h"
-
-status_t
-ResourceFilter::parse(const char* arg)
-{
-    if (arg == NULL) {
-        return 0;
-    }
-
-    const char* p = arg;
-    const char* q;
-
-    while (true) {
-        q = strchr(p, ',');
-        if (q == NULL) {
-            q = p + strlen(p);
-        }
-
-        String8 part(p, q-p);
-
-        if (part == "zz_ZZ") {
-            mContainsPseudo = true;
-        }
-        int axis;
-        uint32_t value;
-        if (AaptGroupEntry::parseNamePart(part, &axis, &value)) {
-            fprintf(stderr, "Invalid configuration: %s\n", arg);
-            fprintf(stderr, "                       ");
-            for (int i=0; i<p-arg; i++) {
-                fprintf(stderr, " ");
-            }
-            for (int i=0; i<q-p; i++) {
-                fprintf(stderr, "^");
-            }
-            fprintf(stderr, "\n");
-            return 1;
-        }
-
-        ssize_t index = mData.indexOfKey(axis);
-        if (index < 0) {
-            mData.add(axis, SortedVector<uint32_t>());
-        }
-        SortedVector<uint32_t>& sv = mData.editValueFor(axis);
-        sv.add(value);
-        // if it's a locale with a region, also match an unmodified locale of the
-        // same language
-        if (axis == AXIS_LANGUAGE) {
-            if (value & 0xffff0000) {
-                sv.add(value & 0x0000ffff);
-            }
-        }
-        p = q;
-        if (!*p) break;
-        p++;
-    }
-
-    return NO_ERROR;
-}
-
-bool
-ResourceFilter::isEmpty() const
-{
-    return mData.size() == 0;
-}
-
-bool
-ResourceFilter::match(int axis, uint32_t value) const
-{
-    if (value == 0) {
-        // they didn't specify anything so take everything
-        return true;
-    }
-    ssize_t index = mData.indexOfKey(axis);
-    if (index < 0) {
-        // we didn't request anything on this axis so take everything
-        return true;
-    }
-    const SortedVector<uint32_t>& sv = mData.valueAt(index);
-    return sv.indexOf(value) >= 0;
-}
-
-bool
-ResourceFilter::match(int axis, const ResTable_config& config) const
-{
-    return match(axis, AaptGroupEntry::getConfigValueForAxis(config, axis));
-}
-
-bool
-ResourceFilter::match(const ResTable_config& config) const
-{
-    for (int i=AXIS_START; i<=AXIS_END; i++) {
-        if (!match(i, AaptGroupEntry::getConfigValueForAxis(config, i))) {
-            return false;
-        }
-    }
-    return true;
-}
-
-const SortedVector<uint32_t>* ResourceFilter::configsForAxis(int axis) const
-{
-    ssize_t index = mData.indexOfKey(axis);
-    if (index < 0) {
-        return NULL;
-    }
-    return &mData.valueAt(index);
-}
diff --git a/tools/aapt/ResourceFilter.h b/tools/aapt/ResourceFilter.h
deleted file mode 100644
index 647b7bb..0000000
--- a/tools/aapt/ResourceFilter.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-// Build resource files from raw assets.
-//
-
-#ifndef RESOURCE_FILTER_H
-#define RESOURCE_FILTER_H
-
-#include "AaptAssets.h"
-
-/**
- * Implements logic for parsing and handling "-c" and "--preferred-configurations"
- * options.
- */
-class ResourceFilter
-{
-public:
-    ResourceFilter() : mData(), mContainsPseudo(false) {}
-    status_t parse(const char* arg);
-    bool isEmpty() const;
-    bool match(int axis, uint32_t value) const;
-    bool match(int axis, const ResTable_config& config) const;
-    bool match(const ResTable_config& config) const;
-    const SortedVector<uint32_t>* configsForAxis(int axis) const;
-    inline bool containsPseudo() const { return mContainsPseudo; }
-
-private:
-    KeyedVector<int,SortedVector<uint32_t> > mData;
-    bool mContainsPseudo;
-};
-
-#endif
diff --git a/tools/aapt/ResourceIdCache.cpp b/tools/aapt/ResourceIdCache.cpp
deleted file mode 100644
index e03f4f6..0000000
--- a/tools/aapt/ResourceIdCache.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-//
-// Copyright 2012 The Android Open Source Project
-//
-// Manage a resource ID cache.
-
-#define LOG_TAG "ResourceIdCache"
-
-#include <utils/String16.h>
-#include <utils/Log.h>
-#include "ResourceIdCache.h"
-#include <map>
-using namespace std;
-
-
-static size_t mHits = 0;
-static size_t mMisses = 0;
-static size_t mCollisions = 0;
-
-static const size_t MAX_CACHE_ENTRIES = 2048;
-static const android::String16 TRUE16("1");
-static const android::String16 FALSE16("0");
-
-struct CacheEntry {
-    // concatenation of the relevant strings into a single instance
-    android::String16 hashedName;
-    uint32_t id;
-
-    CacheEntry() {}
-    CacheEntry(const android::String16& name, uint32_t resId) : hashedName(name), id(resId) { }
-};
-
-static map< uint32_t, CacheEntry > mIdMap;
-
-
-// djb2; reasonable choice for strings when collisions aren't particularly important
-static inline uint32_t hashround(uint32_t hash, int c) {
-    return ((hash << 5) + hash) + c;    /* hash * 33 + c */
-}
-
-static uint32_t hash(const android::String16& hashableString) {
-    uint32_t hash = 5381;
-    const char16_t* str = hashableString.string();
-    while (int c = *str++) hash = hashround(hash, c);
-    return hash;
-}
-
-namespace android {
-
-static inline String16 makeHashableName(const android::String16& package,
-        const android::String16& type,
-        const android::String16& name,
-        bool onlyPublic) {
-    String16 hashable = String16(name);
-    hashable += type;
-    hashable += package;
-    hashable += (onlyPublic ? TRUE16 : FALSE16);
-    return hashable;
-}
-
-uint32_t ResourceIdCache::lookup(const android::String16& package,
-        const android::String16& type,
-        const android::String16& name,
-        bool onlyPublic) {
-    const String16 hashedName = makeHashableName(package, type, name, onlyPublic);
-    const uint32_t hashcode = hash(hashedName);
-    map<uint32_t, CacheEntry>::iterator item = mIdMap.find(hashcode);
-    if (item == mIdMap.end()) {
-        // cache miss
-        mMisses++;
-        return 0;
-    }
-
-    // legit match?
-    if (hashedName == (*item).second.hashedName) {
-        mHits++;
-        return (*item).second.id;
-    }
-
-    // collision
-    mCollisions++;
-    mIdMap.erase(hashcode);
-    return 0;
-}
-
-// returns the resource ID being stored, for callsite convenience
-uint32_t ResourceIdCache::store(const android::String16& package,
-        const android::String16& type,
-        const android::String16& name,
-        bool onlyPublic,
-        uint32_t resId) {
-    if (mIdMap.size() < MAX_CACHE_ENTRIES) {
-        const String16 hashedName = makeHashableName(package, type, name, onlyPublic);
-        const uint32_t hashcode = hash(hashedName);
-        mIdMap[hashcode] = CacheEntry(hashedName, resId);
-    }
-    return resId;
-}
-
-void ResourceIdCache::dump() {
-    printf("ResourceIdCache dump:\n");
-    printf("Size: %ld\n", mIdMap.size());
-    printf("Hits:   %ld\n", mHits);
-    printf("Misses: %ld\n", mMisses);
-    printf("(Collisions: %ld)\n", mCollisions);
-}
-
-}
diff --git a/tools/aapt/ResourceIdCache.h b/tools/aapt/ResourceIdCache.h
deleted file mode 100644
index 65f7781..0000000
--- a/tools/aapt/ResourceIdCache.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright 2012 The Android Open Source Project
-//
-// Manage a resource ID cache.
-
-#ifndef RESOURCE_ID_CACHE_H
-#define RESOURCE_ID_CACHE_H
-
-namespace android {
-class android::String16;
-
-class ResourceIdCache {
-public:
-    static uint32_t lookup(const android::String16& package,
-            const android::String16& type,
-            const android::String16& name,
-            bool onlyPublic);
-
-    static uint32_t store(const android::String16& package,
-            const android::String16& type,
-            const android::String16& name,
-            bool onlyPublic,
-            uint32_t resId);
-
-    static void dump(void);
-};
-
-}
-
-#endif
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
deleted file mode 100644
index f2e5254..0000000
--- a/tools/aapt/ResourceTable.cpp
+++ /dev/null
@@ -1,3966 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Build resource files from raw assets.
-//
-
-#include "ResourceTable.h"
-
-#include "XMLNode.h"
-#include "ResourceFilter.h"
-#include "ResourceIdCache.h"
-
-#include <androidfw/ResourceTypes.h>
-#include <utils/ByteOrder.h>
-#include <stdarg.h>
-
-#define NOISY(x) //x
-
-status_t compileXmlFile(const sp<AaptAssets>& assets,
-                        const sp<AaptFile>& target,
-                        ResourceTable* table,
-                        int options)
-{
-    sp<XMLNode> root = XMLNode::parse(target);
-    if (root == NULL) {
-        return UNKNOWN_ERROR;
-    }
-    
-    return compileXmlFile(assets, root, target, table, options);
-}
-
-status_t compileXmlFile(const sp<AaptAssets>& assets,
-                        const sp<AaptFile>& target,
-                        const sp<AaptFile>& outTarget,
-                        ResourceTable* table,
-                        int options)
-{
-    sp<XMLNode> root = XMLNode::parse(target);
-    if (root == NULL) {
-        return UNKNOWN_ERROR;
-    }
-    
-    return compileXmlFile(assets, root, outTarget, table, options);
-}
-
-status_t compileXmlFile(const sp<AaptAssets>& assets,
-                        const sp<XMLNode>& root,
-                        const sp<AaptFile>& target,
-                        ResourceTable* table,
-                        int options)
-{
-    if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) {
-        root->removeWhitespace(true, NULL);
-    } else  if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) {
-        root->removeWhitespace(false, NULL);
-    }
-
-    if ((options&XML_COMPILE_UTF8) != 0) {
-        root->setUTF8(true);
-    }
-
-    bool hasErrors = false;
-    
-    if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) {
-        status_t err = root->assignResourceIds(assets, table);
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    status_t err = root->parseValues(assets, table);
-    if (err != NO_ERROR) {
-        hasErrors = true;
-    }
-
-    if (hasErrors) {
-        return UNKNOWN_ERROR;
-    }
-    
-    NOISY(printf("Input XML Resource:\n"));
-    NOISY(root->print());
-    err = root->flatten(target,
-            (options&XML_COMPILE_STRIP_COMMENTS) != 0,
-            (options&XML_COMPILE_STRIP_RAW_VALUES) != 0);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    NOISY(printf("Output XML Resource:\n"));
-    NOISY(ResXMLTree tree;
-        tree.setTo(target->getData(), target->getSize());
-        printXMLBlock(&tree));
-
-    target->setCompressionMethod(ZipEntry::kCompressDeflated);
-    
-    return err;
-}
-
-#undef NOISY
-#define NOISY(x) //x
-
-struct flag_entry
-{
-    const char16_t* name;
-    size_t nameLen;
-    uint32_t value;
-    const char* description;
-};
-
-static const char16_t referenceArray[] =
-    { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' };
-static const char16_t stringArray[] =
-    { 's', 't', 'r', 'i', 'n', 'g' };
-static const char16_t integerArray[] =
-    { 'i', 'n', 't', 'e', 'g', 'e', 'r' };
-static const char16_t booleanArray[] =
-    { 'b', 'o', 'o', 'l', 'e', 'a', 'n' };
-static const char16_t colorArray[] =
-    { 'c', 'o', 'l', 'o', 'r' };
-static const char16_t floatArray[] =
-    { 'f', 'l', 'o', 'a', 't' };
-static const char16_t dimensionArray[] =
-    { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' };
-static const char16_t fractionArray[] =
-    { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' };
-static const char16_t enumArray[] =
-    { 'e', 'n', 'u', 'm' };
-static const char16_t flagsArray[] =
-    { 'f', 'l', 'a', 'g', 's' };
-
-static const flag_entry gFormatFlags[] = {
-    { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE,
-      "a reference to another resource, in the form \"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\"\n"
-      "or to a theme attribute in the form \"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\"."},
-    { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING,
-      "a string value, using '\\\\;' to escape characters such as '\\\\n' or '\\\\uxxxx' for a unicode character." },
-    { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER,
-      "an integer value, such as \"<code>100</code>\"." },
-    { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN,
-      "a boolean value, either \"<code>true</code>\" or \"<code>false</code>\"." },
-    { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR,
-      "a color value, in the form of \"<code>#<i>rgb</i></code>\", \"<code>#<i>argb</i></code>\",\n"
-      "\"<code>#<i>rrggbb</i></code>\", or \"<code>#<i>aarrggbb</i></code>\"." },
-    { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT,
-      "a floating point value, such as \"<code>1.2</code>\"."},
-    { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION,
-      "a dimension value, which is a floating point number appended with a unit such as \"<code>14.5sp</code>\".\n"
-      "Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\n"
-      "in (inches), mm (millimeters)." },
-    { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION,
-      "a fractional value, which is a floating point number appended with either % or %p, such as \"<code>14.5%</code>\".\n"
-      "The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\n"
-      "some parent container." },
-    { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL },
-    { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL },
-    { NULL, 0, 0, NULL }
-};
-
-static const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' };
-
-static const flag_entry l10nRequiredFlags[] = {
-    { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL },
-    { NULL, 0, 0, NULL }
-};
-
-static const char16_t nulStr[] = { 0 };
-
-static uint32_t parse_flags(const char16_t* str, size_t len,
-                             const flag_entry* flags, bool* outError = NULL)
-{
-    while (len > 0 && isspace(*str)) {
-        str++;
-        len--;
-    }
-    while (len > 0 && isspace(str[len-1])) {
-        len--;
-    }
-
-    const char16_t* const end = str + len;
-    uint32_t value = 0;
-
-    while (str < end) {
-        const char16_t* div = str;
-        while (div < end && *div != '|') {
-            div++;
-        }
-
-        const flag_entry* cur = flags;
-        while (cur->name) {
-            if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) {
-                value |= cur->value;
-                break;
-            }
-            cur++;
-        }
-
-        if (!cur->name) {
-            if (outError) *outError = true;
-            return 0;
-        }
-
-        str = div < end ? div+1 : div;
-    }
-
-    if (outError) *outError = false;
-    return value;
-}
-
-static String16 mayOrMust(int type, int flags)
-{
-    if ((type&(~flags)) == 0) {
-        return String16("<p>Must");
-    }
-    
-    return String16("<p>May");
-}
-
-static void appendTypeInfo(ResourceTable* outTable, const String16& pkg,
-        const String16& typeName, const String16& ident, int type,
-        const flag_entry* flags)
-{
-    bool hadType = false;
-    while (flags->name) {
-        if ((type&flags->value) != 0 && flags->description != NULL) {
-            String16 fullMsg(mayOrMust(type, flags->value));
-            fullMsg.append(String16(" be "));
-            fullMsg.append(String16(flags->description));
-            outTable->appendTypeComment(pkg, typeName, ident, fullMsg);
-            hadType = true;
-        }
-        flags++;
-    }
-    if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) {
-        outTable->appendTypeComment(pkg, typeName, ident,
-                String16("<p>This may also be a reference to a resource (in the form\n"
-                         "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n"
-                         "theme attribute (in the form\n"
-                         "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n"
-                         "containing a value of this type."));
-    }
-}
-
-struct PendingAttribute
-{
-    const String16 myPackage;
-    const SourcePos sourcePos;
-    const bool appendComment;
-    int32_t type;
-    String16 ident;
-    String16 comment;
-    bool hasErrors;
-    bool added;
-    
-    PendingAttribute(String16 _package, const sp<AaptFile>& in,
-            ResXMLTree& block, bool _appendComment)
-        : myPackage(_package)
-        , sourcePos(in->getPrintableSource(), block.getLineNumber())
-        , appendComment(_appendComment)
-        , type(ResTable_map::TYPE_ANY)
-        , hasErrors(false)
-        , added(false)
-    {
-    }
-    
-    status_t createIfNeeded(ResourceTable* outTable)
-    {
-        if (added || hasErrors) {
-            return NO_ERROR;
-        }
-        added = true;
-
-        String16 attr16("attr");
-        
-        if (outTable->hasBagOrEntry(myPackage, attr16, ident)) {
-            sourcePos.error("Attribute \"%s\" has already been defined\n",
-                    String8(ident).string());
-            hasErrors = true;
-            return UNKNOWN_ERROR;
-        }
-        
-        char numberStr[16];
-        sprintf(numberStr, "%d", type);
-        status_t err = outTable->addBag(sourcePos, myPackage,
-                attr16, ident, String16(""),
-                String16("^type"),
-                String16(numberStr), NULL, NULL);
-        if (err != NO_ERROR) {
-            hasErrors = true;
-            return err;
-        }
-        outTable->appendComment(myPackage, attr16, ident, comment, appendComment);
-        //printf("Attribute %s comment: %s\n", String8(ident).string(),
-        //     String8(comment).string());
-        return err;
-    }
-};
-
-static status_t compileAttribute(const sp<AaptFile>& in,
-                                 ResXMLTree& block,
-                                 const String16& myPackage,
-                                 ResourceTable* outTable,
-                                 String16* outIdent = NULL,
-                                 bool inStyleable = false)
-{
-    PendingAttribute attr(myPackage, in, block, inStyleable);
-    
-    const String16 attr16("attr");
-    const String16 id16("id");
-
-    // Attribute type constants.
-    const String16 enum16("enum");
-    const String16 flag16("flag");
-
-    ResXMLTree::event_code_t code;
-    size_t len;
-    status_t err;
-    
-    ssize_t identIdx = block.indexOfAttribute(NULL, "name");
-    if (identIdx >= 0) {
-        attr.ident = String16(block.getAttributeStringValue(identIdx, &len));
-        if (outIdent) {
-            *outIdent = attr.ident;
-        }
-    } else {
-        attr.sourcePos.error("A 'name' attribute is required for <attr>\n");
-        attr.hasErrors = true;
-    }
-
-    attr.comment = String16(
-            block.getComment(&len) ? block.getComment(&len) : nulStr);
-
-    ssize_t typeIdx = block.indexOfAttribute(NULL, "format");
-    if (typeIdx >= 0) {
-        String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len));
-        attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags);
-        if (attr.type == 0) {
-            attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n",
-                    String8(typeStr).string());
-            attr.hasErrors = true;
-        }
-        attr.createIfNeeded(outTable);
-    } else if (!inStyleable) {
-        // Attribute definitions outside of styleables always define the
-        // attribute as a generic value.
-        attr.createIfNeeded(outTable);
-    }
-
-    //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type);
-
-    ssize_t minIdx = block.indexOfAttribute(NULL, "min");
-    if (minIdx >= 0) {
-        String16 val = String16(block.getAttributeStringValue(minIdx, &len));
-        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
-            attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n",
-                    String8(val).string());
-            attr.hasErrors = true;
-        }
-        attr.createIfNeeded(outTable);
-        if (!attr.hasErrors) {
-            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
-                    String16(""), String16("^min"), String16(val), NULL, NULL);
-            if (err != NO_ERROR) {
-                attr.hasErrors = true;
-            }
-        }
-    }
-
-    ssize_t maxIdx = block.indexOfAttribute(NULL, "max");
-    if (maxIdx >= 0) {
-        String16 val = String16(block.getAttributeStringValue(maxIdx, &len));
-        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
-            attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n",
-                    String8(val).string());
-            attr.hasErrors = true;
-        }
-        attr.createIfNeeded(outTable);
-        if (!attr.hasErrors) {
-            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
-                    String16(""), String16("^max"), String16(val), NULL, NULL);
-            attr.hasErrors = true;
-        }
-    }
-
-    if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) {
-        attr.sourcePos.error("Tag <attr> must have format=integer attribute if using max or min\n");
-        attr.hasErrors = true;
-    }
-
-    ssize_t l10nIdx = block.indexOfAttribute(NULL, "localization");
-    if (l10nIdx >= 0) {
-        const uint16_t* str = block.getAttributeStringValue(l10nIdx, &len);
-        bool error;
-        uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error);
-        if (error) {
-            attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n",
-                    String8(str).string());
-            attr.hasErrors = true;
-        }
-        attr.createIfNeeded(outTable);
-        if (!attr.hasErrors) {
-            char buf[11];
-            sprintf(buf, "%d", l10n_required);
-            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
-                    String16(""), String16("^l10n"), String16(buf), NULL, NULL);
-            if (err != NO_ERROR) {
-                attr.hasErrors = true;
-            }
-        }
-    }
-
-    String16 enumOrFlagsComment;
-    
-    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-        if (code == ResXMLTree::START_TAG) {
-            uint32_t localType = 0;
-            if (strcmp16(block.getElementName(&len), enum16.string()) == 0) {
-                localType = ResTable_map::TYPE_ENUM;
-            } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) {
-                localType = ResTable_map::TYPE_FLAGS;
-            } else {
-                SourcePos(in->getPrintableSource(), block.getLineNumber())
-                        .error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n",
-                        String8(block.getElementName(&len)).string());
-                return UNKNOWN_ERROR;
-            }
-
-            attr.createIfNeeded(outTable);
-            
-            if (attr.type == ResTable_map::TYPE_ANY) {
-                // No type was explicitly stated, so supplying enum tags
-                // implicitly creates an enum or flag.
-                attr.type = 0;
-            }
-
-            if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) {
-                // Wasn't originally specified as an enum, so update its type.
-                attr.type |= localType;
-                if (!attr.hasErrors) {
-                    char numberStr[16];
-                    sprintf(numberStr, "%d", attr.type);
-                    err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
-                            myPackage, attr16, attr.ident, String16(""),
-                            String16("^type"), String16(numberStr), NULL, NULL, true);
-                    if (err != NO_ERROR) {
-                        attr.hasErrors = true;
-                    }
-                }
-            } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) {
-                if (localType == ResTable_map::TYPE_ENUM) {
-                    SourcePos(in->getPrintableSource(), block.getLineNumber())
-                            .error("<enum> attribute can not be used inside a flags format\n");
-                    attr.hasErrors = true;
-                } else {
-                    SourcePos(in->getPrintableSource(), block.getLineNumber())
-                            .error("<flag> attribute can not be used inside a enum format\n");
-                    attr.hasErrors = true;
-                }
-            }
-
-            String16 itemIdent;
-            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name");
-            if (itemIdentIdx >= 0) {
-                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));
-            } else {
-                SourcePos(in->getPrintableSource(), block.getLineNumber())
-                        .error("A 'name' attribute is required for <enum> or <flag>\n");
-                attr.hasErrors = true;
-            }
-
-            String16 value;
-            ssize_t valueIdx = block.indexOfAttribute(NULL, "value");
-            if (valueIdx >= 0) {
-                value = String16(block.getAttributeStringValue(valueIdx, &len));
-            } else {
-                SourcePos(in->getPrintableSource(), block.getLineNumber())
-                        .error("A 'value' attribute is required for <enum> or <flag>\n");
-                attr.hasErrors = true;
-            }
-            if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) {
-                SourcePos(in->getPrintableSource(), block.getLineNumber())
-                        .error("Tag <enum> or <flag> 'value' attribute must be a number,"
-                        " not \"%s\"\n",
-                        String8(value).string());
-                attr.hasErrors = true;
-            }
-
-            // Make sure an id is defined for this enum/flag identifier...
-            if (!attr.hasErrors && !outTable->hasBagOrEntry(itemIdent, &id16, &myPackage)) {
-                err = outTable->startBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
-                                         myPackage, id16, itemIdent, String16(), NULL);
-                if (err != NO_ERROR) {
-                    attr.hasErrors = true;
-                }
-            }
-
-            if (!attr.hasErrors) {
-                if (enumOrFlagsComment.size() == 0) {
-                    enumOrFlagsComment.append(mayOrMust(attr.type,
-                            ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS));
-                    enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM)
-                                       ? String16(" be one of the following constant values.")
-                                       : String16(" be one or more (separated by '|') of the following constant values."));
-                    enumOrFlagsComment.append(String16("</p>\n<table>\n"
-                                                "<colgroup align=\"left\" />\n"
-                                                "<colgroup align=\"left\" />\n"
-                                                "<colgroup align=\"left\" />\n"
-                                                "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>"));
-                }
-                
-                enumOrFlagsComment.append(String16("\n<tr><td><code>"));
-                enumOrFlagsComment.append(itemIdent);
-                enumOrFlagsComment.append(String16("</code></td><td>"));
-                enumOrFlagsComment.append(value);
-                enumOrFlagsComment.append(String16("</td><td>"));
-                if (block.getComment(&len)) {
-                    enumOrFlagsComment.append(String16(block.getComment(&len)));
-                }
-                enumOrFlagsComment.append(String16("</td></tr>"));
-                
-                err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
-                                       myPackage,
-                                       attr16, attr.ident, String16(""),
-                                       itemIdent, value, NULL, NULL, false, true);
-                if (err != NO_ERROR) {
-                    attr.hasErrors = true;
-                }
-            }
-        } else if (code == ResXMLTree::END_TAG) {
-            if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
-                break;
-            }
-            if ((attr.type&ResTable_map::TYPE_ENUM) != 0) {
-                if (strcmp16(block.getElementName(&len), enum16.string()) != 0) {
-                    SourcePos(in->getPrintableSource(), block.getLineNumber())
-                            .error("Found tag </%s> where </enum> is expected\n",
-                            String8(block.getElementName(&len)).string());
-                    return UNKNOWN_ERROR;
-                }
-            } else {
-                if (strcmp16(block.getElementName(&len), flag16.string()) != 0) {
-                    SourcePos(in->getPrintableSource(), block.getLineNumber())
-                            .error("Found tag </%s> where </flag> is expected\n",
-                            String8(block.getElementName(&len)).string());
-                    return UNKNOWN_ERROR;
-                }
-            }
-        }
-    }
-    
-    if (!attr.hasErrors && attr.added) {
-        appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags);
-    }
-    
-    if (!attr.hasErrors && enumOrFlagsComment.size() > 0) {
-        enumOrFlagsComment.append(String16("\n</table>"));
-        outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment);
-    }
-
-
-    return NO_ERROR;
-}
-
-bool localeIsDefined(const ResTable_config& config)
-{
-    return config.locale == 0;
-}
-
-status_t parseAndAddBag(Bundle* bundle,
-                        const sp<AaptFile>& in,
-                        ResXMLTree* block,
-                        const ResTable_config& config,
-                        const String16& myPackage,
-                        const String16& curType,
-                        const String16& ident,
-                        const String16& parentIdent,
-                        const String16& itemIdent,
-                        int32_t curFormat,
-                        bool isFormatted,
-                        const String16& product,
-                        bool pseudolocalize,
-                        const bool overwrite,
-                        ResourceTable* outTable)
-{
-    status_t err;
-    const String16 item16("item");
-    
-    String16 str;
-    Vector<StringPool::entry_style_span> spans;
-    err = parseStyledString(bundle, in->getPrintableSource().string(),
-                            block, item16, &str, &spans, isFormatted,
-                            pseudolocalize);
-    if (err != NO_ERROR) {
-        return err;
-    }
-    
-    NOISY(printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d "
-                 " pid=%s, bag=%s, id=%s: %s\n",
-                 config.language[0], config.language[1],
-                 config.country[0], config.country[1],
-                 config.orientation, config.density,
-                 String8(parentIdent).string(),
-                 String8(ident).string(),
-                 String8(itemIdent).string(),
-                 String8(str).string()));
-
-    err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()),
-                           myPackage, curType, ident, parentIdent, itemIdent, str,
-                           &spans, &config, overwrite, false, curFormat);
-    return err;
-}
-
-/*
- * Returns true if needle is one of the elements in the comma-separated list
- * haystack, false otherwise.
- */
-bool isInProductList(const String16& needle, const String16& haystack) {
-    const char16_t *needle2 = needle.string();
-    const char16_t *haystack2 = haystack.string();
-    size_t needlesize = needle.size();
-
-    while (*haystack2 != '\0') {
-        if (strncmp16(haystack2, needle2, needlesize) == 0) {
-            if (haystack2[needlesize] == '\0' || haystack2[needlesize] == ',') {
-                return true;
-            }
-        }
-
-        while (*haystack2 != '\0' && *haystack2 != ',') {
-            haystack2++;
-        }
-        if (*haystack2 == ',') {
-            haystack2++;
-        }
-    }
-
-    return false;
-}
-
-/*
- * A simple container that holds a resource type and name. It is ordered first by type then
- * by name.
- */
-struct type_ident_pair_t {
-    String16 type;
-    String16 ident;
-
-    type_ident_pair_t() { };
-    type_ident_pair_t(const String16& t, const String16& i) : type(t), ident(i) { }
-    type_ident_pair_t(const type_ident_pair_t& o) : type(o.type), ident(o.ident) { }
-    inline bool operator < (const type_ident_pair_t& o) const {
-        int cmp = compare_type(type, o.type);
-        if (cmp < 0) {
-            return true;
-        } else if (cmp > 0) {
-            return false;
-        } else {
-            return strictly_order_type(ident, o.ident);
-        }
-    }
-};
-
-
-status_t parseAndAddEntry(Bundle* bundle,
-                        const sp<AaptFile>& in,
-                        ResXMLTree* block,
-                        const ResTable_config& config,
-                        const String16& myPackage,
-                        const String16& curType,
-                        const String16& ident,
-                        const String16& curTag,
-                        bool curIsStyled,
-                        int32_t curFormat,
-                        bool isFormatted,
-                        const String16& product,
-                        bool pseudolocalize,
-                        const bool overwrite,
-                        KeyedVector<type_ident_pair_t, bool>* skippedResourceNames,
-                        ResourceTable* outTable)
-{
-    status_t err;
-
-    String16 str;
-    Vector<StringPool::entry_style_span> spans;
-    err = parseStyledString(bundle, in->getPrintableSource().string(), block,
-                            curTag, &str, curIsStyled ? &spans : NULL,
-                            isFormatted, pseudolocalize);
-
-    if (err < NO_ERROR) { 
-        return err;
-    }
-
-    /*
-     * If a product type was specified on the command line
-     * and also in the string, and the two are not the same,
-     * return without adding the string.
-     */
-
-    const char *bundleProduct = bundle->getProduct();
-    if (bundleProduct == NULL) {
-        bundleProduct = "";
-    }
-
-    if (product.size() != 0) {
-        /*
-         * If the command-line-specified product is empty, only "default"
-         * matches.  Other variants are skipped.  This is so generation
-         * of the R.java file when the product is not known is predictable.
-         */
-
-        if (bundleProduct[0] == '\0') {
-            if (strcmp16(String16("default").string(), product.string()) != 0) {
-                /*
-                 * This string has a product other than 'default'. Do not add it,
-                 * but record it so that if we do not see the same string with
-                 * product 'default' or no product, then report an error.
-                 */
-                skippedResourceNames->replaceValueFor(
-                        type_ident_pair_t(curType, ident), true);
-                return NO_ERROR;
-            }
-        } else {
-            /*
-             * The command-line product is not empty.
-             * If the product for this string is on the command-line list,
-             * it matches.  "default" also matches, but only if nothing
-             * else has matched already.
-             */
-
-            if (isInProductList(product, String16(bundleProduct))) {
-                ;
-            } else if (strcmp16(String16("default").string(), product.string()) == 0 &&
-                       !outTable->hasBagOrEntry(myPackage, curType, ident, config)) {
-                ;
-            } else {
-                return NO_ERROR;
-            }
-        }
-    }
-
-    NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n",
-                 config.language[0], config.language[1],
-                 config.country[0], config.country[1],
-                 config.orientation, config.density,
-                 String8(ident).string(), String8(str).string()));
-
-    err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()),
-                             myPackage, curType, ident, str, &spans, &config,
-                             false, curFormat, overwrite);
-
-    return err;
-}
-
-status_t compileResourceFile(Bundle* bundle,
-                             const sp<AaptAssets>& assets,
-                             const sp<AaptFile>& in,
-                             const ResTable_config& defParams,
-                             const bool overwrite,
-                             ResourceTable* outTable)
-{
-    ResXMLTree block;
-    status_t err = parseXMLResource(in, &block, false, true);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    // Top-level tag.
-    const String16 resources16("resources");
-
-    // Identifier declaration tags.
-    const String16 declare_styleable16("declare-styleable");
-    const String16 attr16("attr");
-
-    // Data creation organizational tags.
-    const String16 string16("string");
-    const String16 drawable16("drawable");
-    const String16 color16("color");
-    const String16 bool16("bool");
-    const String16 integer16("integer");
-    const String16 dimen16("dimen");
-    const String16 fraction16("fraction");
-    const String16 style16("style");
-    const String16 plurals16("plurals");
-    const String16 array16("array");
-    const String16 string_array16("string-array");
-    const String16 integer_array16("integer-array");
-    const String16 public16("public");
-    const String16 public_padding16("public-padding");
-    const String16 private_symbols16("private-symbols");
-    const String16 java_symbol16("java-symbol");
-    const String16 add_resource16("add-resource");
-    const String16 skip16("skip");
-    const String16 eat_comment16("eat-comment");
-
-    // Data creation tags.
-    const String16 bag16("bag");
-    const String16 item16("item");
-
-    // Attribute type constants.
-    const String16 enum16("enum");
-
-    // plural values
-    const String16 other16("other");
-    const String16 quantityOther16("^other");
-    const String16 zero16("zero");
-    const String16 quantityZero16("^zero");
-    const String16 one16("one");
-    const String16 quantityOne16("^one");
-    const String16 two16("two");
-    const String16 quantityTwo16("^two");
-    const String16 few16("few");
-    const String16 quantityFew16("^few");
-    const String16 many16("many");
-    const String16 quantityMany16("^many");
-
-    // useful attribute names and special values
-    const String16 name16("name");
-    const String16 translatable16("translatable");
-    const String16 formatted16("formatted");
-    const String16 false16("false");
-
-    const String16 myPackage(assets->getPackage());
-
-    bool hasErrors = false;
-
-    bool fileIsTranslatable = true;
-    if (strstr(in->getPrintableSource().string(), "donottranslate") != NULL) {
-        fileIsTranslatable = false;
-    }
-
-    DefaultKeyedVector<String16, uint32_t> nextPublicId(0);
-
-    // Stores the resource names that were skipped. Typically this happens when
-    // AAPT is invoked without a product specified and a resource has no
-    // 'default' product attribute.
-    KeyedVector<type_ident_pair_t, bool> skippedResourceNames;
-
-    ResXMLTree::event_code_t code;
-    do {
-        code = block.next();
-    } while (code == ResXMLTree::START_NAMESPACE);
-
-    size_t len;
-    if (code != ResXMLTree::START_TAG) {
-        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                "No start tag found\n");
-        return UNKNOWN_ERROR;
-    }
-    if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
-        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                "Invalid start tag %s\n", String8(block.getElementName(&len)).string());
-        return UNKNOWN_ERROR;
-    }
-
-    ResTable_config curParams(defParams);
-
-    ResTable_config pseudoParams(curParams);
-        pseudoParams.language[0] = 'z';
-        pseudoParams.language[1] = 'z';
-        pseudoParams.country[0] = 'Z';
-        pseudoParams.country[1] = 'Z';
-
-    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-        if (code == ResXMLTree::START_TAG) {
-            const String16* curTag = NULL;
-            String16 curType;
-            int32_t curFormat = ResTable_map::TYPE_ANY;
-            bool curIsBag = false;
-            bool curIsBagReplaceOnOverwrite = false;
-            bool curIsStyled = false;
-            bool curIsPseudolocalizable = false;
-            bool curIsFormatted = fileIsTranslatable;
-            bool localHasErrors = false;
-
-            if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
-                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
-                        && code != ResXMLTree::BAD_DOCUMENT) {
-                    if (code == ResXMLTree::END_TAG) {
-                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
-                            break;
-                        }
-                    }
-                }
-                continue;
-
-            } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
-                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
-                        && code != ResXMLTree::BAD_DOCUMENT) {
-                    if (code == ResXMLTree::END_TAG) {
-                        if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
-                            break;
-                        }
-                    }
-                }
-                continue;
-
-            } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
-                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
-            
-                String16 type;
-                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
-                if (typeIdx < 0) {
-                    srcPos.error("A 'type' attribute is required for <public>\n");
-                    hasErrors = localHasErrors = true;
-                }
-                type = String16(block.getAttributeStringValue(typeIdx, &len));
-
-                String16 name;
-                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
-                if (nameIdx < 0) {
-                    srcPos.error("A 'name' attribute is required for <public>\n");
-                    hasErrors = localHasErrors = true;
-                }
-                name = String16(block.getAttributeStringValue(nameIdx, &len));
-
-                uint32_t ident = 0;
-                ssize_t identIdx = block.indexOfAttribute(NULL, "id");
-                if (identIdx >= 0) {
-                    const char16_t* identStr = block.getAttributeStringValue(identIdx, &len);
-                    Res_value identValue;
-                    if (!ResTable::stringToInt(identStr, len, &identValue)) {
-                        srcPos.error("Given 'id' attribute is not an integer: %s\n",
-                                String8(block.getAttributeStringValue(identIdx, &len)).string());
-                        hasErrors = localHasErrors = true;
-                    } else {
-                        ident = identValue.data;
-                        nextPublicId.replaceValueFor(type, ident+1);
-                    }
-                } else if (nextPublicId.indexOfKey(type) < 0) {
-                    srcPos.error("No 'id' attribute supplied <public>,"
-                            " and no previous id defined in this file.\n");
-                    hasErrors = localHasErrors = true;
-                } else if (!localHasErrors) {
-                    ident = nextPublicId.valueFor(type);
-                    nextPublicId.replaceValueFor(type, ident+1);
-                }
-
-                if (!localHasErrors) {
-                    err = outTable->addPublic(srcPos, myPackage, type, name, ident);
-                    if (err < NO_ERROR) {
-                        hasErrors = localHasErrors = true;
-                    }
-                }
-                if (!localHasErrors) {
-                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
-                    if (symbols != NULL) {
-                        symbols = symbols->addNestedSymbol(String8(type), srcPos);
-                    }
-                    if (symbols != NULL) {
-                        symbols->makeSymbolPublic(String8(name), srcPos);
-                        String16 comment(
-                            block.getComment(&len) ? block.getComment(&len) : nulStr);
-                        symbols->appendComment(String8(name), comment, srcPos);
-                    } else {
-                        srcPos.error("Unable to create symbols!\n");
-                        hasErrors = localHasErrors = true;
-                    }
-                }
-
-                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-                    if (code == ResXMLTree::END_TAG) {
-                        if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
-                            break;
-                        }
-                    }
-                }
-                continue;
-
-            } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
-                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
-            
-                String16 type;
-                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
-                if (typeIdx < 0) {
-                    srcPos.error("A 'type' attribute is required for <public-padding>\n");
-                    hasErrors = localHasErrors = true;
-                }
-                type = String16(block.getAttributeStringValue(typeIdx, &len));
-
-                String16 name;
-                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
-                if (nameIdx < 0) {
-                    srcPos.error("A 'name' attribute is required for <public-padding>\n");
-                    hasErrors = localHasErrors = true;
-                }
-                name = String16(block.getAttributeStringValue(nameIdx, &len));
-
-                uint32_t start = 0;
-                ssize_t startIdx = block.indexOfAttribute(NULL, "start");
-                if (startIdx >= 0) {
-                    const char16_t* startStr = block.getAttributeStringValue(startIdx, &len);
-                    Res_value startValue;
-                    if (!ResTable::stringToInt(startStr, len, &startValue)) {
-                        srcPos.error("Given 'start' attribute is not an integer: %s\n",
-                                String8(block.getAttributeStringValue(startIdx, &len)).string());
-                        hasErrors = localHasErrors = true;
-                    } else {
-                        start = startValue.data;
-                    }
-                } else if (nextPublicId.indexOfKey(type) < 0) {
-                    srcPos.error("No 'start' attribute supplied <public-padding>,"
-                            " and no previous id defined in this file.\n");
-                    hasErrors = localHasErrors = true;
-                } else if (!localHasErrors) {
-                    start = nextPublicId.valueFor(type);
-                }
-
-                uint32_t end = 0;
-                ssize_t endIdx = block.indexOfAttribute(NULL, "end");
-                if (endIdx >= 0) {
-                    const char16_t* endStr = block.getAttributeStringValue(endIdx, &len);
-                    Res_value endValue;
-                    if (!ResTable::stringToInt(endStr, len, &endValue)) {
-                        srcPos.error("Given 'end' attribute is not an integer: %s\n",
-                                String8(block.getAttributeStringValue(endIdx, &len)).string());
-                        hasErrors = localHasErrors = true;
-                    } else {
-                        end = endValue.data;
-                    }
-                } else {
-                    srcPos.error("No 'end' attribute supplied <public-padding>\n");
-                    hasErrors = localHasErrors = true;
-                }
-
-                if (end >= start) {
-                    nextPublicId.replaceValueFor(type, end+1);
-                } else {
-                    srcPos.error("Padding start '%ul' is after end '%ul'\n",
-                            start, end);
-                    hasErrors = localHasErrors = true;
-                }
-                
-                String16 comment(
-                    block.getComment(&len) ? block.getComment(&len) : nulStr);
-                for (uint32_t curIdent=start; curIdent<=end; curIdent++) {
-                    if (localHasErrors) {
-                        break;
-                    }
-                    String16 curName(name);
-                    char buf[64];
-                    sprintf(buf, "%d", (int)(end-curIdent+1));
-                    curName.append(String16(buf));
-                    
-                    err = outTable->addEntry(srcPos, myPackage, type, curName,
-                                             String16("padding"), NULL, &curParams, false,
-                                             ResTable_map::TYPE_STRING, overwrite);
-                    if (err < NO_ERROR) {
-                        hasErrors = localHasErrors = true;
-                        break;
-                    }
-                    err = outTable->addPublic(srcPos, myPackage, type,
-                            curName, curIdent);
-                    if (err < NO_ERROR) {
-                        hasErrors = localHasErrors = true;
-                        break;
-                    }
-                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
-                    if (symbols != NULL) {
-                        symbols = symbols->addNestedSymbol(String8(type), srcPos);
-                    }
-                    if (symbols != NULL) {
-                        symbols->makeSymbolPublic(String8(curName), srcPos);
-                        symbols->appendComment(String8(curName), comment, srcPos);
-                    } else {
-                        srcPos.error("Unable to create symbols!\n");
-                        hasErrors = localHasErrors = true;
-                    }
-                }
-
-                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-                    if (code == ResXMLTree::END_TAG) {
-                        if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
-                            break;
-                        }
-                    }
-                }
-                continue;
-
-            } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
-                String16 pkg;
-                ssize_t pkgIdx = block.indexOfAttribute(NULL, "package");
-                if (pkgIdx < 0) {
-                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                            "A 'package' attribute is required for <private-symbols>\n");
-                    hasErrors = localHasErrors = true;
-                }
-                pkg = String16(block.getAttributeStringValue(pkgIdx, &len));
-                if (!localHasErrors) {
-                    assets->setSymbolsPrivatePackage(String8(pkg));
-                }
-
-                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-                    if (code == ResXMLTree::END_TAG) {
-                        if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
-                            break;
-                        }
-                    }
-                }
-                continue;
-
-            } else if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) {
-                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
-            
-                String16 type;
-                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
-                if (typeIdx < 0) {
-                    srcPos.error("A 'type' attribute is required for <public>\n");
-                    hasErrors = localHasErrors = true;
-                }
-                type = String16(block.getAttributeStringValue(typeIdx, &len));
-
-                String16 name;
-                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
-                if (nameIdx < 0) {
-                    srcPos.error("A 'name' attribute is required for <public>\n");
-                    hasErrors = localHasErrors = true;
-                }
-                name = String16(block.getAttributeStringValue(nameIdx, &len));
-
-                sp<AaptSymbols> symbols = assets->getJavaSymbolsFor(String8("R"));
-                if (symbols != NULL) {
-                    symbols = symbols->addNestedSymbol(String8(type), srcPos);
-                }
-                if (symbols != NULL) {
-                    symbols->makeSymbolJavaSymbol(String8(name), srcPos);
-                    String16 comment(
-                        block.getComment(&len) ? block.getComment(&len) : nulStr);
-                    symbols->appendComment(String8(name), comment, srcPos);
-                } else {
-                    srcPos.error("Unable to create symbols!\n");
-                    hasErrors = localHasErrors = true;
-                }
-
-                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-                    if (code == ResXMLTree::END_TAG) {
-                        if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) {
-                            break;
-                        }
-                    }
-                }
-                continue;
-
-
-            } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
-                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
-            
-                String16 typeName;
-                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
-                if (typeIdx < 0) {
-                    srcPos.error("A 'type' attribute is required for <add-resource>\n");
-                    hasErrors = localHasErrors = true;
-                }
-                typeName = String16(block.getAttributeStringValue(typeIdx, &len));
-
-                String16 name;
-                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
-                if (nameIdx < 0) {
-                    srcPos.error("A 'name' attribute is required for <add-resource>\n");
-                    hasErrors = localHasErrors = true;
-                }
-                name = String16(block.getAttributeStringValue(nameIdx, &len));
-
-                outTable->canAddEntry(srcPos, myPackage, typeName, name);
-
-                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-                    if (code == ResXMLTree::END_TAG) {
-                        if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
-                            break;
-                        }
-                    }
-                }
-                continue;
-                
-            } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
-                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
-                                
-                String16 ident;
-                ssize_t identIdx = block.indexOfAttribute(NULL, "name");
-                if (identIdx < 0) {
-                    srcPos.error("A 'name' attribute is required for <declare-styleable>\n");
-                    hasErrors = localHasErrors = true;
-                }
-                ident = String16(block.getAttributeStringValue(identIdx, &len));
-
-                sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
-                if (!localHasErrors) {
-                    if (symbols != NULL) {
-                        symbols = symbols->addNestedSymbol(String8("styleable"), srcPos);
-                    }
-                    sp<AaptSymbols> styleSymbols = symbols;
-                    if (symbols != NULL) {
-                        symbols = symbols->addNestedSymbol(String8(ident), srcPos);
-                    }
-                    if (symbols == NULL) {
-                        srcPos.error("Unable to create symbols!\n");
-                        return UNKNOWN_ERROR;
-                    }
-                    
-                    String16 comment(
-                        block.getComment(&len) ? block.getComment(&len) : nulStr);
-                    styleSymbols->appendComment(String8(ident), comment, srcPos);
-                } else {
-                    symbols = NULL;
-                }
-
-                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-                    if (code == ResXMLTree::START_TAG) {
-                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
-                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT
-                                   && code != ResXMLTree::BAD_DOCUMENT) {
-                                if (code == ResXMLTree::END_TAG) {
-                                    if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
-                                        break;
-                                    }
-                                }
-                            }
-                            continue;
-                        } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
-                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT
-                                   && code != ResXMLTree::BAD_DOCUMENT) {
-                                if (code == ResXMLTree::END_TAG) {
-                                    if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
-                                        break;
-                                    }
-                                }
-                            }
-                            continue;
-                        } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) {
-                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                                    "Tag <%s> can not appear inside <declare-styleable>, only <attr>\n",
-                                    String8(block.getElementName(&len)).string());
-                            return UNKNOWN_ERROR;
-                        }
-
-                        String16 comment(
-                            block.getComment(&len) ? block.getComment(&len) : nulStr);
-                        String16 itemIdent;
-                        err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true);
-                        if (err != NO_ERROR) {
-                            hasErrors = localHasErrors = true;
-                        }
-
-                        if (symbols != NULL) {
-                            SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber());
-                            symbols->addSymbol(String8(itemIdent), 0, srcPos);
-                            symbols->appendComment(String8(itemIdent), comment, srcPos);
-                            //printf("Attribute %s comment: %s\n", String8(itemIdent).string(),
-                            //     String8(comment).string());
-                        }
-                    } else if (code == ResXMLTree::END_TAG) {
-                        if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
-                            break;
-                        }
-
-                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                                "Found tag </%s> where </attr> is expected\n",
-                                String8(block.getElementName(&len)).string());
-                        return UNKNOWN_ERROR;
-                    }
-                }
-                continue;
-
-            } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
-                err = compileAttribute(in, block, myPackage, outTable, NULL);
-                if (err != NO_ERROR) {
-                    hasErrors = true;
-                }
-                continue;
-
-            } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) {
-                curTag = &item16;
-                ssize_t attri = block.indexOfAttribute(NULL, "type");
-                if (attri >= 0) {
-                    curType = String16(block.getAttributeStringValue(attri, &len));
-                    ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
-                    if (formatIdx >= 0) {
-                        String16 formatStr = String16(block.getAttributeStringValue(
-                                formatIdx, &len));
-                        curFormat = parse_flags(formatStr.string(), formatStr.size(),
-                                                gFormatFlags);
-                        if (curFormat == 0) {
-                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                                    "Tag <item> 'format' attribute value \"%s\" not valid\n",
-                                    String8(formatStr).string());
-                            hasErrors = localHasErrors = true;
-                        }
-                    }
-                } else {
-                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                            "A 'type' attribute is required for <item>\n");
-                    hasErrors = localHasErrors = true;
-                }
-                curIsStyled = true;
-            } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) {
-                // Note the existence and locale of every string we process
-                char rawLocale[16];
-                curParams.getLocale(rawLocale);
-                String8 locale(rawLocale);
-                String16 name;
-                String16 translatable;
-                String16 formatted;
-
-                size_t n = block.getAttributeCount();
-                for (size_t i = 0; i < n; i++) {
-                    size_t length;
-                    const uint16_t* attr = block.getAttributeName(i, &length);
-                    if (strcmp16(attr, name16.string()) == 0) {
-                        name.setTo(block.getAttributeStringValue(i, &length));
-                    } else if (strcmp16(attr, translatable16.string()) == 0) {
-                        translatable.setTo(block.getAttributeStringValue(i, &length));
-                    } else if (strcmp16(attr, formatted16.string()) == 0) {
-                        formatted.setTo(block.getAttributeStringValue(i, &length));
-                    }
-                }
-                
-                if (name.size() > 0) {
-                    if (translatable == false16) {
-                        curIsFormatted = false;
-                        // Untranslatable strings must only exist in the default [empty] locale
-                        if (locale.size() > 0) {
-                            fprintf(stderr, "aapt: warning: string '%s' in %s marked untranslatable but exists"
-                                    " in locale '%s'\n", String8(name).string(),
-                                    bundle->getResourceSourceDirs()[0],
-                                    locale.string());
-                            // hasErrors = localHasErrors = true;
-                        } else {
-                            // Intentionally empty block:
-                            //
-                            // Don't add untranslatable strings to the localization table; that
-                            // way if we later see localizations of them, they'll be flagged as
-                            // having no default translation.
-                        }
-                    } else {
-                        outTable->addLocalization(name, locale);
-                    }
-
-                    if (formatted == false16) {
-                        curIsFormatted = false;
-                    }
-                }
-
-                curTag = &string16;
-                curType = string16;
-                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
-                curIsStyled = true;
-                curIsPseudolocalizable = true;
-            } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) {
-                curTag = &drawable16;
-                curType = drawable16;
-                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
-            } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) {
-                curTag = &color16;
-                curType = color16;
-                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
-            } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) {
-                curTag = &bool16;
-                curType = bool16;
-                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN;
-            } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) {
-                curTag = &integer16;
-                curType = integer16;
-                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
-            } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) {
-                curTag = &dimen16;
-                curType = dimen16;
-                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION;
-            } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) {
-                curTag = &fraction16;
-                curType = fraction16;
-                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION;
-            } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) {
-                curTag = &bag16;
-                curIsBag = true;
-                ssize_t attri = block.indexOfAttribute(NULL, "type");
-                if (attri >= 0) {
-                    curType = String16(block.getAttributeStringValue(attri, &len));
-                } else {
-                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                            "A 'type' attribute is required for <bag>\n");
-                    hasErrors = localHasErrors = true;
-                }
-            } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) {
-                curTag = &style16;
-                curType = style16;
-                curIsBag = true;
-            } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) {
-                curTag = &plurals16;
-                curType = plurals16;
-                curIsBag = true;
-            } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) {
-                curTag = &array16;
-                curType = array16;
-                curIsBag = true;
-                curIsBagReplaceOnOverwrite = true;
-                ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
-                if (formatIdx >= 0) {
-                    String16 formatStr = String16(block.getAttributeStringValue(
-                            formatIdx, &len));
-                    curFormat = parse_flags(formatStr.string(), formatStr.size(),
-                                            gFormatFlags);
-                    if (curFormat == 0) {
-                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                                "Tag <array> 'format' attribute value \"%s\" not valid\n",
-                                String8(formatStr).string());
-                        hasErrors = localHasErrors = true;
-                    }
-                }
-            } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) {
-                // Check whether these strings need valid formats.
-                // (simplified form of what string16 does above)
-                size_t n = block.getAttributeCount();
-                for (size_t i = 0; i < n; i++) {
-                    size_t length;
-                    const uint16_t* attr = block.getAttributeName(i, &length);
-                    if (strcmp16(attr, translatable16.string()) == 0
-                            || strcmp16(attr, formatted16.string()) == 0) {
-                        const uint16_t* value = block.getAttributeStringValue(i, &length);
-                        if (strcmp16(value, false16.string()) == 0) {
-                            curIsFormatted = false;
-                            break;
-                        }
-                    }
-                }
-
-                curTag = &string_array16;
-                curType = array16;
-                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
-                curIsBag = true;
-                curIsBagReplaceOnOverwrite = true;
-                curIsPseudolocalizable = true;
-            } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) {
-                curTag = &integer_array16;
-                curType = array16;
-                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
-                curIsBag = true;
-                curIsBagReplaceOnOverwrite = true;
-            } else {
-                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                        "Found tag %s where item is expected\n",
-                        String8(block.getElementName(&len)).string());
-                return UNKNOWN_ERROR;
-            }
-
-            String16 ident;
-            ssize_t identIdx = block.indexOfAttribute(NULL, "name");
-            if (identIdx >= 0) {
-                ident = String16(block.getAttributeStringValue(identIdx, &len));
-            } else {
-                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                        "A 'name' attribute is required for <%s>\n",
-                        String8(*curTag).string());
-                hasErrors = localHasErrors = true;
-            }
-
-            String16 product;
-            identIdx = block.indexOfAttribute(NULL, "product");
-            if (identIdx >= 0) {
-                product = String16(block.getAttributeStringValue(identIdx, &len));
-            }
-
-            String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr);
-            
-            if (curIsBag) {
-                // Figure out the parent of this bag...
-                String16 parentIdent;
-                ssize_t parentIdentIdx = block.indexOfAttribute(NULL, "parent");
-                if (parentIdentIdx >= 0) {
-                    parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len));
-                } else {
-                    ssize_t sep = ident.findLast('.');
-                    if (sep >= 0) {
-                        parentIdent.setTo(ident, sep);
-                    }
-                }
-
-                if (!localHasErrors) {
-                    err = outTable->startBag(SourcePos(in->getPrintableSource(),
-                            block.getLineNumber()), myPackage, curType, ident,
-                            parentIdent, &curParams,
-                            overwrite, curIsBagReplaceOnOverwrite);
-                    if (err != NO_ERROR) {
-                        hasErrors = localHasErrors = true;
-                    }
-                }
-                
-                ssize_t elmIndex = 0;
-                char elmIndexStr[14];
-                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
-                        && code != ResXMLTree::BAD_DOCUMENT) {
-
-                    if (code == ResXMLTree::START_TAG) {
-                        if (strcmp16(block.getElementName(&len), item16.string()) != 0) {
-                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                                    "Tag <%s> can not appear inside <%s>, only <item>\n",
-                                    String8(block.getElementName(&len)).string(),
-                                    String8(*curTag).string());
-                            return UNKNOWN_ERROR;
-                        }
-
-                        String16 itemIdent;
-                        if (curType == array16) {
-                            sprintf(elmIndexStr, "^index_%d", (int)elmIndex++);
-                            itemIdent = String16(elmIndexStr);
-                        } else if (curType == plurals16) {
-                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "quantity");
-                            if (itemIdentIdx >= 0) {
-                                String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len));
-                                if (quantity16 == other16) {
-                                    itemIdent = quantityOther16;
-                                }
-                                else if (quantity16 == zero16) {
-                                    itemIdent = quantityZero16;
-                                }
-                                else if (quantity16 == one16) {
-                                    itemIdent = quantityOne16;
-                                }
-                                else if (quantity16 == two16) {
-                                    itemIdent = quantityTwo16;
-                                }
-                                else if (quantity16 == few16) {
-                                    itemIdent = quantityFew16;
-                                }
-                                else if (quantity16 == many16) {
-                                    itemIdent = quantityMany16;
-                                }
-                                else {
-                                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                                            "Illegal 'quantity' attribute is <item> inside <plurals>\n");
-                                    hasErrors = localHasErrors = true;
-                                }
-                            } else {
-                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                                        "A 'quantity' attribute is required for <item> inside <plurals>\n");
-                                hasErrors = localHasErrors = true;
-                            }
-                        } else {
-                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name");
-                            if (itemIdentIdx >= 0) {
-                                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));
-                            } else {
-                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                                        "A 'name' attribute is required for <item>\n");
-                                hasErrors = localHasErrors = true;
-                            }
-                        }
-
-                        ResXMLParser::ResXMLPosition parserPosition;
-                        block.getPosition(&parserPosition);
-
-                        err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,
-                                ident, parentIdent, itemIdent, curFormat, curIsFormatted,
-                                product, false, overwrite, outTable);
-                        if (err == NO_ERROR) {
-                            if (curIsPseudolocalizable && localeIsDefined(curParams)
-                                    && bundle->getPseudolocalize()) {
-                                // pseudolocalize here
-#if 1
-                                block.setPosition(parserPosition);
-                                err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,
-                                        curType, ident, parentIdent, itemIdent, curFormat,
-                                        curIsFormatted, product, true, overwrite, outTable);
-#endif
-                            }
-                        } 
-                        if (err != NO_ERROR) {
-                            hasErrors = localHasErrors = true;
-                        }
-                    } else if (code == ResXMLTree::END_TAG) {
-                        if (strcmp16(block.getElementName(&len), curTag->string()) != 0) {
-                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                                    "Found tag </%s> where </%s> is expected\n",
-                                    String8(block.getElementName(&len)).string(),
-                                    String8(*curTag).string());
-                            return UNKNOWN_ERROR;
-                        }
-                        break;
-                    }
-                }
-            } else {
-                ResXMLParser::ResXMLPosition parserPosition;
-                block.getPosition(&parserPosition);
-
-                err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,
-                        *curTag, curIsStyled, curFormat, curIsFormatted,
-                        product, false, overwrite, &skippedResourceNames, outTable);
-
-                if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?
-                    hasErrors = localHasErrors = true;
-                }
-                else if (err == NO_ERROR) {
-                    if (curIsPseudolocalizable && localeIsDefined(curParams)
-                            && bundle->getPseudolocalize()) {
-                        // pseudolocalize here
-                        block.setPosition(parserPosition);
-                        err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,
-                                ident, *curTag, curIsStyled, curFormat,
-                                curIsFormatted, product,
-                                true, overwrite, &skippedResourceNames, outTable);
-                        if (err != NO_ERROR) {
-                            hasErrors = localHasErrors = true;
-                        }
-                    }
-                }
-            }
-
-#if 0
-            if (comment.size() > 0) {
-                printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(),
-                       String8(curType).string(), String8(ident).string(),
-                       String8(comment).string());
-            }
-#endif
-            if (!localHasErrors) {
-                outTable->appendComment(myPackage, curType, ident, comment, false);
-            }
-        }
-        else if (code == ResXMLTree::END_TAG) {
-            if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
-                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                        "Unexpected end tag %s\n", String8(block.getElementName(&len)).string());
-                return UNKNOWN_ERROR;
-            }
-        }
-        else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) {
-        }
-        else if (code == ResXMLTree::TEXT) {
-            if (isWhitespace(block.getText(&len))) {
-                continue;
-            }
-            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
-                    "Found text \"%s\" where item tag is expected\n",
-                    String8(block.getText(&len)).string());
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    // For every resource defined, there must be exist one variant with a product attribute
-    // set to 'default' (or no product attribute at all).
-    // We check to see that for every resource that was ignored because of a mismatched
-    // product attribute, some product variant of that resource was processed.
-    for (size_t i = 0; i < skippedResourceNames.size(); i++) {
-        if (skippedResourceNames[i]) {
-            const type_ident_pair_t& p = skippedResourceNames.keyAt(i);
-            if (!outTable->hasBagOrEntry(myPackage, p.type, p.ident)) {
-                const char* bundleProduct =
-                        (bundle->getProduct() == NULL) ? "" : bundle->getProduct();
-                fprintf(stderr, "In resource file %s: %s\n",
-                        in->getPrintableSource().string(),
-                        curParams.toString().string());
-
-                fprintf(stderr, "\t%s '%s' does not match product %s.\n"
-                        "\tYou may have forgotten to include a 'default' product variant"
-                        " of the resource.\n",
-                        String8(p.type).string(), String8(p.ident).string(),
-                        bundleProduct[0] == 0 ? "default" : bundleProduct);
-                return UNKNOWN_ERROR;
-            }
-        }
-    }
-
-    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
-}
-
-ResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage)
-    : mAssetsPackage(assetsPackage), mNextPackageId(1), mHaveAppPackage(false),
-      mIsAppPackage(!bundle->getExtending()),
-      mNumLocal(0),
-      mBundle(bundle)
-{
-}
-
-status_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets)
-{
-    status_t err = assets->buildIncludedResources(bundle);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    // For future reference to included resources.
-    mAssets = assets;
-
-    const ResTable& incl = assets->getIncludedResources();
-
-    // Retrieve all the packages.
-    const size_t N = incl.getBasePackageCount();
-    for (size_t phase=0; phase<2; phase++) {
-        for (size_t i=0; i<N; i++) {
-            String16 name(incl.getBasePackageName(i));
-            uint32_t id = incl.getBasePackageId(i);
-            // First time through: only add base packages (id
-            // is not 0); second time through add the other
-            // packages.
-            if (phase != 0) {
-                if (id != 0) {
-                    // Skip base packages -- already one.
-                    id = 0;
-                } else {
-                    // Assign a dynamic id.
-                    id = mNextPackageId;
-                }
-            } else if (id != 0) {
-                if (id == 127) {
-                    if (mHaveAppPackage) {
-                        fprintf(stderr, "Included resources have two application packages!\n");
-                        return UNKNOWN_ERROR;
-                    }
-                    mHaveAppPackage = true;
-                }
-                if (mNextPackageId > id) {
-                    fprintf(stderr, "Included base package ID %d already in use!\n", id);
-                    return UNKNOWN_ERROR;
-                }
-            }
-            if (id != 0) {
-                NOISY(printf("Including package %s with ID=%d\n",
-                             String8(name).string(), id));
-                sp<Package> p = new Package(name, id);
-                mPackages.add(name, p);
-                mOrderedPackages.add(p);
-
-                if (id >= mNextPackageId) {
-                    mNextPackageId = id+1;
-                }
-            }
-        }
-    }
-
-    // Every resource table always has one first entry, the bag attributes.
-    const SourcePos unknown(String8("????"), 0);
-    sp<Type> attr = getType(mAssetsPackage, String16("attr"), unknown);
-
-    return NO_ERROR;
-}
-
-status_t ResourceTable::addPublic(const SourcePos& sourcePos,
-                                  const String16& package,
-                                  const String16& type,
-                                  const String16& name,
-                                  const uint32_t ident)
-{
-    uint32_t rid = mAssets->getIncludedResources()
-        .identifierForName(name.string(), name.size(),
-                           type.string(), type.size(),
-                           package.string(), package.size());
-    if (rid != 0) {
-        sourcePos.error("Error declaring public resource %s/%s for included package %s\n",
-                String8(type).string(), String8(name).string(),
-                String8(package).string());
-        return UNKNOWN_ERROR;
-    }
-
-    sp<Type> t = getType(package, type, sourcePos);
-    if (t == NULL) {
-        return UNKNOWN_ERROR;
-    }
-    return t->addPublic(sourcePos, name, ident);
-}
-
-status_t ResourceTable::addEntry(const SourcePos& sourcePos,
-                                 const String16& package,
-                                 const String16& type,
-                                 const String16& name,
-                                 const String16& value,
-                                 const Vector<StringPool::entry_style_span>* style,
-                                 const ResTable_config* params,
-                                 const bool doSetIndex,
-                                 const int32_t format,
-                                 const bool overwrite)
-{
-    // Check for adding entries in other packages...  for now we do
-    // nothing.  We need to do the right thing here to support skinning.
-    uint32_t rid = mAssets->getIncludedResources()
-        .identifierForName(name.string(), name.size(),
-                           type.string(), type.size(),
-                           package.string(), package.size());
-    if (rid != 0) {
-        return NO_ERROR;
-    }
-    
-#if 0
-    if (name == String16("left")) {
-        printf("Adding entry left: file=%s, line=%d, type=%s, value=%s\n",
-               sourcePos.file.string(), sourcePos.line, String8(type).string(),
-               String8(value).string());
-    }
-#endif
-
-    sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite,
-                           params, doSetIndex);
-    if (e == NULL) {
-        return UNKNOWN_ERROR;
-    }
-    status_t err = e->setItem(sourcePos, value, style, format, overwrite);
-    if (err == NO_ERROR) {
-        mNumLocal++;
-    }
-    return err;
-}
-
-status_t ResourceTable::startBag(const SourcePos& sourcePos,
-                                 const String16& package,
-                                 const String16& type,
-                                 const String16& name,
-                                 const String16& bagParent,
-                                 const ResTable_config* params,
-                                 bool overlay,
-                                 bool replace, bool isId)
-{
-    status_t result = NO_ERROR;
-
-    // Check for adding entries in other packages...  for now we do
-    // nothing.  We need to do the right thing here to support skinning.
-    uint32_t rid = mAssets->getIncludedResources()
-    .identifierForName(name.string(), name.size(),
-                       type.string(), type.size(),
-                       package.string(), package.size());
-    if (rid != 0) {
-        return NO_ERROR;
-    }
-    
-#if 0
-    if (name == String16("left")) {
-        printf("Adding bag left: file=%s, line=%d, type=%s\n",
-               sourcePos.file.striing(), sourcePos.line, String8(type).string());
-    }
-#endif
-    if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) {
-        bool canAdd = false;
-        sp<Package> p = mPackages.valueFor(package);
-        if (p != NULL) {
-            sp<Type> t = p->getTypes().valueFor(type);
-            if (t != NULL) {
-                if (t->getCanAddEntries().indexOf(name) >= 0) {
-                    canAdd = true;
-                }
-            }
-        }
-        if (!canAdd) {
-            sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n",
-                            String8(name).string());
-            return UNKNOWN_ERROR;
-        }
-    }
-    sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params);
-    if (e == NULL) {
-        return UNKNOWN_ERROR;
-    }
-    
-    // If a parent is explicitly specified, set it.
-    if (bagParent.size() > 0) {
-        e->setParent(bagParent);
-    }
-
-    if ((result = e->makeItABag(sourcePos)) != NO_ERROR) {
-        return result;
-    }
-
-    if (overlay && replace) { 
-        return e->emptyBag(sourcePos);
-    }
-    return result;
-}
-
-status_t ResourceTable::addBag(const SourcePos& sourcePos,
-                               const String16& package,
-                               const String16& type,
-                               const String16& name,
-                               const String16& bagParent,
-                               const String16& bagKey,
-                               const String16& value,
-                               const Vector<StringPool::entry_style_span>* style,
-                               const ResTable_config* params,
-                               bool replace, bool isId, const int32_t format)
-{
-    // Check for adding entries in other packages...  for now we do
-    // nothing.  We need to do the right thing here to support skinning.
-    uint32_t rid = mAssets->getIncludedResources()
-        .identifierForName(name.string(), name.size(),
-                           type.string(), type.size(),
-                           package.string(), package.size());
-    if (rid != 0) {
-        return NO_ERROR;
-    }
-
-#if 0
-    if (name == String16("left")) {
-        printf("Adding bag left: file=%s, line=%d, type=%s\n",
-               sourcePos.file.striing(), sourcePos.line, String8(type).string());
-    }
-#endif
-    sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params);
-    if (e == NULL) {
-        return UNKNOWN_ERROR;
-    }
-
-    // If a parent is explicitly specified, set it.
-    if (bagParent.size() > 0) {
-        e->setParent(bagParent);
-    }
-
-    const bool first = e->getBag().indexOfKey(bagKey) < 0;
-    status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format);
-    if (err == NO_ERROR && first) {
-        mNumLocal++;
-    }
-    return err;
-}
-
-bool ResourceTable::hasBagOrEntry(const String16& package,
-                                  const String16& type,
-                                  const String16& name) const
-{
-    // First look for this in the included resources...
-    uint32_t rid = mAssets->getIncludedResources()
-        .identifierForName(name.string(), name.size(),
-                           type.string(), type.size(),
-                           package.string(), package.size());
-    if (rid != 0) {
-        return true;
-    }
-
-    sp<Package> p = mPackages.valueFor(package);
-    if (p != NULL) {
-        sp<Type> t = p->getTypes().valueFor(type);
-        if (t != NULL) {
-            sp<ConfigList> c =  t->getConfigs().valueFor(name);
-            if (c != NULL) return true;
-        }
-    }
-
-    return false;
-}
-
-bool ResourceTable::hasBagOrEntry(const String16& package,
-                                  const String16& type,
-                                  const String16& name,
-                                  const ResTable_config& config) const
-{
-    // First look for this in the included resources...
-    uint32_t rid = mAssets->getIncludedResources()
-        .identifierForName(name.string(), name.size(),
-                           type.string(), type.size(),
-                           package.string(), package.size());
-    if (rid != 0) {
-        return true;
-    }
-
-    sp<Package> p = mPackages.valueFor(package);
-    if (p != NULL) {
-        sp<Type> t = p->getTypes().valueFor(type);
-        if (t != NULL) {
-            sp<ConfigList> c =  t->getConfigs().valueFor(name);
-            if (c != NULL) {
-                sp<Entry> e = c->getEntries().valueFor(config);
-                if (e != NULL) {
-                    return true;
-                }
-            }
-        }
-    }
-
-    return false;
-}
-
-bool ResourceTable::hasBagOrEntry(const String16& ref,
-                                  const String16* defType,
-                                  const String16* defPackage)
-{
-    String16 package, type, name;
-    if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name,
-                defType, defPackage ? defPackage:&mAssetsPackage, NULL)) {
-        return false;
-    }
-    return hasBagOrEntry(package, type, name);
-}
-
-bool ResourceTable::appendComment(const String16& package,
-                                  const String16& type,
-                                  const String16& name,
-                                  const String16& comment,
-                                  bool onlyIfEmpty)
-{
-    if (comment.size() <= 0) {
-        return true;
-    }
-
-    sp<Package> p = mPackages.valueFor(package);
-    if (p != NULL) {
-        sp<Type> t = p->getTypes().valueFor(type);
-        if (t != NULL) {
-            sp<ConfigList> c =  t->getConfigs().valueFor(name);
-            if (c != NULL) {
-                c->appendComment(comment, onlyIfEmpty);
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-bool ResourceTable::appendTypeComment(const String16& package,
-                                      const String16& type,
-                                      const String16& name,
-                                      const String16& comment)
-{
-    if (comment.size() <= 0) {
-        return true;
-    }
-    
-    sp<Package> p = mPackages.valueFor(package);
-    if (p != NULL) {
-        sp<Type> t = p->getTypes().valueFor(type);
-        if (t != NULL) {
-            sp<ConfigList> c =  t->getConfigs().valueFor(name);
-            if (c != NULL) {
-                c->appendTypeComment(comment);
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-void ResourceTable::canAddEntry(const SourcePos& pos,
-        const String16& package, const String16& type, const String16& name)
-{
-    sp<Type> t = getType(package, type, pos);
-    if (t != NULL) {
-        t->canAddEntry(name);
-    }
-}
-
-size_t ResourceTable::size() const {
-    return mPackages.size();
-}
-
-size_t ResourceTable::numLocalResources() const {
-    return mNumLocal;
-}
-
-bool ResourceTable::hasResources() const {
-    return mNumLocal > 0;
-}
-
-sp<AaptFile> ResourceTable::flatten(Bundle* bundle)
-{
-    sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());
-    status_t err = flatten(bundle, data);
-    return err == NO_ERROR ? data : NULL;
-}
-
-inline uint32_t ResourceTable::getResId(const sp<Package>& p,
-                                        const sp<Type>& t,
-                                        uint32_t nameId)
-{
-    return makeResId(p->getAssignedId(), t->getIndex(), nameId);
-}
-
-uint32_t ResourceTable::getResId(const String16& package,
-                                 const String16& type,
-                                 const String16& name,
-                                 bool onlyPublic) const
-{
-    uint32_t id = ResourceIdCache::lookup(package, type, name, onlyPublic);
-    if (id != 0) return id;     // cache hit
-
-    sp<Package> p = mPackages.valueFor(package);
-    if (p == NULL) return 0;
-
-    // First look for this in the included resources...
-    uint32_t specFlags = 0;
-    uint32_t rid = mAssets->getIncludedResources()
-        .identifierForName(name.string(), name.size(),
-                           type.string(), type.size(),
-                           package.string(), package.size(),
-                           &specFlags);
-    if (rid != 0) {
-        if (onlyPublic) {
-            if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) {
-                return 0;
-            }
-        }
-        
-        if (Res_INTERNALID(rid)) {
-            return ResourceIdCache::store(package, type, name, onlyPublic, rid);
-        }
-        return ResourceIdCache::store(package, type, name, onlyPublic,
-                Res_MAKEID(p->getAssignedId()-1, Res_GETTYPE(rid), Res_GETENTRY(rid)));
-    }
-
-    sp<Type> t = p->getTypes().valueFor(type);
-    if (t == NULL) return 0;
-    sp<ConfigList> c =  t->getConfigs().valueFor(name);
-    if (c == NULL) return 0;
-    int32_t ei = c->getEntryIndex();
-    if (ei < 0) return 0;
-
-    return ResourceIdCache::store(package, type, name, onlyPublic,
-            getResId(p, t, ei));
-}
-
-uint32_t ResourceTable::getResId(const String16& ref,
-                                 const String16* defType,
-                                 const String16* defPackage,
-                                 const char** outErrorMsg,
-                                 bool onlyPublic) const
-{
-    String16 package, type, name;
-    bool refOnlyPublic = true;
-    if (!ResTable::expandResourceRef(
-        ref.string(), ref.size(), &package, &type, &name,
-        defType, defPackage ? defPackage:&mAssetsPackage,
-        outErrorMsg, &refOnlyPublic)) {
-        NOISY(printf("Expanding resource: ref=%s\n",
-                     String8(ref).string()));
-        NOISY(printf("Expanding resource: defType=%s\n",
-                     defType ? String8(*defType).string() : "NULL"));
-        NOISY(printf("Expanding resource: defPackage=%s\n",
-                     defPackage ? String8(*defPackage).string() : "NULL"));
-        NOISY(printf("Expanding resource: ref=%s\n", String8(ref).string()));
-        NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n",
-                     String8(package).string(), String8(type).string(),
-                     String8(name).string()));
-        return 0;
-    }
-    uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic);
-    NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n",
-                 String8(package).string(), String8(type).string(),
-                 String8(name).string(), res));
-    if (res == 0) {
-        if (outErrorMsg)
-            *outErrorMsg = "No resource found that matches the given name";
-    }
-    return res;
-}
-
-bool ResourceTable::isValidResourceName(const String16& s)
-{
-    const char16_t* p = s.string();
-    bool first = true;
-    while (*p) {
-        if ((*p >= 'a' && *p <= 'z')
-            || (*p >= 'A' && *p <= 'Z')
-            || *p == '_'
-            || (!first && *p >= '0' && *p <= '9')) {
-            first = false;
-            p++;
-            continue;
-        }
-        return false;
-    }
-    return true;
-}
-
-bool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool,
-                                  const String16& str,
-                                  bool preserveSpaces, bool coerceType,
-                                  uint32_t attrID,
-                                  const Vector<StringPool::entry_style_span>* style,
-                                  String16* outStr, void* accessorCookie,
-                                  uint32_t attrType, const String8* configTypeName,
-                                  const ConfigDescription* config)
-{
-    String16 finalStr;
-
-    bool res = true;
-    if (style == NULL || style->size() == 0) {
-        // Text is not styled so it can be any type...  let's figure it out.
-        res = mAssets->getIncludedResources()
-            .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces,
-                            coerceType, attrID, NULL, &mAssetsPackage, this,
-                           accessorCookie, attrType);
-    } else {
-        // Styled text can only be a string, and while collecting the style
-        // information we have already processed that string!
-        outValue->size = sizeof(Res_value);
-        outValue->res0 = 0;
-        outValue->dataType = outValue->TYPE_STRING;
-        outValue->data = 0;
-        finalStr = str;
-    }
-
-    if (!res) {
-        return false;
-    }
-
-    if (outValue->dataType == outValue->TYPE_STRING) {
-        // Should do better merging styles.
-        if (pool) {
-            String8 configStr;
-            if (config != NULL) {
-                configStr = config->toString();
-            } else {
-                configStr = "(null)";
-            }
-            NOISY(printf("Adding to pool string style #%d config %s: %s\n",
-                    style != NULL ? style->size() : 0,
-                    configStr.string(), String8(finalStr).string()));
-            if (style != NULL && style->size() > 0) {
-                outValue->data = pool->add(finalStr, *style, configTypeName, config);
-            } else {
-                outValue->data = pool->add(finalStr, true, configTypeName, config);
-            }
-        } else {
-            // Caller will fill this in later.
-            outValue->data = 0;
-        }
-    
-        if (outStr) {
-            *outStr = finalStr;
-        }
-
-    }
-
-    return true;
-}
-
-uint32_t ResourceTable::getCustomResource(
-    const String16& package, const String16& type, const String16& name) const
-{
-    //printf("getCustomResource: %s %s %s\n", String8(package).string(),
-    //       String8(type).string(), String8(name).string());
-    sp<Package> p = mPackages.valueFor(package);
-    if (p == NULL) return 0;
-    sp<Type> t = p->getTypes().valueFor(type);
-    if (t == NULL) return 0;
-    sp<ConfigList> c =  t->getConfigs().valueFor(name);
-    if (c == NULL) return 0;
-    int32_t ei = c->getEntryIndex();
-    if (ei < 0) return 0;
-    return getResId(p, t, ei);
-}
-
-uint32_t ResourceTable::getCustomResourceWithCreation(
-        const String16& package, const String16& type, const String16& name,
-        const bool createIfNotFound)
-{
-    uint32_t resId = getCustomResource(package, type, name);
-    if (resId != 0 || !createIfNotFound) {
-        return resId;
-    }
-    String16 value("false");
-
-    status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true);
-    if (status == NO_ERROR) {
-        resId = getResId(package, type, name);
-        return resId;
-    }
-    return 0;
-}
-
-uint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const
-{
-    return origPackage;
-}
-
-bool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType)
-{
-    //printf("getAttributeType #%08x\n", attrID);
-    Res_value value;
-    if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) {
-        //printf("getAttributeType #%08x (%s): #%08x\n", attrID,
-        //       String8(getEntry(attrID)->getName()).string(), value.data);
-        *outType = value.data;
-        return true;
-    }
-    return false;
-}
-
-bool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin)
-{
-    //printf("getAttributeMin #%08x\n", attrID);
-    Res_value value;
-    if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) {
-        *outMin = value.data;
-        return true;
-    }
-    return false;
-}
-
-bool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax)
-{
-    //printf("getAttributeMax #%08x\n", attrID);
-    Res_value value;
-    if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) {
-        *outMax = value.data;
-        return true;
-    }
-    return false;
-}
-
-uint32_t ResourceTable::getAttributeL10N(uint32_t attrID)
-{
-    //printf("getAttributeL10N #%08x\n", attrID);
-    Res_value value;
-    if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) {
-        return value.data;
-    }
-    return ResTable_map::L10N_NOT_REQUIRED;
-}
-
-bool ResourceTable::getLocalizationSetting()
-{
-    return mBundle->getRequireLocalization();
-}
-
-void ResourceTable::reportError(void* accessorCookie, const char* fmt, ...)
-{
-    if (accessorCookie != NULL && fmt != NULL) {
-        AccessorCookie* ac = (AccessorCookie*)accessorCookie;
-        int retval=0;
-        char buf[1024];
-        va_list ap;
-        va_start(ap, fmt);
-        retval = vsnprintf(buf, sizeof(buf), fmt, ap);
-        va_end(ap);
-        ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n",
-                            buf, ac->attr.string(), ac->value.string());
-    }
-}
-
-bool ResourceTable::getAttributeKeys(
-    uint32_t attrID, Vector<String16>* outKeys)
-{
-    sp<const Entry> e = getEntry(attrID);
-    if (e != NULL) {
-        const size_t N = e->getBag().size();
-        for (size_t i=0; i<N; i++) {
-            const String16& key = e->getBag().keyAt(i);
-            if (key.size() > 0 && key.string()[0] != '^') {
-                outKeys->add(key);
-            }
-        }
-        return true;
-    }
-    return false;
-}
-
-bool ResourceTable::getAttributeEnum(
-    uint32_t attrID, const char16_t* name, size_t nameLen,
-    Res_value* outValue)
-{
-    //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string());
-    String16 nameStr(name, nameLen);
-    sp<const Entry> e = getEntry(attrID);
-    if (e != NULL) {
-        const size_t N = e->getBag().size();
-        for (size_t i=0; i<N; i++) {
-            //printf("Comparing %s to %s\n", String8(name, nameLen).string(),
-            //       String8(e->getBag().keyAt(i)).string());
-            if (e->getBag().keyAt(i) == nameStr) {
-                return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue);
-            }
-        }
-    }
-    return false;
-}
-
-bool ResourceTable::getAttributeFlags(
-    uint32_t attrID, const char16_t* name, size_t nameLen,
-    Res_value* outValue)
-{
-    outValue->dataType = Res_value::TYPE_INT_HEX;
-    outValue->data = 0;
-
-    //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string());
-    String16 nameStr(name, nameLen);
-    sp<const Entry> e = getEntry(attrID);
-    if (e != NULL) {
-        const size_t N = e->getBag().size();
-
-        const char16_t* end = name + nameLen;
-        const char16_t* pos = name;
-        while (pos < end) {
-            const char16_t* start = pos;
-            while (pos < end && *pos != '|') {
-                pos++;
-            }
-
-            String16 nameStr(start, pos-start);
-            size_t i;
-            for (i=0; i<N; i++) {
-                //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(),
-                //       String8(e->getBag().keyAt(i)).string());
-                if (e->getBag().keyAt(i) == nameStr) {
-                    Res_value val;
-                    bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val);
-                    if (!got) {
-                        return false;
-                    }
-                    //printf("Got value: 0x%08x\n", val.data);
-                    outValue->data |= val.data;
-                    break;
-                }
-            }
-
-            if (i >= N) {
-                // Didn't find this flag identifier.
-                return false;
-            }
-            pos++;
-        }
-
-        return true;
-    }
-    return false;
-}
-
-status_t ResourceTable::assignResourceIds()
-{
-    const size_t N = mOrderedPackages.size();
-    size_t pi;
-    status_t firstError = NO_ERROR;
-
-    // First generate all bag attributes and assign indices.
-    for (pi=0; pi<N; pi++) {
-        sp<Package> p = mOrderedPackages.itemAt(pi);
-        if (p == NULL || p->getTypes().size() == 0) {
-            // Empty, skip!
-            continue;
-        }
-
-        status_t err = p->applyPublicTypeOrder();
-        if (err != NO_ERROR && firstError == NO_ERROR) {
-            firstError = err;
-        }
-
-        // Generate attributes...
-        const size_t N = p->getOrderedTypes().size();
-        size_t ti;
-        for (ti=0; ti<N; ti++) {
-            sp<Type> t = p->getOrderedTypes().itemAt(ti);
-            if (t == NULL) {
-                continue;
-            }
-            const size_t N = t->getOrderedConfigs().size();
-            for (size_t ci=0; ci<N; ci++) {
-                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
-                if (c == NULL) {
-                    continue;
-                }
-                const size_t N = c->getEntries().size();
-                for (size_t ei=0; ei<N; ei++) {
-                    sp<Entry> e = c->getEntries().valueAt(ei);
-                    if (e == NULL) {
-                        continue;
-                    }
-                    status_t err = e->generateAttributes(this, p->getName());
-                    if (err != NO_ERROR && firstError == NO_ERROR) {
-                        firstError = err;
-                    }
-                }
-            }
-        }
-
-        const SourcePos unknown(String8("????"), 0);
-        sp<Type> attr = p->getType(String16("attr"), unknown);
-
-        // Assign indices...
-        for (ti=0; ti<N; ti++) {
-            sp<Type> t = p->getOrderedTypes().itemAt(ti);
-            if (t == NULL) {
-                continue;
-            }
-            err = t->applyPublicEntryOrder();
-            if (err != NO_ERROR && firstError == NO_ERROR) {
-                firstError = err;
-            }
-
-            const size_t N = t->getOrderedConfigs().size();
-            t->setIndex(ti+1);
-
-            LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t,
-                                "First type is not attr!");
-
-            for (size_t ei=0; ei<N; ei++) {
-                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei);
-                if (c == NULL) {
-                    continue;
-                }
-                c->setEntryIndex(ei);
-            }
-        }
-
-        // Assign resource IDs to keys in bags...
-        for (ti=0; ti<N; ti++) {
-            sp<Type> t = p->getOrderedTypes().itemAt(ti);
-            if (t == NULL) {
-                continue;
-            }
-            const size_t N = t->getOrderedConfigs().size();
-            for (size_t ci=0; ci<N; ci++) {
-                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
-                //printf("Ordered config #%d: %p\n", ci, c.get());
-                const size_t N = c->getEntries().size();
-                for (size_t ei=0; ei<N; ei++) {
-                    sp<Entry> e = c->getEntries().valueAt(ei);
-                    if (e == NULL) {
-                        continue;
-                    }
-                    status_t err = e->assignResourceIds(this, p->getName());
-                    if (err != NO_ERROR && firstError == NO_ERROR) {
-                        firstError = err;
-                    }
-                }
-            }
-        }
-    }
-    return firstError;
-}
-
-status_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) {
-    const size_t N = mOrderedPackages.size();
-    size_t pi;
-
-    for (pi=0; pi<N; pi++) {
-        sp<Package> p = mOrderedPackages.itemAt(pi);
-        if (p->getTypes().size() == 0) {
-            // Empty, skip!
-            continue;
-        }
-
-        const size_t N = p->getOrderedTypes().size();
-        size_t ti;
-
-        for (ti=0; ti<N; ti++) {
-            sp<Type> t = p->getOrderedTypes().itemAt(ti);
-            if (t == NULL) {
-                continue;
-            }
-            const size_t N = t->getOrderedConfigs().size();
-            sp<AaptSymbols> typeSymbols;
-            typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos());
-            for (size_t ci=0; ci<N; ci++) {
-                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
-                if (c == NULL) {
-                    continue;
-                }
-                uint32_t rid = getResId(p, t, ci);
-                if (rid == 0) {
-                    return UNKNOWN_ERROR;
-                }
-                if (Res_GETPACKAGE(rid) == (size_t)(p->getAssignedId()-1)) {
-                    typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos());
-                    
-                    String16 comment(c->getComment());
-                    typeSymbols->appendComment(String8(c->getName()), comment, c->getPos());
-                    //printf("Type symbol [%08x] %s comment: %s\n", rid,
-                    //        String8(c->getName()).string(), String8(comment).string());
-                    comment = c->getTypeComment();
-                    typeSymbols->appendTypeComment(String8(c->getName()), comment);
-                } else {
-#if 0
-                    printf("**** NO MATCH: 0x%08x vs 0x%08x\n",
-                           Res_GETPACKAGE(rid), p->getAssignedId());
-#endif
-                }
-            }
-        }
-    }
-    return NO_ERROR;
-}
-
-
-void
-ResourceTable::addLocalization(const String16& name, const String8& locale)
-{
-    mLocalizations[name].insert(locale);
-}
-
-
-/*!
- * Flag various sorts of localization problems.  '+' indicates checks already implemented;
- * '-' indicates checks that will be implemented in the future.
- *
- * + A localized string for which no default-locale version exists => warning
- * + A string for which no version in an explicitly-requested locale exists => warning
- * + A localized translation of an translateable="false" string => warning
- * - A localized string not provided in every locale used by the table
- */
-status_t
-ResourceTable::validateLocalizations(void)
-{
-    status_t err = NO_ERROR;
-    const String8 defaultLocale;
-
-    // For all strings...
-    for (map<String16, set<String8> >::iterator nameIter = mLocalizations.begin();
-         nameIter != mLocalizations.end();
-         nameIter++) {
-        const set<String8>& configSet = nameIter->second;   // naming convenience
-
-        // Look for strings with no default localization
-        if (configSet.count(defaultLocale) == 0) {
-            fprintf(stdout, "aapt: warning: string '%s' has no default translation in %s; found:",
-                    String8(nameIter->first).string(), mBundle->getResourceSourceDirs()[0]);
-            for (set<String8>::const_iterator locales = configSet.begin();
-                 locales != configSet.end();
-                 locales++) {
-                fprintf(stdout, " %s", (*locales).string());
-            }
-            fprintf(stdout, "\n");
-            // !!! TODO: throw an error here in some circumstances
-        }
-
-        // Check that all requested localizations are present for this string
-        if (mBundle->getConfigurations() != NULL && mBundle->getRequireLocalization()) {
-            const char* allConfigs = mBundle->getConfigurations();
-            const char* start = allConfigs;
-            const char* comma;
-            
-            do {
-                String8 config;
-                comma = strchr(start, ',');
-                if (comma != NULL) {
-                    config.setTo(start, comma - start);
-                    start = comma + 1;
-                } else {
-                    config.setTo(start);
-                }
-
-                // don't bother with the pseudolocale "zz_ZZ"
-                if (config != "zz_ZZ") {
-                    if (configSet.find(config) == configSet.end()) {
-                        // okay, no specific localization found.  it's possible that we are
-                        // requiring a specific regional localization [e.g. de_DE] but there is an
-                        // available string in the generic language localization [e.g. de];
-                        // consider that string to have fulfilled the localization requirement.
-                        String8 region(config.string(), 2);
-                        if (configSet.find(region) == configSet.end()) {
-                            if (configSet.count(defaultLocale) == 0) {
-                                fprintf(stdout, "aapt: warning: "
-                                        "**** string '%s' has no default or required localization "
-                                        "for '%s' in %s\n",
-                                        String8(nameIter->first).string(),
-                                        config.string(),
-                                        mBundle->getResourceSourceDirs()[0]);
-                            }
-                        }
-                    }
-                }
-           } while (comma != NULL);
-        }
-    }
-
-    return err;
-}
-
-status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
-{
-    ResourceFilter filter;
-    status_t err = filter.parse(bundle->getConfigurations());
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    const ConfigDescription nullConfig;
-
-    const size_t N = mOrderedPackages.size();
-    size_t pi;
-
-    const static String16 mipmap16("mipmap");
-
-    bool useUTF8 = !bundle->getUTF16StringsOption();
-
-    // Iterate through all data, collecting all values (strings,
-    // references, etc).
-    StringPool valueStrings(useUTF8);
-    Vector<sp<Entry> > allEntries;
-    for (pi=0; pi<N; pi++) {
-        sp<Package> p = mOrderedPackages.itemAt(pi);
-        if (p->getTypes().size() == 0) {
-            // Empty, skip!
-            continue;
-        }
-
-        StringPool typeStrings(useUTF8);
-        StringPool keyStrings(useUTF8);
-
-        const size_t N = p->getOrderedTypes().size();
-        for (size_t ti=0; ti<N; ti++) {
-            sp<Type> t = p->getOrderedTypes().itemAt(ti);
-            if (t == NULL) {
-                typeStrings.add(String16("<empty>"), false);
-                continue;
-            }
-            const String16 typeName(t->getName());
-            typeStrings.add(typeName, false);
-
-            // This is a hack to tweak the sorting order of the final strings,
-            // to put stuff that is generally not language-specific first.
-            String8 configTypeName(typeName);
-            if (configTypeName == "drawable" || configTypeName == "layout"
-                    || configTypeName == "color" || configTypeName == "anim"
-                    || configTypeName == "interpolator" || configTypeName == "animator"
-                    || configTypeName == "xml" || configTypeName == "menu"
-                    || configTypeName == "mipmap" || configTypeName == "raw") {
-                configTypeName = "1complex";
-            } else {
-                configTypeName = "2value";
-            }
-
-            const bool filterable = (typeName != mipmap16);
-
-            const size_t N = t->getOrderedConfigs().size();
-            for (size_t ci=0; ci<N; ci++) {
-                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
-                if (c == NULL) {
-                    continue;
-                }
-                const size_t N = c->getEntries().size();
-                for (size_t ei=0; ei<N; ei++) {
-                    ConfigDescription config = c->getEntries().keyAt(ei);
-                    if (filterable && !filter.match(config)) {
-                        continue;
-                    }
-                    sp<Entry> e = c->getEntries().valueAt(ei);
-                    if (e == NULL) {
-                        continue;
-                    }
-                    e->setNameIndex(keyStrings.add(e->getName(), true));
-
-                    // If this entry has no values for other configs,
-                    // and is the default config, then it is special.  Otherwise
-                    // we want to add it with the config info.
-                    ConfigDescription* valueConfig = NULL;
-                    if (N != 1 || config == nullConfig) {
-                        valueConfig = &config;
-                    }
-
-                    status_t err = e->prepareFlatten(&valueStrings, this,
-                            &configTypeName, &config);
-                    if (err != NO_ERROR) {
-                        return err;
-                    }
-                    allEntries.add(e);
-                }
-            }
-        }
-
-        p->setTypeStrings(typeStrings.createStringBlock());
-        p->setKeyStrings(keyStrings.createStringBlock());
-    }
-
-    if (bundle->getOutputAPKFile() != NULL) {
-        // Now we want to sort the value strings for better locality.  This will
-        // cause the positions of the strings to change, so we need to go back
-        // through out resource entries and update them accordingly.  Only need
-        // to do this if actually writing the output file.
-        valueStrings.sortByConfig();
-        for (pi=0; pi<allEntries.size(); pi++) {
-            allEntries[pi]->remapStringValue(&valueStrings);
-        }
-    }
-
-    ssize_t strAmt = 0;
-    
-    // Now build the array of package chunks.
-    Vector<sp<AaptFile> > flatPackages;
-    for (pi=0; pi<N; pi++) {
-        sp<Package> p = mOrderedPackages.itemAt(pi);
-        if (p->getTypes().size() == 0) {
-            // Empty, skip!
-            continue;
-        }
-
-        const size_t N = p->getTypeStrings().size();
-
-        const size_t baseSize = sizeof(ResTable_package);
-
-        // Start the package data.
-        sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());
-        ResTable_package* header = (ResTable_package*)data->editData(baseSize);
-        if (header == NULL) {
-            fprintf(stderr, "ERROR: out of memory creating ResTable_package\n");
-            return NO_MEMORY;
-        }
-        memset(header, 0, sizeof(*header));
-        header->header.type = htods(RES_TABLE_PACKAGE_TYPE);
-        header->header.headerSize = htods(sizeof(*header));
-        header->id = htodl(p->getAssignedId());
-        strcpy16_htod(header->name, p->getName().string());
-
-        // Write the string blocks.
-        const size_t typeStringsStart = data->getSize();
-        sp<AaptFile> strFile = p->getTypeStringsData();
-        ssize_t amt = data->writeData(strFile->getData(), strFile->getSize());
-        #if PRINT_STRING_METRICS
-        fprintf(stderr, "**** type strings: %d\n", amt);
-        #endif
-        strAmt += amt;
-        if (amt < 0) {
-            return amt;
-        }
-        const size_t keyStringsStart = data->getSize();
-        strFile = p->getKeyStringsData();
-        amt = data->writeData(strFile->getData(), strFile->getSize());
-        #if PRINT_STRING_METRICS
-        fprintf(stderr, "**** key strings: %d\n", amt);
-        #endif
-        strAmt += amt;
-        if (amt < 0) {
-            return amt;
-        }
-
-        // Build the type chunks inside of this package.
-        for (size_t ti=0; ti<N; ti++) {
-            // Retrieve them in the same order as the type string block.
-            size_t len;
-            String16 typeName(p->getTypeStrings().stringAt(ti, &len));
-            sp<Type> t = p->getTypes().valueFor(typeName);
-            LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"),
-                                "Type name %s not found",
-                                String8(typeName).string());
-
-            const bool filterable = (typeName != mipmap16);
-
-            const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;
-
-            // Until a non-NO_ENTRY value has been written for a resource,
-            // that resource is invalid; validResources[i] represents
-            // the item at t->getOrderedConfigs().itemAt(i).
-            Vector<bool> validResources;
-            validResources.insertAt(false, 0, N);
-            
-            // First write the typeSpec chunk, containing information about
-            // each resource entry in this type.
-            {
-                const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N;
-                const size_t typeSpecStart = data->getSize();
-                ResTable_typeSpec* tsHeader = (ResTable_typeSpec*)
-                    (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart);
-                if (tsHeader == NULL) {
-                    fprintf(stderr, "ERROR: out of memory creating ResTable_typeSpec\n");
-                    return NO_MEMORY;
-                }
-                memset(tsHeader, 0, sizeof(*tsHeader));
-                tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE);
-                tsHeader->header.headerSize = htods(sizeof(*tsHeader));
-                tsHeader->header.size = htodl(typeSpecSize);
-                tsHeader->id = ti+1;
-                tsHeader->entryCount = htodl(N);
-                
-                uint32_t* typeSpecFlags = (uint32_t*)
-                    (((uint8_t*)data->editData())
-                        + typeSpecStart + sizeof(ResTable_typeSpec));
-                memset(typeSpecFlags, 0, sizeof(uint32_t)*N);
-
-                for (size_t ei=0; ei<N; ei++) {
-                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);
-                    if (cl->getPublic()) {
-                        typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC);
-                    }
-                    const size_t CN = cl->getEntries().size();
-                    for (size_t ci=0; ci<CN; ci++) {
-                        if (filterable && !filter.match(cl->getEntries().keyAt(ci))) {
-                            continue;
-                        }
-                        for (size_t cj=ci+1; cj<CN; cj++) {
-                            if (filterable && !filter.match(cl->getEntries().keyAt(cj))) {
-                                continue;
-                            }
-                            typeSpecFlags[ei] |= htodl(
-                                cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj)));
-                        }
-                    }
-                }
-            }
-            
-            // We need to write one type chunk for each configuration for
-            // which we have entries in this type.
-            const size_t NC = t->getUniqueConfigs().size();
-            
-            const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N;
-            
-            for (size_t ci=0; ci<NC; ci++) {
-                ConfigDescription config = t->getUniqueConfigs().itemAt(ci);
-
-                NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
-                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
-                     "sw%ddp w%ddp h%ddp dir:%d\n",
-                      ti+1,
-                      config.mcc, config.mnc,
-                      config.language[0] ? config.language[0] : '-',
-                      config.language[1] ? config.language[1] : '-',
-                      config.country[0] ? config.country[0] : '-',
-                      config.country[1] ? config.country[1] : '-',
-                      config.orientation,
-                      config.uiMode,
-                      config.touchscreen,
-                      config.density,
-                      config.keyboard,
-                      config.inputFlags,
-                      config.navigation,
-                      config.screenWidth,
-                      config.screenHeight,
-                      config.smallestScreenWidthDp,
-                      config.screenWidthDp,
-                      config.screenHeightDp,
-                      config.layoutDirection));
-                      
-                if (filterable && !filter.match(config)) {
-                    continue;
-                }
-                
-                const size_t typeStart = data->getSize();
-
-                ResTable_type* tHeader = (ResTable_type*)
-                    (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart);
-                if (tHeader == NULL) {
-                    fprintf(stderr, "ERROR: out of memory creating ResTable_type\n");
-                    return NO_MEMORY;
-                }
-
-                memset(tHeader, 0, sizeof(*tHeader));
-                tHeader->header.type = htods(RES_TABLE_TYPE_TYPE);
-                tHeader->header.headerSize = htods(sizeof(*tHeader));
-                tHeader->id = ti+1;
-                tHeader->entryCount = htodl(N);
-                tHeader->entriesStart = htodl(typeSize);
-                tHeader->config = config;
-                NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
-                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
-                     "sw%ddp w%ddp h%ddp dir:%d\n",
-                      ti+1,
-                      tHeader->config.mcc, tHeader->config.mnc,
-                      tHeader->config.language[0] ? tHeader->config.language[0] : '-',
-                      tHeader->config.language[1] ? tHeader->config.language[1] : '-',
-                      tHeader->config.country[0] ? tHeader->config.country[0] : '-',
-                      tHeader->config.country[1] ? tHeader->config.country[1] : '-',
-                      tHeader->config.orientation,
-                      tHeader->config.uiMode,
-                      tHeader->config.touchscreen,
-                      tHeader->config.density,
-                      tHeader->config.keyboard,
-                      tHeader->config.inputFlags,
-                      tHeader->config.navigation,
-                      tHeader->config.screenWidth,
-                      tHeader->config.screenHeight,
-                      tHeader->config.smallestScreenWidthDp,
-                      tHeader->config.screenWidthDp,
-                      tHeader->config.screenHeightDp,
-                      tHeader->config.layoutDirection));
-                tHeader->config.swapHtoD();
-
-                // Build the entries inside of this type.
-                for (size_t ei=0; ei<N; ei++) {
-                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);
-                    sp<Entry> e = cl->getEntries().valueFor(config);
-
-                    // Set the offset for this entry in its type.
-                    uint32_t* index = (uint32_t*)
-                        (((uint8_t*)data->editData())
-                            + typeStart + sizeof(ResTable_type));
-                    if (e != NULL) {
-                        index[ei] = htodl(data->getSize()-typeStart-typeSize);
-
-                        // Create the entry.
-                        ssize_t amt = e->flatten(bundle, data, cl->getPublic());
-                        if (amt < 0) {
-                            return amt;
-                        }
-                        validResources.editItemAt(ei) = true;
-                    } else {
-                        index[ei] = htodl(ResTable_type::NO_ENTRY);
-                    }
-                }
-
-                // Fill in the rest of the type information.
-                tHeader = (ResTable_type*)
-                    (((uint8_t*)data->editData()) + typeStart);
-                tHeader->header.size = htodl(data->getSize()-typeStart);
-            }
-
-            for (size_t i = 0; i < N; ++i) {
-                if (!validResources[i]) {
-                    sp<ConfigList> c = t->getOrderedConfigs().itemAt(i);
-                    fprintf(stderr, "warning: no entries written for %s/%s\n",
-                            String8(typeName).string(), String8(c->getName()).string());
-                }
-            }
-        }
-
-        // Fill in the rest of the package information.
-        header = (ResTable_package*)data->editData();
-        header->header.size = htodl(data->getSize());
-        header->typeStrings = htodl(typeStringsStart);
-        header->lastPublicType = htodl(p->getTypeStrings().size());
-        header->keyStrings = htodl(keyStringsStart);
-        header->lastPublicKey = htodl(p->getKeyStrings().size());
-
-        flatPackages.add(data);
-    }
-
-    // And now write out the final chunks.
-    const size_t dataStart = dest->getSize();
-
-    {
-        // blah
-        ResTable_header header;
-        memset(&header, 0, sizeof(header));
-        header.header.type = htods(RES_TABLE_TYPE);
-        header.header.headerSize = htods(sizeof(header));
-        header.packageCount = htodl(flatPackages.size());
-        status_t err = dest->writeData(&header, sizeof(header));
-        if (err != NO_ERROR) {
-            fprintf(stderr, "ERROR: out of memory creating ResTable_header\n");
-            return err;
-        }
-    }
-    
-    ssize_t strStart = dest->getSize();
-    err = valueStrings.writeStringBlock(dest);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    ssize_t amt = (dest->getSize()-strStart);
-    strAmt += amt;
-    #if PRINT_STRING_METRICS
-    fprintf(stderr, "**** value strings: %d\n", amt);
-    fprintf(stderr, "**** total strings: %d\n", strAmt);
-    #endif
-    
-    for (pi=0; pi<flatPackages.size(); pi++) {
-        err = dest->writeData(flatPackages[pi]->getData(),
-                              flatPackages[pi]->getSize());
-        if (err != NO_ERROR) {
-            fprintf(stderr, "ERROR: out of memory creating package chunk for ResTable_header\n");
-            return err;
-        }
-    }
-
-    ResTable_header* header = (ResTable_header*)
-        (((uint8_t*)dest->getData()) + dataStart);
-    header->header.size = htodl(dest->getSize() - dataStart);
-
-    NOISY(aout << "Resource table:"
-          << HexDump(dest->getData(), dest->getSize()) << endl);
-
-    #if PRINT_STRING_METRICS
-    fprintf(stderr, "**** total resource table size: %d / %d%% strings\n",
-        dest->getSize(), (strAmt*100)/dest->getSize());
-    #endif
-    
-    return NO_ERROR;
-}
-
-void ResourceTable::writePublicDefinitions(const String16& package, FILE* fp)
-{
-    fprintf(fp,
-    "<!-- This file contains <public> resource definitions for all\n"
-    "     resources that were generated from the source data. -->\n"
-    "\n"
-    "<resources>\n");
-
-    writePublicDefinitions(package, fp, true);
-    writePublicDefinitions(package, fp, false);
-
-    fprintf(fp,
-    "\n"
-    "</resources>\n");
-}
-
-void ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub)
-{
-    bool didHeader = false;
-
-    sp<Package> pkg = mPackages.valueFor(package);
-    if (pkg != NULL) {
-        const size_t NT = pkg->getOrderedTypes().size();
-        for (size_t i=0; i<NT; i++) {
-            sp<Type> t = pkg->getOrderedTypes().itemAt(i);
-            if (t == NULL) {
-                continue;
-            }
-
-            bool didType = false;
-
-            const size_t NC = t->getOrderedConfigs().size();
-            for (size_t j=0; j<NC; j++) {
-                sp<ConfigList> c = t->getOrderedConfigs().itemAt(j);
-                if (c == NULL) {
-                    continue;
-                }
-
-                if (c->getPublic() != pub) {
-                    continue;
-                }
-
-                if (!didType) {
-                    fprintf(fp, "\n");
-                    didType = true;
-                }
-                if (!didHeader) {
-                    if (pub) {
-                        fprintf(fp,"  <!-- PUBLIC SECTION.  These resources have been declared public.\n");
-                        fprintf(fp,"       Changes to these definitions will break binary compatibility. -->\n\n");
-                    } else {
-                        fprintf(fp,"  <!-- PRIVATE SECTION.  These resources have not been declared public.\n");
-                        fprintf(fp,"       You can make them public my moving these lines into a file in res/values. -->\n\n");
-                    }
-                    didHeader = true;
-                }
-                if (!pub) {
-                    const size_t NE = c->getEntries().size();
-                    for (size_t k=0; k<NE; k++) {
-                        const SourcePos& pos = c->getEntries().valueAt(k)->getPos();
-                        if (pos.file != "") {
-                            fprintf(fp,"  <!-- Declared at %s:%d -->\n",
-                                    pos.file.string(), pos.line);
-                        }
-                    }
-                }
-                fprintf(fp, "  <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n",
-                        String8(t->getName()).string(),
-                        String8(c->getName()).string(),
-                        getResId(pkg, t, c->getEntryIndex()));
-            }
-        }
-    }
-}
-
-ResourceTable::Item::Item(const SourcePos& _sourcePos,
-                          bool _isId,
-                          const String16& _value,
-                          const Vector<StringPool::entry_style_span>* _style,
-                          int32_t _format)
-    : sourcePos(_sourcePos)
-    , isId(_isId)
-    , value(_value)
-    , format(_format)
-    , bagKeyId(0)
-    , evaluating(false)
-{
-    if (_style) {
-        style = *_style;
-    }
-}
-
-status_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos)
-{
-    if (mType == TYPE_BAG) {
-        return NO_ERROR;
-    }
-    if (mType == TYPE_UNKNOWN) {
-        mType = TYPE_BAG;
-        return NO_ERROR;
-    }
-    sourcePos.error("Resource entry %s is already defined as a single item.\n"
-                    "%s:%d: Originally defined here.\n",
-                    String8(mName).string(),
-                    mItem.sourcePos.file.string(), mItem.sourcePos.line);
-    return UNKNOWN_ERROR;
-}
-
-status_t ResourceTable::Entry::setItem(const SourcePos& sourcePos,
-                                       const String16& value,
-                                       const Vector<StringPool::entry_style_span>* style,
-                                       int32_t format,
-                                       const bool overwrite)
-{
-    Item item(sourcePos, false, value, style);
-
-    if (mType == TYPE_BAG) {
-        const Item& item(mBag.valueAt(0));
-        sourcePos.error("Resource entry %s is already defined as a bag.\n"
-                        "%s:%d: Originally defined here.\n",
-                        String8(mName).string(),
-                        item.sourcePos.file.string(), item.sourcePos.line);
-        return UNKNOWN_ERROR;
-    }
-    if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) {
-        sourcePos.error("Resource entry %s is already defined.\n"
-                        "%s:%d: Originally defined here.\n",
-                        String8(mName).string(),
-                        mItem.sourcePos.file.string(), mItem.sourcePos.line);
-        return UNKNOWN_ERROR;
-    }
-
-    mType = TYPE_ITEM;
-    mItem = item;
-    mItemFormat = format;
-    return NO_ERROR;
-}
-
-status_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos,
-                                        const String16& key, const String16& value,
-                                        const Vector<StringPool::entry_style_span>* style,
-                                        bool replace, bool isId, int32_t format)
-{
-    status_t err = makeItABag(sourcePos);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    Item item(sourcePos, isId, value, style, format);
-    
-    // XXX NOTE: there is an error if you try to have a bag with two keys,
-    // one an attr and one an id, with the same name.  Not something we
-    // currently ever have to worry about.
-    ssize_t origKey = mBag.indexOfKey(key);
-    if (origKey >= 0) {
-        if (!replace) {
-            const Item& item(mBag.valueAt(origKey));
-            sourcePos.error("Resource entry %s already has bag item %s.\n"
-                    "%s:%d: Originally defined here.\n",
-                    String8(mName).string(), String8(key).string(),
-                    item.sourcePos.file.string(), item.sourcePos.line);
-            return UNKNOWN_ERROR;
-        }
-        //printf("Replacing %s with %s\n",
-        //       String8(mBag.valueFor(key).value).string(), String8(value).string());
-        mBag.replaceValueFor(key, item);
-    }
-
-    mBag.add(key, item);
-    return NO_ERROR;
-}
-
-status_t ResourceTable::Entry::emptyBag(const SourcePos& sourcePos)
-{
-    status_t err = makeItABag(sourcePos);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    mBag.clear();
-    return NO_ERROR;
-}
-
-status_t ResourceTable::Entry::generateAttributes(ResourceTable* table,
-                                                  const String16& package)
-{
-    const String16 attr16("attr");
-    const String16 id16("id");
-    const size_t N = mBag.size();
-    for (size_t i=0; i<N; i++) {
-        const String16& key = mBag.keyAt(i);
-        const Item& it = mBag.valueAt(i);
-        if (it.isId) {
-            if (!table->hasBagOrEntry(key, &id16, &package)) {
-                String16 value("false");
-                status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package,
-                                               id16, key, value);
-                if (err != NO_ERROR) {
-                    return err;
-                }
-            }
-        } else if (!table->hasBagOrEntry(key, &attr16, &package)) {
-
-#if 1
-//             fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n",
-//                     String8(key).string());
-//             const Item& item(mBag.valueAt(i));
-//             fprintf(stderr, "Referenced from file %s line %d\n",
-//                     item.sourcePos.file.string(), item.sourcePos.line);
-//             return UNKNOWN_ERROR;
-#else
-            char numberStr[16];
-            sprintf(numberStr, "%d", ResTable_map::TYPE_ANY);
-            status_t err = table->addBag(SourcePos("<generated>", 0), package,
-                                         attr16, key, String16(""),
-                                         String16("^type"),
-                                         String16(numberStr), NULL, NULL);
-            if (err != NO_ERROR) {
-                return err;
-            }
-#endif
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t ResourceTable::Entry::assignResourceIds(ResourceTable* table,
-                                                 const String16& package)
-{
-    bool hasErrors = false;
-    
-    if (mType == TYPE_BAG) {
-        const char* errorMsg;
-        const String16 style16("style");
-        const String16 attr16("attr");
-        const String16 id16("id");
-        mParentId = 0;
-        if (mParent.size() > 0) {
-            mParentId = table->getResId(mParent, &style16, NULL, &errorMsg);
-            if (mParentId == 0) {
-                mPos.error("Error retrieving parent for item: %s '%s'.\n",
-                        errorMsg, String8(mParent).string());
-                hasErrors = true;
-            }
-        }
-        const size_t N = mBag.size();
-        for (size_t i=0; i<N; i++) {
-            const String16& key = mBag.keyAt(i);
-            Item& it = mBag.editValueAt(i);
-            it.bagKeyId = table->getResId(key,
-                    it.isId ? &id16 : &attr16, NULL, &errorMsg);
-            //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId);
-            if (it.bagKeyId == 0) {
-                it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg,
-                        String8(it.isId ? id16 : attr16).string(),
-                        String8(key).string());
-                hasErrors = true;
-            }
-        }
-    }
-    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
-}
-
-status_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table,
-        const String8* configTypeName, const ConfigDescription* config)
-{
-    if (mType == TYPE_ITEM) {
-        Item& it = mItem;
-        AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value));
-        if (!table->stringToValue(&it.parsedValue, strings,
-                                  it.value, false, true, 0,
-                                  &it.style, NULL, &ac, mItemFormat,
-                                  configTypeName, config)) {
-            return UNKNOWN_ERROR;
-        }
-    } else if (mType == TYPE_BAG) {
-        const size_t N = mBag.size();
-        for (size_t i=0; i<N; i++) {
-            const String16& key = mBag.keyAt(i);
-            Item& it = mBag.editValueAt(i);
-            AccessorCookie ac(it.sourcePos, String8(key), String8(it.value));
-            if (!table->stringToValue(&it.parsedValue, strings,
-                                      it.value, false, true, it.bagKeyId,
-                                      &it.style, NULL, &ac, it.format,
-                                      configTypeName, config)) {
-                return UNKNOWN_ERROR;
-            }
-        }
-    } else {
-        mPos.error("Error: entry %s is not a single item or a bag.\n",
-                   String8(mName).string());
-        return UNKNOWN_ERROR;
-    }
-    return NO_ERROR;
-}
-
-status_t ResourceTable::Entry::remapStringValue(StringPool* strings)
-{
-    if (mType == TYPE_ITEM) {
-        Item& it = mItem;
-        if (it.parsedValue.dataType == Res_value::TYPE_STRING) {
-            it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data);
-        }
-    } else if (mType == TYPE_BAG) {
-        const size_t N = mBag.size();
-        for (size_t i=0; i<N; i++) {
-            Item& it = mBag.editValueAt(i);
-            if (it.parsedValue.dataType == Res_value::TYPE_STRING) {
-                it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data);
-            }
-        }
-    } else {
-        mPos.error("Error: entry %s is not a single item or a bag.\n",
-                   String8(mName).string());
-        return UNKNOWN_ERROR;
-    }
-    return NO_ERROR;
-}
-
-ssize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic)
-{
-    size_t amt = 0;
-    ResTable_entry header;
-    memset(&header, 0, sizeof(header));
-    header.size = htods(sizeof(header));
-    const type ty = this != NULL ? mType : TYPE_ITEM;
-    if (this != NULL) {
-        if (ty == TYPE_BAG) {
-            header.flags |= htods(header.FLAG_COMPLEX);
-        }
-        if (isPublic) {
-            header.flags |= htods(header.FLAG_PUBLIC);
-        }
-        header.key.index = htodl(mNameIndex);
-    }
-    if (ty != TYPE_BAG) {
-        status_t err = data->writeData(&header, sizeof(header));
-        if (err != NO_ERROR) {
-            fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n");
-            return err;
-        }
-
-        const Item& it = mItem;
-        Res_value par;
-        memset(&par, 0, sizeof(par));
-        par.size = htods(it.parsedValue.size);
-        par.dataType = it.parsedValue.dataType;
-        par.res0 = it.parsedValue.res0;
-        par.data = htodl(it.parsedValue.data);
-        #if 0
-        printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n",
-               String8(mName).string(), it.parsedValue.dataType,
-               it.parsedValue.data, par.res0);
-        #endif
-        err = data->writeData(&par, it.parsedValue.size);
-        if (err != NO_ERROR) {
-            fprintf(stderr, "ERROR: out of memory creating Res_value\n");
-            return err;
-        }
-        amt += it.parsedValue.size;
-    } else {
-        size_t N = mBag.size();
-        size_t i;
-        // Create correct ordering of items.
-        KeyedVector<uint32_t, const Item*> items;
-        for (i=0; i<N; i++) {
-            const Item& it = mBag.valueAt(i);
-            items.add(it.bagKeyId, &it);
-        }
-        N = items.size();
-        
-        ResTable_map_entry mapHeader;
-        memcpy(&mapHeader, &header, sizeof(header));
-        mapHeader.size = htods(sizeof(mapHeader));
-        mapHeader.parent.ident = htodl(mParentId);
-        mapHeader.count = htodl(N);
-        status_t err = data->writeData(&mapHeader, sizeof(mapHeader));
-        if (err != NO_ERROR) {
-            fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n");
-            return err;
-        }
-
-        for (i=0; i<N; i++) {
-            const Item& it = *items.valueAt(i);
-            ResTable_map map;
-            map.name.ident = htodl(it.bagKeyId);
-            map.value.size = htods(it.parsedValue.size);
-            map.value.dataType = it.parsedValue.dataType;
-            map.value.res0 = it.parsedValue.res0;
-            map.value.data = htodl(it.parsedValue.data);
-            err = data->writeData(&map, sizeof(map));
-            if (err != NO_ERROR) {
-                fprintf(stderr, "ERROR: out of memory creating Res_value\n");
-                return err;
-            }
-            amt += sizeof(map);
-        }
-    }
-    return amt;
-}
-
-void ResourceTable::ConfigList::appendComment(const String16& comment,
-                                              bool onlyIfEmpty)
-{
-    if (comment.size() <= 0) {
-        return;
-    }
-    if (onlyIfEmpty && mComment.size() > 0) {
-        return;
-    }
-    if (mComment.size() > 0) {
-        mComment.append(String16("\n"));
-    }
-    mComment.append(comment);
-}
-
-void ResourceTable::ConfigList::appendTypeComment(const String16& comment)
-{
-    if (comment.size() <= 0) {
-        return;
-    }
-    if (mTypeComment.size() > 0) {
-        mTypeComment.append(String16("\n"));
-    }
-    mTypeComment.append(comment);
-}
-
-status_t ResourceTable::Type::addPublic(const SourcePos& sourcePos,
-                                        const String16& name,
-                                        const uint32_t ident)
-{
-    #if 0
-    int32_t entryIdx = Res_GETENTRY(ident);
-    if (entryIdx < 0) {
-        sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n",
-                String8(mName).string(), String8(name).string(), ident);
-        return UNKNOWN_ERROR;
-    }
-    #endif
-
-    int32_t typeIdx = Res_GETTYPE(ident);
-    if (typeIdx >= 0) {
-        typeIdx++;
-        if (mPublicIndex > 0 && mPublicIndex != typeIdx) {
-            sourcePos.error("Public resource %s/%s has conflicting type codes for its"
-                    " public identifiers (0x%x vs 0x%x).\n",
-                    String8(mName).string(), String8(name).string(),
-                    mPublicIndex, typeIdx);
-            return UNKNOWN_ERROR;
-        }
-        mPublicIndex = typeIdx;
-    }
-
-    if (mFirstPublicSourcePos == NULL) {
-        mFirstPublicSourcePos = new SourcePos(sourcePos);
-    }
-
-    if (mPublic.indexOfKey(name) < 0) {
-        mPublic.add(name, Public(sourcePos, String16(), ident));
-    } else {
-        Public& p = mPublic.editValueFor(name);
-        if (p.ident != ident) {
-            sourcePos.error("Public resource %s/%s has conflicting public identifiers"
-                    " (0x%08x vs 0x%08x).\n"
-                    "%s:%d: Originally defined here.\n",
-                    String8(mName).string(), String8(name).string(), p.ident, ident,
-                    p.sourcePos.file.string(), p.sourcePos.line);
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-void ResourceTable::Type::canAddEntry(const String16& name)
-{
-    mCanAddEntries.add(name);
-}
-
-sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
-                                                       const SourcePos& sourcePos,
-                                                       const ResTable_config* config,
-                                                       bool doSetIndex,
-                                                       bool overlay,
-                                                       bool autoAddOverlay)
-{
-    int pos = -1;
-    sp<ConfigList> c = mConfigs.valueFor(entry);
-    if (c == NULL) {
-        if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) {
-            sourcePos.error("Resource at %s appears in overlay but not"
-                            " in the base package; use <add-resource> to add.\n",
-                            String8(entry).string());
-            return NULL;
-        }
-        c = new ConfigList(entry, sourcePos);
-        mConfigs.add(entry, c);
-        pos = (int)mOrderedConfigs.size();
-        mOrderedConfigs.add(c);
-        if (doSetIndex) {
-            c->setEntryIndex(pos);
-        }
-    }
-    
-    ConfigDescription cdesc;
-    if (config) cdesc = *config;
-    
-    sp<Entry> e = c->getEntries().valueFor(cdesc);
-    if (e == NULL) {
-        if (config != NULL) {
-            NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
-                    "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
-                    "sw%ddp w%ddp h%ddp dir:%d\n",
-                      sourcePos.file.string(), sourcePos.line,
-                      config->mcc, config->mnc,
-                      config->language[0] ? config->language[0] : '-',
-                      config->language[1] ? config->language[1] : '-',
-                      config->country[0] ? config->country[0] : '-',
-                      config->country[1] ? config->country[1] : '-',
-                      config->orientation,
-                      config->touchscreen,
-                      config->density,
-                      config->keyboard,
-                      config->inputFlags,
-                      config->navigation,
-                      config->screenWidth,
-                      config->screenHeight,
-                      config->smallestScreenWidthDp,
-                      config->screenWidthDp,
-                      config->screenHeightDp,
-                      config->layoutDirection));
-        } else {
-            NOISY(printf("New entry at %s:%d: NULL config\n",
-                      sourcePos.file.string(), sourcePos.line));
-        }
-        e = new Entry(entry, sourcePos);
-        c->addEntry(cdesc, e);
-        /*
-        if (doSetIndex) {
-            if (pos < 0) {
-                for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) {
-                    if (mOrderedConfigs[pos] == c) {
-                        break;
-                    }
-                }
-                if (pos >= (int)mOrderedConfigs.size()) {
-                    sourcePos.error("Internal error: config not found in mOrderedConfigs when adding entry");
-                    return NULL;
-                }
-            }
-            e->setEntryIndex(pos);
-        }
-        */
-    }
-    
-    mUniqueConfigs.add(cdesc);
-    
-    return e;
-}
-
-status_t ResourceTable::Type::applyPublicEntryOrder()
-{
-    size_t N = mOrderedConfigs.size();
-    Vector<sp<ConfigList> > origOrder(mOrderedConfigs);
-    bool hasError = false;
-
-    size_t i;
-    for (i=0; i<N; i++) {
-        mOrderedConfigs.replaceAt(NULL, i);
-    }
-
-    const size_t NP = mPublic.size();
-    //printf("Ordering %d configs from %d public defs\n", N, NP);
-    size_t j;
-    for (j=0; j<NP; j++) {
-        const String16& name = mPublic.keyAt(j);
-        const Public& p = mPublic.valueAt(j);
-        int32_t idx = Res_GETENTRY(p.ident);
-        //printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n",
-        //       String8(mName).string(), String8(name).string(), p.ident, N);
-        bool found = false;
-        for (i=0; i<N; i++) {
-            sp<ConfigList> e = origOrder.itemAt(i);
-            //printf("#%d: \"%s\"\n", i, String8(e->getName()).string());
-            if (e->getName() == name) {
-                if (idx >= (int32_t)mOrderedConfigs.size()) {
-                    p.sourcePos.error("Public entry identifier 0x%x entry index "
-                            "is larger than available symbols (index %d, total symbols %d).\n",
-                            p.ident, idx, mOrderedConfigs.size());
-                    hasError = true;
-                } else if (mOrderedConfigs.itemAt(idx) == NULL) {
-                    e->setPublic(true);
-                    e->setPublicSourcePos(p.sourcePos);
-                    mOrderedConfigs.replaceAt(e, idx);
-                    origOrder.removeAt(i);
-                    N--;
-                    found = true;
-                    break;
-                } else {
-                    sp<ConfigList> oe = mOrderedConfigs.itemAt(idx);
-
-                    p.sourcePos.error("Multiple entry names declared for public entry"
-                            " identifier 0x%x in type %s (%s vs %s).\n"
-                            "%s:%d: Originally defined here.",
-                            idx+1, String8(mName).string(),
-                            String8(oe->getName()).string(),
-                            String8(name).string(),
-                            oe->getPublicSourcePos().file.string(),
-                            oe->getPublicSourcePos().line);
-                    hasError = true;
-                }
-            }
-        }
-
-        if (!found) {
-            p.sourcePos.error("Public symbol %s/%s declared here is not defined.",
-                    String8(mName).string(), String8(name).string());
-            hasError = true;
-        }
-    }
-
-    //printf("Copying back in %d non-public configs, have %d\n", N, origOrder.size());
-    
-    if (N != origOrder.size()) {
-        printf("Internal error: remaining private symbol count mismatch\n");
-        N = origOrder.size();
-    }
-    
-    j = 0;
-    for (i=0; i<N; i++) {
-        sp<ConfigList> e = origOrder.itemAt(i);
-        // There will always be enough room for the remaining entries.
-        while (mOrderedConfigs.itemAt(j) != NULL) {
-            j++;
-        }
-        mOrderedConfigs.replaceAt(e, j);
-        j++;
-    }
-
-    return hasError ? UNKNOWN_ERROR : NO_ERROR;
-}
-
-ResourceTable::Package::Package(const String16& name, ssize_t includedId)
-    : mName(name), mIncludedId(includedId),
-      mTypeStringsMapping(0xffffffff),
-      mKeyStringsMapping(0xffffffff)
-{
-}
-
-sp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type,
-                                                        const SourcePos& sourcePos,
-                                                        bool doSetIndex)
-{
-    sp<Type> t = mTypes.valueFor(type);
-    if (t == NULL) {
-        t = new Type(type, sourcePos);
-        mTypes.add(type, t);
-        mOrderedTypes.add(t);
-        if (doSetIndex) {
-            // For some reason the type's index is set to one plus the index
-            // in the mOrderedTypes list, rather than just the index.
-            t->setIndex(mOrderedTypes.size());
-        }
-    }
-    return t;
-}
-
-status_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data)
-{
-    mTypeStringsData = data;
-    status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping);
-    if (err != NO_ERROR) {
-        fprintf(stderr, "ERROR: Type string data is corrupt!\n");
-    }
-    return err;
-}
-
-status_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data)
-{
-    mKeyStringsData = data;
-    status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping);
-    if (err != NO_ERROR) {
-        fprintf(stderr, "ERROR: Key string data is corrupt!\n");
-    }
-    return err;
-}
-
-status_t ResourceTable::Package::setStrings(const sp<AaptFile>& data,
-                                            ResStringPool* strings,
-                                            DefaultKeyedVector<String16, uint32_t>* mappings)
-{
-    if (data->getData() == NULL) {
-        return UNKNOWN_ERROR;
-    }
-
-    NOISY(aout << "Setting restable string pool: "
-          << HexDump(data->getData(), data->getSize()) << endl);
-
-    status_t err = strings->setTo(data->getData(), data->getSize());
-    if (err == NO_ERROR) {
-        const size_t N = strings->size();
-        for (size_t i=0; i<N; i++) {
-            size_t len;
-            mappings->add(String16(strings->stringAt(i, &len)), i);
-        }
-    }
-    return err;
-}
-
-status_t ResourceTable::Package::applyPublicTypeOrder()
-{
-    size_t N = mOrderedTypes.size();
-    Vector<sp<Type> > origOrder(mOrderedTypes);
-
-    size_t i;
-    for (i=0; i<N; i++) {
-        mOrderedTypes.replaceAt(NULL, i);
-    }
-
-    for (i=0; i<N; i++) {
-        sp<Type> t = origOrder.itemAt(i);
-        int32_t idx = t->getPublicIndex();
-        if (idx > 0) {
-            idx--;
-            while (idx >= (int32_t)mOrderedTypes.size()) {
-                mOrderedTypes.add();
-            }
-            if (mOrderedTypes.itemAt(idx) != NULL) {
-                sp<Type> ot = mOrderedTypes.itemAt(idx);
-                t->getFirstPublicSourcePos().error("Multiple type names declared for public type"
-                        " identifier 0x%x (%s vs %s).\n"
-                        "%s:%d: Originally defined here.",
-                        idx, String8(ot->getName()).string(),
-                        String8(t->getName()).string(),
-                        ot->getFirstPublicSourcePos().file.string(),
-                        ot->getFirstPublicSourcePos().line);
-                return UNKNOWN_ERROR;
-            }
-            mOrderedTypes.replaceAt(t, idx);
-            origOrder.removeAt(i);
-            i--;
-            N--;
-        }
-    }
-
-    size_t j=0;
-    for (i=0; i<N; i++) {
-        sp<Type> t = origOrder.itemAt(i);
-        // There will always be enough room for the remaining types.
-        while (mOrderedTypes.itemAt(j) != NULL) {
-            j++;
-        }
-        mOrderedTypes.replaceAt(t, j);
-    }
-
-    return NO_ERROR;
-}
-
-sp<ResourceTable::Package> ResourceTable::getPackage(const String16& package)
-{
-    sp<Package> p = mPackages.valueFor(package);
-    if (p == NULL) {
-        if (mIsAppPackage) {
-            if (mHaveAppPackage) {
-                fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n"
-                                "Use -x to create extended resources.\n");
-                return NULL;
-            }
-            mHaveAppPackage = true;
-            p = new Package(package, 127);
-        } else {
-            p = new Package(package, mNextPackageId);
-        }
-        //printf("*** NEW PACKAGE: \"%s\" id=%d\n",
-        //       String8(package).string(), p->getAssignedId());
-        mPackages.add(package, p);
-        mOrderedPackages.add(p);
-        mNextPackageId++;
-    }
-    return p;
-}
-
-sp<ResourceTable::Type> ResourceTable::getType(const String16& package,
-                                               const String16& type,
-                                               const SourcePos& sourcePos,
-                                               bool doSetIndex)
-{
-    sp<Package> p = getPackage(package);
-    if (p == NULL) {
-        return NULL;
-    }
-    return p->getType(type, sourcePos, doSetIndex);
-}
-
-sp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package,
-                                                 const String16& type,
-                                                 const String16& name,
-                                                 const SourcePos& sourcePos,
-                                                 bool overlay,
-                                                 const ResTable_config* config,
-                                                 bool doSetIndex)
-{
-    sp<Type> t = getType(package, type, sourcePos, doSetIndex);
-    if (t == NULL) {
-        return NULL;
-    }
-    return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay());
-}
-
-sp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID,
-                                                       const ResTable_config* config) const
-{
-    int pid = Res_GETPACKAGE(resID)+1;
-    const size_t N = mOrderedPackages.size();
-    size_t i;
-    sp<Package> p;
-    for (i=0; i<N; i++) {
-        sp<Package> check = mOrderedPackages[i];
-        if (check->getAssignedId() == pid) {
-            p = check;
-            break;
-        }
-
-    }
-    if (p == NULL) {
-        fprintf(stderr, "warning: Package not found for resource #%08x\n", resID);
-        return NULL;
-    }
-
-    int tid = Res_GETTYPE(resID);
-    if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) {
-        fprintf(stderr, "warning: Type not found for resource #%08x\n", resID);
-        return NULL;
-    }
-    sp<Type> t = p->getOrderedTypes()[tid];
-
-    int eid = Res_GETENTRY(resID);
-    if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) {
-        fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID);
-        return NULL;
-    }
-
-    sp<ConfigList> c = t->getOrderedConfigs()[eid];
-    if (c == NULL) {
-        fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID);
-        return NULL;
-    }
-    
-    ConfigDescription cdesc;
-    if (config) cdesc = *config;
-    sp<Entry> e = c->getEntries().valueFor(cdesc);
-    if (c == NULL) {
-        fprintf(stderr, "warning: Entry configuration not found for resource #%08x\n", resID);
-        return NULL;
-    }
-    
-    return e;
-}
-
-const ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const
-{
-    sp<const Entry> e = getEntry(resID);
-    if (e == NULL) {
-        return NULL;
-    }
-
-    const size_t N = e->getBag().size();
-    for (size_t i=0; i<N; i++) {
-        const Item& it = e->getBag().valueAt(i);
-        if (it.bagKeyId == 0) {
-            fprintf(stderr, "warning: ID not yet assigned to '%s' in bag '%s'\n",
-                    String8(e->getName()).string(),
-                    String8(e->getBag().keyAt(i)).string());
-        }
-        if (it.bagKeyId == attrID) {
-            return &it;
-        }
-    }
-
-    return NULL;
-}
-
-bool ResourceTable::getItemValue(
-    uint32_t resID, uint32_t attrID, Res_value* outValue)
-{
-    const Item* item = getItem(resID, attrID);
-
-    bool res = false;
-    if (item != NULL) {
-        if (item->evaluating) {
-            sp<const Entry> e = getEntry(resID);
-            const size_t N = e->getBag().size();
-            size_t i;
-            for (i=0; i<N; i++) {
-                if (&e->getBag().valueAt(i) == item) {
-                    break;
-                }
-            }
-            fprintf(stderr, "warning: Circular reference detected in key '%s' of bag '%s'\n",
-                    String8(e->getName()).string(),
-                    String8(e->getBag().keyAt(i)).string());
-            return false;
-        }
-        item->evaluating = true;
-        res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId);
-        NOISY(
-            if (res) {
-                printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n",
-                       resID, attrID, String8(getEntry(resID)->getName()).string(),
-                       outValue->dataType, outValue->data);
-            } else {
-                printf("getItemValue of #%08x[#%08x]: failed\n",
-                       resID, attrID);
-            }
-        );
-        item->evaluating = false;
-    }
-    return res;
-}
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
deleted file mode 100644
index a3e0666..0000000
--- a/tools/aapt/ResourceTable.h
+++ /dev/null
@@ -1,557 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Build resource files from raw assets.
-//
-
-#ifndef RESOURCE_TABLE_H
-#define RESOURCE_TABLE_H
-
-#include "StringPool.h"
-#include "SourcePos.h"
-
-#include <set>
-#include <map>
-
-using namespace std;
-
-class XMLNode;
-class ResourceTable;
-
-enum {
-    XML_COMPILE_STRIP_COMMENTS = 1<<0,
-    XML_COMPILE_ASSIGN_ATTRIBUTE_IDS = 1<<1,
-    XML_COMPILE_COMPACT_WHITESPACE = 1<<2,
-    XML_COMPILE_STRIP_WHITESPACE = 1<<3,
-    XML_COMPILE_STRIP_RAW_VALUES = 1<<4,
-    XML_COMPILE_UTF8 = 1<<5,
-    
-    XML_COMPILE_STANDARD_RESOURCE =
-            XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS
-            | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES
-};
-
-status_t compileXmlFile(const sp<AaptAssets>& assets,
-                        const sp<AaptFile>& target,
-                        ResourceTable* table,
-                        int options = XML_COMPILE_STANDARD_RESOURCE);
-
-status_t compileXmlFile(const sp<AaptAssets>& assets,
-                        const sp<AaptFile>& target,
-                        const sp<AaptFile>& outTarget,
-                        ResourceTable* table,
-                        int options = XML_COMPILE_STANDARD_RESOURCE);
-
-status_t compileXmlFile(const sp<AaptAssets>& assets,
-                        const sp<XMLNode>& xmlTree,
-                        const sp<AaptFile>& target,
-                        ResourceTable* table,
-                        int options = XML_COMPILE_STANDARD_RESOURCE);
-
-status_t compileResourceFile(Bundle* bundle,
-                             const sp<AaptAssets>& assets,
-                             const sp<AaptFile>& in,
-                             const ResTable_config& defParams,
-                             const bool overwrite,
-                             ResourceTable* outTable);
-
-struct AccessorCookie
-{
-    SourcePos sourcePos;
-    String8 attr;
-    String8 value;
-
-    AccessorCookie(const SourcePos&p, const String8& a, const String8& v)
-        :sourcePos(p),
-         attr(a),
-         value(v)
-    {
-    }
-};
-
-class ResourceTable : public ResTable::Accessor
-{
-public:
-    class Package;
-    class Type;
-    class Entry;
-
-    struct ConfigDescription : public ResTable_config {
-        ConfigDescription() {
-            memset(this, 0, sizeof(*this));
-            size = sizeof(ResTable_config);
-        }
-        ConfigDescription(const ResTable_config&o) {
-            *static_cast<ResTable_config*>(this) = o;
-            size = sizeof(ResTable_config);
-        }
-        ConfigDescription(const ConfigDescription&o) {
-            *static_cast<ResTable_config*>(this) = o;
-        }
-
-        ConfigDescription& operator=(const ResTable_config& o) {
-            *static_cast<ResTable_config*>(this) = o;
-            size = sizeof(ResTable_config);
-            return *this;
-        }
-        ConfigDescription& operator=(const ConfigDescription& o) {
-            *static_cast<ResTable_config*>(this) = o;
-            return *this;
-        }
-
-        inline bool operator<(const ConfigDescription& o) const { return compare(o) < 0; }
-        inline bool operator<=(const ConfigDescription& o) const { return compare(o) <= 0; }
-        inline bool operator==(const ConfigDescription& o) const { return compare(o) == 0; }
-        inline bool operator!=(const ConfigDescription& o) const { return compare(o) != 0; }
-        inline bool operator>=(const ConfigDescription& o) const { return compare(o) >= 0; }
-        inline bool operator>(const ConfigDescription& o) const { return compare(o) > 0; }
-    };
-
-    ResourceTable(Bundle* bundle, const String16& assetsPackage);
-
-    status_t addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets);
-
-    status_t addPublic(const SourcePos& pos,
-                       const String16& package,
-                       const String16& type,
-                       const String16& name,
-                       const uint32_t ident);
-
-    status_t addEntry(const SourcePos& pos,
-                      const String16& package,
-                      const String16& type,
-                      const String16& name,
-                      const String16& value,
-                      const Vector<StringPool::entry_style_span>* style = NULL,
-                      const ResTable_config* params = NULL,
-                      const bool doSetIndex = false,
-                      const int32_t format = ResTable_map::TYPE_ANY,
-                      const bool overwrite = false);
-
-    status_t startBag(const SourcePos& pos,
-                    const String16& package,
-                    const String16& type,
-                    const String16& name,
-                    const String16& bagParent,
-                    const ResTable_config* params = NULL,
-                    bool overlay = false,
-                    bool replace = false,
-                    bool isId = false);
-    
-    status_t addBag(const SourcePos& pos,
-                    const String16& package,
-                    const String16& type,
-                    const String16& name,
-                    const String16& bagParent,
-                    const String16& bagKey,
-                    const String16& value,
-                    const Vector<StringPool::entry_style_span>* style = NULL,
-                    const ResTable_config* params = NULL,
-                    bool replace = false,
-                    bool isId = false,
-                    const int32_t format = ResTable_map::TYPE_ANY);
-
-    bool hasBagOrEntry(const String16& package,
-                       const String16& type,
-                       const String16& name) const;
-
-    bool hasBagOrEntry(const String16& package,
-                       const String16& type,
-                       const String16& name,
-                       const ResTable_config& config) const;
-
-    bool hasBagOrEntry(const String16& ref,
-                       const String16* defType = NULL,
-                       const String16* defPackage = NULL);
-
-    bool appendComment(const String16& package,
-                       const String16& type,
-                       const String16& name,
-                       const String16& comment,
-                       bool onlyIfEmpty = false);
-
-    bool appendTypeComment(const String16& package,
-                           const String16& type,
-                           const String16& name,
-                           const String16& comment);
-    
-    void canAddEntry(const SourcePos& pos,
-        const String16& package, const String16& type, const String16& name);
-        
-    size_t size() const;
-    size_t numLocalResources() const;
-    bool hasResources() const;
-
-    sp<AaptFile> flatten(Bundle*);
-
-    static inline uint32_t makeResId(uint32_t packageId,
-                                     uint32_t typeId,
-                                     uint32_t nameId)
-    {
-        return nameId | (typeId<<16) | (packageId<<24);
-    }
-
-    static inline uint32_t getResId(const sp<Package>& p,
-                                    const sp<Type>& t,
-                                    uint32_t nameId);
-
-    uint32_t getResId(const String16& package,
-                      const String16& type,
-                      const String16& name,
-                      bool onlyPublic = true) const;
-
-    uint32_t getResId(const String16& ref,
-                      const String16* defType = NULL,
-                      const String16* defPackage = NULL,
-                      const char** outErrorMsg = NULL,
-                      bool onlyPublic = true) const;
-
-    static bool isValidResourceName(const String16& s);
-    
-    bool stringToValue(Res_value* outValue, StringPool* pool,
-                       const String16& str,
-                       bool preserveSpaces, bool coerceType,
-                       uint32_t attrID,
-                       const Vector<StringPool::entry_style_span>* style = NULL,
-                       String16* outStr = NULL, void* accessorCookie = NULL,
-                       uint32_t attrType = ResTable_map::TYPE_ANY,
-                       const String8* configTypeName = NULL,
-                       const ConfigDescription* config = NULL);
-
-    status_t assignResourceIds();
-    status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL);
-    void addLocalization(const String16& name, const String8& locale);
-    status_t validateLocalizations(void);
-
-    status_t flatten(Bundle*, const sp<AaptFile>& dest);
-
-    void writePublicDefinitions(const String16& package, FILE* fp);
-
-    virtual uint32_t getCustomResource(const String16& package,
-                                       const String16& type,
-                                       const String16& name) const;
-    virtual uint32_t getCustomResourceWithCreation(const String16& package,
-                                                   const String16& type,
-                                                   const String16& name,
-                                                   const bool createIfNeeded);
-    virtual uint32_t getRemappedPackage(uint32_t origPackage) const;
-    virtual bool getAttributeType(uint32_t attrID, uint32_t* outType);
-    virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin);
-    virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax);
-    virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys);
-    virtual bool getAttributeEnum(uint32_t attrID,
-                                  const char16_t* name, size_t nameLen,
-                                  Res_value* outValue);
-    virtual bool getAttributeFlags(uint32_t attrID,
-                                   const char16_t* name, size_t nameLen,
-                                   Res_value* outValue);
-    virtual uint32_t getAttributeL10N(uint32_t attrID);
-
-    virtual bool getLocalizationSetting();
-    virtual void reportError(void* accessorCookie, const char* fmt, ...);
-
-    void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }
-
-    class Item {
-    public:
-        Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false)
-            { memset(&parsedValue, 0, sizeof(parsedValue)); }
-        Item(const SourcePos& pos,
-             bool _isId,
-             const String16& _value,
-             const Vector<StringPool::entry_style_span>* _style = NULL,
-             int32_t format = ResTable_map::TYPE_ANY);
-        Item(const Item& o) : sourcePos(o.sourcePos),
-            isId(o.isId), value(o.value), style(o.style),
-            format(o.format), bagKeyId(o.bagKeyId), evaluating(false) {
-            memset(&parsedValue, 0, sizeof(parsedValue));
-        }
-        ~Item() { }
-
-        Item& operator=(const Item& o) {
-            sourcePos = o.sourcePos;
-            isId = o.isId;
-            value = o.value;
-            style = o.style;
-            format = o.format;
-            bagKeyId = o.bagKeyId;
-            parsedValue = o.parsedValue;
-            return *this;
-        }
-
-        SourcePos                               sourcePos;
-        mutable bool                            isId;
-        String16                                value;
-        Vector<StringPool::entry_style_span>    style;
-        int32_t                                 format;
-        uint32_t                                bagKeyId;
-        mutable bool                            evaluating;
-        Res_value                               parsedValue;
-    };
-
-    class Entry : public RefBase {
-    public:
-        Entry(const String16& name, const SourcePos& pos)
-            : mName(name), mType(TYPE_UNKNOWN),
-              mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos)
-        { }
-        virtual ~Entry() { }
-
-        enum type {
-            TYPE_UNKNOWN = 0,
-            TYPE_ITEM,
-            TYPE_BAG
-        };
-        
-        String16 getName() const { return mName; }
-        type getType() const { return mType; }
-
-        void setParent(const String16& parent) { mParent = parent; }
-        String16 getParent() const { return mParent; }
-
-        status_t makeItABag(const SourcePos& sourcePos);
-
-        status_t emptyBag(const SourcePos& sourcePos);
- 
-        status_t setItem(const SourcePos& pos,
-                         const String16& value,
-                         const Vector<StringPool::entry_style_span>* style = NULL,
-                         int32_t format = ResTable_map::TYPE_ANY,
-                         const bool overwrite = false);
-
-        status_t addToBag(const SourcePos& pos,
-                          const String16& key, const String16& value,
-                          const Vector<StringPool::entry_style_span>* style = NULL,
-                          bool replace=false, bool isId = false,
-                          int32_t format = ResTable_map::TYPE_ANY);
-
-        // Index of the entry's name string in the key pool.
-        int32_t getNameIndex() const { return mNameIndex; }
-        void setNameIndex(int32_t index) { mNameIndex = index; }
-
-        const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }
-        const KeyedVector<String16, Item>& getBag() const { return mBag; }
-
-        status_t generateAttributes(ResourceTable* table,
-                                    const String16& package);
-
-        status_t assignResourceIds(ResourceTable* table,
-                                   const String16& package);
-
-        status_t prepareFlatten(StringPool* strings, ResourceTable* table,
-               const String8* configTypeName, const ConfigDescription* config);
-
-        status_t remapStringValue(StringPool* strings);
-
-        ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic);
-
-        const SourcePos& getPos() const { return mPos; }
-
-    private:
-        String16 mName;
-        String16 mParent;
-        type mType;
-        Item mItem;
-        int32_t mItemFormat;
-        KeyedVector<String16, Item> mBag;
-        int32_t mNameIndex;
-        uint32_t mParentId;
-        SourcePos mPos;
-    };
-    
-    class ConfigList : public RefBase {
-    public:
-        ConfigList(const String16& name, const SourcePos& pos)
-            : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }
-        virtual ~ConfigList() { }
-        
-        String16 getName() const { return mName; }
-        const SourcePos& getPos() const { return mPos; }
-        
-        void appendComment(const String16& comment, bool onlyIfEmpty = false);
-        const String16& getComment() const { return mComment; }
-        
-        void appendTypeComment(const String16& comment);
-        const String16& getTypeComment() const { return mTypeComment; }
-        
-        // Index of this entry in its Type.
-        int32_t getEntryIndex() const { return mEntryIndex; }
-        void setEntryIndex(int32_t index) { mEntryIndex = index; }
-        
-        void setPublic(bool pub) { mPublic = pub; }
-        bool getPublic() const { return mPublic; }
-        void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }
-        const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }
-        
-        void addEntry(const ResTable_config& config, const sp<Entry>& entry) {
-            mEntries.add(config, entry);
-        }
-        
-        const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }
-    private:
-        const String16 mName;
-        const SourcePos mPos;
-        String16 mComment;
-        String16 mTypeComment;
-        bool mPublic;
-        SourcePos mPublicSourcePos;
-        int32_t mEntryIndex;
-        DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries;
-    };
-    
-    class Public {
-    public:
-        Public() : sourcePos(), ident(0) { }
-        Public(const SourcePos& pos,
-               const String16& _comment,
-               uint32_t _ident)
-            : sourcePos(pos),
-            comment(_comment), ident(_ident) { }
-        Public(const Public& o) : sourcePos(o.sourcePos),
-            comment(o.comment), ident(o.ident) { }
-        ~Public() { }
-        
-        Public& operator=(const Public& o) {
-            sourcePos = o.sourcePos;
-            comment = o.comment;
-            ident = o.ident;
-            return *this;
-        }
-        
-        SourcePos   sourcePos;
-        String16    comment;
-        uint32_t    ident;
-    };
-    
-    class Type : public RefBase {
-    public:
-        Type(const String16& name, const SourcePos& pos)
-                : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)
-        { }
-        virtual ~Type() { delete mFirstPublicSourcePos; }
-
-        status_t addPublic(const SourcePos& pos,
-                           const String16& name,
-                           const uint32_t ident);
-                           
-        void canAddEntry(const String16& name);
-        
-        String16 getName() const { return mName; }
-        sp<Entry> getEntry(const String16& entry,
-                           const SourcePos& pos,
-                           const ResTable_config* config = NULL,
-                           bool doSetIndex = false,
-                           bool overlay = false,
-                           bool autoAddOverlay = false);
-
-        const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
-
-        int32_t getPublicIndex() const { return mPublicIndex; }
-
-        int32_t getIndex() const { return mIndex; }
-        void setIndex(int32_t index) { mIndex = index; }
-
-        status_t applyPublicEntryOrder();
-
-        const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; }
-        
-        const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
-        const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
-
-        const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
-        
-        const SourcePos& getPos() const { return mPos; }
-    private:
-        String16 mName;
-        SourcePos* mFirstPublicSourcePos;
-        DefaultKeyedVector<String16, Public> mPublic;
-        SortedVector<ConfigDescription> mUniqueConfigs;
-        DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;
-        Vector<sp<ConfigList> > mOrderedConfigs;
-        SortedVector<String16> mCanAddEntries;
-        int32_t mPublicIndex;
-        int32_t mIndex;
-        SourcePos mPos;
-    };
-
-    class Package : public RefBase {
-    public:
-        Package(const String16& name, ssize_t includedId=-1);
-        virtual ~Package() { }
-
-        String16 getName() const { return mName; }
-        sp<Type> getType(const String16& type,
-                         const SourcePos& pos,
-                         bool doSetIndex = false);
-
-        ssize_t getAssignedId() const { return mIncludedId; }
-
-        const ResStringPool& getTypeStrings() const { return mTypeStrings; }
-        uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }
-        const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }
-        status_t setTypeStrings(const sp<AaptFile>& data);
-
-        const ResStringPool& getKeyStrings() const { return mKeyStrings; }
-        uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }
-        const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }
-        status_t setKeyStrings(const sp<AaptFile>& data);
-
-        status_t applyPublicTypeOrder();
-
-        const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }
-        const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; }
-
-    private:
-        status_t setStrings(const sp<AaptFile>& data,
-                            ResStringPool* strings,
-                            DefaultKeyedVector<String16, uint32_t>* mappings);
-
-        const String16 mName;
-        const ssize_t mIncludedId;
-        DefaultKeyedVector<String16, sp<Type> > mTypes;
-        Vector<sp<Type> > mOrderedTypes;
-        sp<AaptFile> mTypeStringsData;
-        sp<AaptFile> mKeyStringsData;
-        ResStringPool mTypeStrings;
-        ResStringPool mKeyStrings;
-        DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping;
-        DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
-    };
-
-private:
-    void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
-    sp<Package> getPackage(const String16& package);
-    sp<Type> getType(const String16& package,
-                     const String16& type,
-                     const SourcePos& pos,
-                     bool doSetIndex = false);
-    sp<Entry> getEntry(const String16& package,
-                       const String16& type,
-                       const String16& name,
-                       const SourcePos& pos,
-                       bool overlay,
-                       const ResTable_config* config = NULL,
-                       bool doSetIndex = false);
-    sp<const Entry> getEntry(uint32_t resID,
-                             const ResTable_config* config = NULL) const;
-    const Item* getItem(uint32_t resID, uint32_t attrID) const;
-    bool getItemValue(uint32_t resID, uint32_t attrID,
-                      Res_value* outValue);
-
-
-    String16 mAssetsPackage;
-    sp<AaptAssets> mAssets;
-    DefaultKeyedVector<String16, sp<Package> > mPackages;
-    Vector<sp<Package> > mOrderedPackages;
-    uint32_t mNextPackageId;
-    bool mHaveAppPackage;
-    bool mIsAppPackage;
-    size_t mNumLocal;
-    SourcePos mCurrentXmlPos;
-    Bundle* mBundle;
-    
-    // key = string resource name, value = set of locales in which that name is defined
-    map<String16, set<String8> > mLocalizations;
-};
-
-#endif
diff --git a/tools/aapt/SourcePos.cpp b/tools/aapt/SourcePos.cpp
deleted file mode 100644
index e2a921c..0000000
--- a/tools/aapt/SourcePos.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-#include "SourcePos.h"
-
-#include <stdarg.h>
-#include <vector>
-
-using namespace std;
-
-
-// ErrorPos
-// =============================================================================
-struct ErrorPos
-{
-    String8 file;
-    int line;
-    String8 error;
-    bool fatal;
-
-    ErrorPos();
-    ErrorPos(const ErrorPos& that);
-    ErrorPos(const String8& file, int line, const String8& error, bool fatal);
-    ~ErrorPos();
-    bool operator<(const ErrorPos& rhs) const;
-    bool operator==(const ErrorPos& rhs) const;
-    ErrorPos& operator=(const ErrorPos& rhs);
-
-    void print(FILE* to) const;
-};
-
-static vector<ErrorPos> g_errors;
-
-ErrorPos::ErrorPos()
-    :line(-1), fatal(false)
-{
-}
-
-ErrorPos::ErrorPos(const ErrorPos& that)
-    :file(that.file),
-     line(that.line),
-     error(that.error),
-     fatal(that.fatal)
-{
-}
-
-ErrorPos::ErrorPos(const String8& f, int l, const String8& e, bool fat)
-    :file(f),
-     line(l),
-     error(e),
-     fatal(fat)
-{
-}
-
-ErrorPos::~ErrorPos()
-{
-}
-
-bool
-ErrorPos::operator<(const ErrorPos& rhs) const
-{
-    if (this->file < rhs.file) return true;
-    if (this->file == rhs.file) {
-        if (this->line < rhs.line) return true;
-        if (this->line == rhs.line) {
-            if (this->error < rhs.error) return true;
-        }
-    }
-    return false;
-}
-
-bool
-ErrorPos::operator==(const ErrorPos& rhs) const
-{
-    return this->file == rhs.file
-            && this->line == rhs.line
-            && this->error == rhs.error;
-}
-
-ErrorPos&
-ErrorPos::operator=(const ErrorPos& rhs)
-{
-    this->file = rhs.file;
-    this->line = rhs.line;
-    this->error = rhs.error;
-    return *this;
-}
-
-void
-ErrorPos::print(FILE* to) const
-{
-    const char* type = fatal ? "error:" : "warning:";
-    
-    if (this->line >= 0) {
-        fprintf(to, "%s:%d: %s %s\n", this->file.string(), this->line, type, this->error.string());
-    } else {
-        fprintf(to, "%s: %s %s\n", this->file.string(), type, this->error.string());
-    }
-}
-
-// SourcePos
-// =============================================================================
-SourcePos::SourcePos(const String8& f, int l)
-    : file(f), line(l)
-{
-}
-
-SourcePos::SourcePos(const SourcePos& that)
-    : file(that.file), line(that.line)
-{
-}
-
-SourcePos::SourcePos()
-    : file("???", 0), line(-1)
-{
-}
-
-SourcePos::~SourcePos()
-{
-}
-
-int
-SourcePos::error(const char* fmt, ...) const
-{
-    int retval=0;
-    char buf[1024];
-    va_list ap;
-    va_start(ap, fmt);
-    retval = vsnprintf(buf, sizeof(buf), fmt, ap);
-    va_end(ap);
-    char* p = buf + retval - 1;
-    while (p > buf && *p == '\n') {
-        *p = '\0';
-        p--;
-    }
-    g_errors.push_back(ErrorPos(this->file, this->line, String8(buf), true));
-    return retval;
-}
-
-int
-SourcePos::warning(const char* fmt, ...) const
-{
-    int retval=0;
-    char buf[1024];
-    va_list ap;
-    va_start(ap, fmt);
-    retval = vsnprintf(buf, sizeof(buf), fmt, ap);
-    va_end(ap);
-    char* p = buf + retval - 1;
-    while (p > buf && *p == '\n') {
-        *p = '\0';
-        p--;
-    }
-    ErrorPos(this->file, this->line, String8(buf), false).print(stderr);
-    return retval;
-}
-
-bool
-SourcePos::hasErrors()
-{
-    return g_errors.size() > 0;
-}
-
-void
-SourcePos::printErrors(FILE* to)
-{
-    vector<ErrorPos>::const_iterator it;
-    for (it=g_errors.begin(); it!=g_errors.end(); it++) {
-        it->print(to);
-    }
-}
-
-
-
diff --git a/tools/aapt/SourcePos.h b/tools/aapt/SourcePos.h
deleted file mode 100644
index 33f72a9..0000000
--- a/tools/aapt/SourcePos.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef SOURCEPOS_H
-#define SOURCEPOS_H
-
-#include <utils/String8.h>
-#include <stdio.h>
-
-using namespace android;
-
-class SourcePos
-{
-public:
-    String8 file;
-    int line;
-
-    SourcePos(const String8& f, int l);
-    SourcePos(const SourcePos& that);
-    SourcePos();
-    ~SourcePos();
-
-    int error(const char* fmt, ...) const;
-    int warning(const char* fmt, ...) const;
-
-    static bool hasErrors();
-    static void printErrors(FILE* to);
-};
-
-
-#endif // SOURCEPOS_H
diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp
deleted file mode 100644
index 158b391..0000000
--- a/tools/aapt/StringPool.cpp
+++ /dev/null
@@ -1,574 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Build resource files from raw assets.
-//
-
-#include "StringPool.h"
-#include "ResourceTable.h"
-
-#include <utils/ByteOrder.h>
-#include <utils/SortedVector.h>
-#include "qsort_r_compat.h"
-
-#if HAVE_PRINTF_ZD
-#  define ZD "%zd"
-#  define ZD_TYPE ssize_t
-#else
-#  define ZD "%ld"
-#  define ZD_TYPE long
-#endif
-
-#define NOISY(x) //x
-
-void strcpy16_htod(uint16_t* dst, const uint16_t* src)
-{
-    while (*src) {
-        char16_t s = htods(*src);
-        *dst++ = s;
-        src++;
-    }
-    *dst = 0;
-}
-
-void printStringPool(const ResStringPool* pool)
-{
-    SortedVector<const void*> uniqueStrings;
-    const size_t N = pool->size();
-    for (size_t i=0; i<N; i++) {
-        size_t len;
-        if (pool->isUTF8()) {
-            uniqueStrings.add(pool->string8At(i, &len));
-        } else {
-            uniqueStrings.add(pool->stringAt(i, &len));
-        }
-    }
-
-    printf("String pool of " ZD " unique %s %s strings, " ZD " entries and "
-            ZD " styles using " ZD " bytes:\n",
-            (ZD_TYPE)uniqueStrings.size(), pool->isUTF8() ? "UTF-8" : "UTF-16",
-            pool->isSorted() ? "sorted" : "non-sorted",
-            (ZD_TYPE)N, (ZD_TYPE)pool->styleCount(), (ZD_TYPE)pool->bytes());
-
-    const size_t NS = pool->size();
-    for (size_t s=0; s<NS; s++) {
-        String8 str = pool->string8ObjectAt(s);
-        printf("String #" ZD ": %s\n", (ZD_TYPE) s, str.string());
-    }
-}
-
-String8 StringPool::entry::makeConfigsString() const {
-    String8 configStr(configTypeName);
-    if (configStr.size() > 0) configStr.append(" ");
-    if (configs.size() > 0) {
-        for (size_t j=0; j<configs.size(); j++) {
-            if (j > 0) configStr.append(", ");
-            configStr.append(configs[j].toString());
-        }
-    } else {
-        configStr = "(none)";
-    }
-    return configStr;
-}
-
-int StringPool::entry::compare(const entry& o) const {
-    // Strings with styles go first, to reduce the size of the styles array.
-    // We don't care about the relative order of these strings.
-    if (hasStyles) {
-        return o.hasStyles ? 0 : -1;
-    }
-    if (o.hasStyles) {
-        return 1;
-    }
-
-    // Sort unstyled strings by type, then by logical configuration.
-    int comp = configTypeName.compare(o.configTypeName);
-    if (comp != 0) {
-        return comp;
-    }
-    const size_t LHN = configs.size();
-    const size_t RHN = o.configs.size();
-    size_t i=0;
-    while (i < LHN && i < RHN) {
-        comp = configs[i].compareLogical(o.configs[i]);
-        if (comp != 0) {
-            return comp;
-        }
-        i++;
-    }
-    if (LHN < RHN) return -1;
-    else if (LHN > RHN) return 1;
-    return 0;
-}
-
-StringPool::StringPool(bool utf8) :
-        mUTF8(utf8), mValues(-1)
-{
-}
-
-ssize_t StringPool::add(const String16& value, const Vector<entry_style_span>& spans,
-        const String8* configTypeName, const ResTable_config* config)
-{
-    ssize_t res = add(value, false, configTypeName, config);
-    if (res >= 0) {
-        addStyleSpans(res, spans);
-    }
-    return res;
-}
-
-ssize_t StringPool::add(const String16& value,
-        bool mergeDuplicates, const String8* configTypeName, const ResTable_config* config)
-{
-    ssize_t vidx = mValues.indexOfKey(value);
-    ssize_t pos = vidx >= 0 ? mValues.valueAt(vidx) : -1;
-    ssize_t eidx = pos >= 0 ? mEntryArray.itemAt(pos) : -1;
-    if (eidx < 0) {
-        eidx = mEntries.add(entry(value));
-        if (eidx < 0) {
-            fprintf(stderr, "Failure adding string %s\n", String8(value).string());
-            return eidx;
-        }
-    }
-
-    if (configTypeName != NULL) {
-        entry& ent = mEntries.editItemAt(eidx);
-        NOISY(printf("*** adding config type name %s, was %s\n",
-                configTypeName->string(), ent.configTypeName.string()));
-        if (ent.configTypeName.size() <= 0) {
-            ent.configTypeName = *configTypeName;
-        } else if (ent.configTypeName != *configTypeName) {
-            ent.configTypeName = " ";
-        }
-    }
-
-    if (config != NULL) {
-        // Add this to the set of configs associated with the string.
-        entry& ent = mEntries.editItemAt(eidx);
-        size_t addPos;
-        for (addPos=0; addPos<ent.configs.size(); addPos++) {
-            int cmp = ent.configs.itemAt(addPos).compareLogical(*config);
-            if (cmp >= 0) {
-                if (cmp > 0) {
-                    NOISY(printf("*** inserting config: %s\n", config->toString().string()));
-                    ent.configs.insertAt(*config, addPos);
-                }
-                break;
-            }
-        }
-        if (addPos >= ent.configs.size()) {
-            NOISY(printf("*** adding config: %s\n", config->toString().string()));
-            ent.configs.add(*config);
-        }
-    }
-
-    const bool first = vidx < 0;
-    const bool styled = (pos >= 0 && (size_t)pos < mEntryStyleArray.size()) ?
-        mEntryStyleArray[pos].spans.size() : 0;
-    if (first || styled || !mergeDuplicates) {
-        pos = mEntryArray.add(eidx);
-        if (first) {
-            vidx = mValues.add(value, pos);
-        }
-        entry& ent = mEntries.editItemAt(eidx);
-        ent.indices.add(pos);
-    }
-
-    NOISY(printf("Adding string %s to pool: pos=%d eidx=%d vidx=%d\n",
-            String8(value).string(), pos, eidx, vidx));
-    
-    return pos;
-}
-
-status_t StringPool::addStyleSpan(size_t idx, const String16& name,
-                                  uint32_t start, uint32_t end)
-{
-    entry_style_span span;
-    span.name = name;
-    span.span.firstChar = start;
-    span.span.lastChar = end;
-    return addStyleSpan(idx, span);
-}
-
-status_t StringPool::addStyleSpans(size_t idx, const Vector<entry_style_span>& spans)
-{
-    const size_t N=spans.size();
-    for (size_t i=0; i<N; i++) {
-        status_t err = addStyleSpan(idx, spans[i]);
-        if (err != NO_ERROR) {
-            return err;
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t StringPool::addStyleSpan(size_t idx, const entry_style_span& span)
-{
-    // Place blank entries in the span array up to this index.
-    while (mEntryStyleArray.size() <= idx) {
-        mEntryStyleArray.add();
-    }
-
-    entry_style& style = mEntryStyleArray.editItemAt(idx);
-    style.spans.add(span);
-    mEntries.editItemAt(mEntryArray[idx]).hasStyles = true;
-    return NO_ERROR;
-}
-
-int StringPool::config_sort(void* state, const void* lhs, const void* rhs)
-{
-    StringPool* pool = (StringPool*)state;
-    const entry& lhe = pool->mEntries[pool->mEntryArray[*static_cast<const size_t*>(lhs)]];
-    const entry& rhe = pool->mEntries[pool->mEntryArray[*static_cast<const size_t*>(rhs)]];
-    return lhe.compare(rhe);
-}
-
-void StringPool::sortByConfig()
-{
-    LOG_ALWAYS_FATAL_IF(mOriginalPosToNewPos.size() > 0, "Can't sort string pool after already sorted.");
-
-    const size_t N = mEntryArray.size();
-
-    // This is a vector that starts out with a 1:1 mapping to entries
-    // in the array, which we will sort to come up with the desired order.
-    // At that point it maps from the new position in the array to the
-    // original position the entry appeared.
-    Vector<size_t> newPosToOriginalPos;
-    newPosToOriginalPos.setCapacity(N);
-    for (size_t i=0; i < N; i++) {
-        newPosToOriginalPos.add(i);
-    }
-
-    // Sort the array.
-    NOISY(printf("SORTING STRINGS BY CONFIGURATION...\n"));
-    // Vector::sort uses insertion sort, which is very slow for this data set.
-    // Use quicksort instead because we don't need a stable sort here.
-    qsort_r_compat(newPosToOriginalPos.editArray(), N, sizeof(size_t), this, config_sort);
-    //newPosToOriginalPos.sort(config_sort, this);
-    NOISY(printf("DONE SORTING STRINGS BY CONFIGURATION.\n"));
-
-    // Create the reverse mapping from the original position in the array
-    // to the new position where it appears in the sorted array.  This is
-    // so that clients can re-map any positions they had previously stored.
-    mOriginalPosToNewPos = newPosToOriginalPos;
-    for (size_t i=0; i<N; i++) {
-        mOriginalPosToNewPos.editItemAt(newPosToOriginalPos[i]) = i;
-    }
-
-#if 0
-    SortedVector<entry> entries;
-
-    for (size_t i=0; i<N; i++) {
-        printf("#%d was %d: %s\n", i, newPosToOriginalPos[i],
-                mEntries[mEntryArray[newPosToOriginalPos[i]]].makeConfigsString().string());
-        entries.add(mEntries[mEntryArray[i]]);
-    }
-
-    for (size_t i=0; i<entries.size(); i++) {
-        printf("Sorted config #%d: %s\n", i,
-                entries[i].makeConfigsString().string());
-    }
-#endif
-
-    // Now we rebuild the arrays.
-    Vector<entry> newEntries;
-    Vector<size_t> newEntryArray;
-    Vector<entry_style> newEntryStyleArray;
-    DefaultKeyedVector<size_t, size_t> origOffsetToNewOffset;
-
-    for (size_t i=0; i<N; i++) {
-        // We are filling in new offset 'i'; oldI is where we can find it
-        // in the original data structure.
-        size_t oldI = newPosToOriginalPos[i];
-        // This is the actual entry associated with the old offset.
-        const entry& oldEnt = mEntries[mEntryArray[oldI]];
-        // This is the same entry the last time we added it to the
-        // new entry array, if any.
-        ssize_t newIndexOfOffset = origOffsetToNewOffset.indexOfKey(oldI);
-        size_t newOffset;
-        if (newIndexOfOffset < 0) {
-            // This is the first time we have seen the entry, so add
-            // it.
-            newOffset = newEntries.add(oldEnt);
-            newEntries.editItemAt(newOffset).indices.clear();
-        } else {
-            // We have seen this entry before, use the existing one
-            // instead of adding it again.
-            newOffset = origOffsetToNewOffset.valueAt(newIndexOfOffset);
-        }
-        // Update the indices to include this new position.
-        newEntries.editItemAt(newOffset).indices.add(i);
-        // And add the offset of the entry to the new entry array.
-        newEntryArray.add(newOffset);
-        // Add any old style to the new style array.
-        if (mEntryStyleArray.size() > 0) {
-            if (oldI < mEntryStyleArray.size()) {
-                newEntryStyleArray.add(mEntryStyleArray[oldI]);
-            } else {
-                newEntryStyleArray.add(entry_style());
-            }
-        }
-    }
-
-    // Now trim any entries at the end of the new style array that are
-    // not needed.
-    for (ssize_t i=newEntryStyleArray.size()-1; i>=0; i--) {
-        const entry_style& style = newEntryStyleArray[i];
-        if (style.spans.size() > 0) {
-            // That's it.
-            break;
-        }
-        // This one is not needed; remove.
-        newEntryStyleArray.removeAt(i);
-    }
-
-    // All done, install the new data structures and upate mValues with
-    // the new positions.
-    mEntries = newEntries;
-    mEntryArray = newEntryArray;
-    mEntryStyleArray = newEntryStyleArray;
-    mValues.clear();
-    for (size_t i=0; i<mEntries.size(); i++) {
-        const entry& ent = mEntries[i];
-        mValues.add(ent.value, ent.indices[0]);
-    }
-
-#if 0
-    printf("FINAL SORTED STRING CONFIGS:\n");
-    for (size_t i=0; i<mEntries.size(); i++) {
-        const entry& ent = mEntries[i];
-        printf("#" ZD " %s: %s\n", (ZD_TYPE)i, ent.makeConfigsString().string(),
-                String8(ent.value).string());
-    }
-#endif
-}
-
-sp<AaptFile> StringPool::createStringBlock()
-{
-    sp<AaptFile> pool = new AaptFile(String8(), AaptGroupEntry(),
-                                     String8());
-    status_t err = writeStringBlock(pool);
-    return err == NO_ERROR ? pool : NULL;
-}
-
-#define ENCODE_LENGTH(str, chrsz, strSize) \
-{ \
-    size_t maxMask = 1 << ((chrsz*8)-1); \
-    size_t maxSize = maxMask-1; \
-    if (strSize > maxSize) { \
-        *str++ = maxMask | ((strSize>>(chrsz*8))&maxSize); \
-    } \
-    *str++ = strSize; \
-}
-
-status_t StringPool::writeStringBlock(const sp<AaptFile>& pool)
-{
-    // Allow appending.  Sorry this is a little wacky.
-    if (pool->getSize() > 0) {
-        sp<AaptFile> block = createStringBlock();
-        if (block == NULL) {
-            return UNKNOWN_ERROR;
-        }
-        ssize_t res = pool->writeData(block->getData(), block->getSize());
-        return (res >= 0) ? (status_t)NO_ERROR : res;
-    }
-
-    // First we need to add all style span names to the string pool.
-    // We do this now (instead of when the span is added) so that these
-    // will appear at the end of the pool, not disrupting the order
-    // our client placed their own strings in it.
-    
-    const size_t STYLES = mEntryStyleArray.size();
-    size_t i;
-
-    for (i=0; i<STYLES; i++) {
-        entry_style& style = mEntryStyleArray.editItemAt(i);
-        const size_t N = style.spans.size();
-        for (size_t i=0; i<N; i++) {
-            entry_style_span& span = style.spans.editItemAt(i);
-            ssize_t idx = add(span.name, true);
-            if (idx < 0) {
-                fprintf(stderr, "Error adding span for style tag '%s'\n",
-                        String8(span.name).string());
-                return idx;
-            }
-            span.span.name.index = (uint32_t)idx;
-        }
-    }
-
-    const size_t ENTRIES = mEntryArray.size();
-
-    // Now build the pool of unique strings.
-
-    const size_t STRINGS = mEntries.size();
-    const size_t preSize = sizeof(ResStringPool_header)
-                         + (sizeof(uint32_t)*ENTRIES)
-                         + (sizeof(uint32_t)*STYLES);
-    if (pool->editData(preSize) == NULL) {
-        fprintf(stderr, "ERROR: Out of memory for string pool\n");
-        return NO_MEMORY;
-    }
-
-    const size_t charSize = mUTF8 ? sizeof(uint8_t) : sizeof(char16_t);
-
-    size_t strPos = 0;
-    for (i=0; i<STRINGS; i++) {
-        entry& ent = mEntries.editItemAt(i);
-        const size_t strSize = (ent.value.size());
-        const size_t lenSize = strSize > (size_t)(1<<((charSize*8)-1))-1 ?
-            charSize*2 : charSize;
-
-        String8 encStr;
-        if (mUTF8) {
-            encStr = String8(ent.value);
-        }
-
-        const size_t encSize = mUTF8 ? encStr.size() : 0;
-        const size_t encLenSize = mUTF8 ?
-            (encSize > (size_t)(1<<((charSize*8)-1))-1 ?
-                charSize*2 : charSize) : 0;
-
-        ent.offset = strPos;
-
-        const size_t totalSize = lenSize + encLenSize +
-            ((mUTF8 ? encSize : strSize)+1)*charSize;
-
-        void* dat = (void*)pool->editData(preSize + strPos + totalSize);
-        if (dat == NULL) {
-            fprintf(stderr, "ERROR: Out of memory for string pool\n");
-            return NO_MEMORY;
-        }
-        dat = (uint8_t*)dat + preSize + strPos;
-        if (mUTF8) {
-            uint8_t* strings = (uint8_t*)dat;
-
-            ENCODE_LENGTH(strings, sizeof(uint8_t), strSize)
-
-            ENCODE_LENGTH(strings, sizeof(uint8_t), encSize)
-
-            strncpy((char*)strings, encStr, encSize+1);
-        } else {
-            uint16_t* strings = (uint16_t*)dat;
-
-            ENCODE_LENGTH(strings, sizeof(uint16_t), strSize)
-
-            strcpy16_htod(strings, ent.value);
-        }
-
-        strPos += totalSize;
-    }
-
-    // Pad ending string position up to a uint32_t boundary.
-
-    if (strPos&0x3) {
-        size_t padPos = ((strPos+3)&~0x3);
-        uint8_t* dat = (uint8_t*)pool->editData(preSize + padPos);
-        if (dat == NULL) {
-            fprintf(stderr, "ERROR: Out of memory padding string pool\n");
-            return NO_MEMORY;
-        }
-        memset(dat+preSize+strPos, 0, padPos-strPos);
-        strPos = padPos;
-    }
-
-    // Build the pool of style spans.
-
-    size_t styPos = strPos;
-    for (i=0; i<STYLES; i++) {
-        entry_style& ent = mEntryStyleArray.editItemAt(i);
-        const size_t N = ent.spans.size();
-        const size_t totalSize = (N*sizeof(ResStringPool_span))
-                               + sizeof(ResStringPool_ref);
-
-        ent.offset = styPos-strPos;
-        uint8_t* dat = (uint8_t*)pool->editData(preSize + styPos + totalSize);
-        if (dat == NULL) {
-            fprintf(stderr, "ERROR: Out of memory for string styles\n");
-            return NO_MEMORY;
-        }
-        ResStringPool_span* span = (ResStringPool_span*)(dat+preSize+styPos);
-        for (size_t i=0; i<N; i++) {
-            span->name.index = htodl(ent.spans[i].span.name.index);
-            span->firstChar = htodl(ent.spans[i].span.firstChar);
-            span->lastChar = htodl(ent.spans[i].span.lastChar);
-            span++;
-        }
-        span->name.index = htodl(ResStringPool_span::END);
-
-        styPos += totalSize;
-    }
-
-    if (STYLES > 0) {
-        // Add full terminator at the end (when reading we validate that
-        // the end of the pool is fully terminated to simplify error
-        // checking).
-        size_t extra = sizeof(ResStringPool_span)-sizeof(ResStringPool_ref);
-        uint8_t* dat = (uint8_t*)pool->editData(preSize + styPos + extra);
-        if (dat == NULL) {
-            fprintf(stderr, "ERROR: Out of memory for string styles\n");
-            return NO_MEMORY;
-        }
-        uint32_t* p = (uint32_t*)(dat+preSize+styPos);
-        while (extra > 0) {
-            *p++ = htodl(ResStringPool_span::END);
-            extra -= sizeof(uint32_t);
-        }
-        styPos += extra;
-    }
-
-    // Write header.
-
-    ResStringPool_header* header =
-        (ResStringPool_header*)pool->padData(sizeof(uint32_t));
-    if (header == NULL) {
-        fprintf(stderr, "ERROR: Out of memory for string pool\n");
-        return NO_MEMORY;
-    }
-    memset(header, 0, sizeof(*header));
-    header->header.type = htods(RES_STRING_POOL_TYPE);
-    header->header.headerSize = htods(sizeof(*header));
-    header->header.size = htodl(pool->getSize());
-    header->stringCount = htodl(ENTRIES);
-    header->styleCount = htodl(STYLES);
-    if (mUTF8) {
-        header->flags |= htodl(ResStringPool_header::UTF8_FLAG);
-    }
-    header->stringsStart = htodl(preSize);
-    header->stylesStart = htodl(STYLES > 0 ? (preSize+strPos) : 0);
-
-    // Write string index array.
-
-    uint32_t* index = (uint32_t*)(header+1);
-    for (i=0; i<ENTRIES; i++) {
-        entry& ent = mEntries.editItemAt(mEntryArray[i]);
-        *index++ = htodl(ent.offset);
-        NOISY(printf("Writing entry #%d: \"%s\" ent=%d off=%d\n", i,
-                String8(ent.value).string(),
-                mEntryArray[i], ent.offset));
-    }
-
-    // Write style index array.
-
-    for (i=0; i<STYLES; i++) {
-        *index++ = htodl(mEntryStyleArray[i].offset);
-    }
-
-    return NO_ERROR;
-}
-
-ssize_t StringPool::offsetForString(const String16& val) const
-{
-    const Vector<size_t>* indices = offsetsForString(val);
-    ssize_t res = indices != NULL && indices->size() > 0 ? indices->itemAt(0) : -1;
-    NOISY(printf("Offset for string %s: %d (%s)\n", String8(val).string(), res,
-            res >= 0 ? String8(mEntries[mEntryArray[res]].value).string() : String8()));
-    return res;
-}
-
-const Vector<size_t>* StringPool::offsetsForString(const String16& val) const
-{
-    ssize_t pos = mValues.valueFor(val);
-    if (pos < 0) {
-        return NULL;
-    }
-    return &mEntries[mEntryArray[pos]].indices;
-}
diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h
deleted file mode 100644
index 1b3abfd..0000000
--- a/tools/aapt/StringPool.h
+++ /dev/null
@@ -1,183 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Build resource files from raw assets.
-//
-
-#ifndef STRING_POOL_H
-#define STRING_POOL_H
-
-#include "Main.h"
-#include "AaptAssets.h"
-
-#include <androidfw/ResourceTypes.h>
-#include <utils/String16.h>
-#include <utils/TypeHelpers.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <libexpat/expat.h>
-
-using namespace android;
-
-#define PRINT_STRING_METRICS 0
-
-void strcpy16_htod(uint16_t* dst, const uint16_t* src);
-
-void printStringPool(const ResStringPool* pool);
-
-/**
- * The StringPool class is used as an intermediate representation for
- * generating the string pool resource data structure that can be parsed with
- * ResStringPool in include/utils/ResourceTypes.h.
- */
-class StringPool
-{
-public:
-    struct entry {
-        entry() : offset(0) { }
-        entry(const String16& _value) : value(_value), offset(0), hasStyles(false) { }
-        entry(const entry& o) : value(o.value), offset(o.offset),
-                hasStyles(o.hasStyles), indices(o.indices),
-                configTypeName(o.configTypeName), configs(o.configs) { }
-
-        String16 value;
-        size_t offset;
-        bool hasStyles;
-        Vector<size_t> indices;
-        String8 configTypeName;
-        Vector<ResTable_config> configs;
-
-        String8 makeConfigsString() const;
-
-        int compare(const entry& o) const;
-
-        inline bool operator<(const entry& o) const { return compare(o) < 0; }
-        inline bool operator<=(const entry& o) const { return compare(o) <= 0; }
-        inline bool operator==(const entry& o) const { return compare(o) == 0; }
-        inline bool operator!=(const entry& o) const { return compare(o) != 0; }
-        inline bool operator>=(const entry& o) const { return compare(o) >= 0; }
-        inline bool operator>(const entry& o) const { return compare(o) > 0; }
-    };
-
-    struct entry_style_span {
-        String16 name;
-        ResStringPool_span span;
-    };
-
-    struct entry_style {
-        entry_style() : offset(0) { }
-
-        entry_style(const entry_style& o) : offset(o.offset), spans(o.spans) { }
-
-        size_t offset;
-        Vector<entry_style_span> spans;
-    };
-
-    /**
-     * If 'utf8' is true, strings will be encoded with UTF-8 instead of
-     * left in Java's native UTF-16.
-     */
-    explicit StringPool(bool utf8 = false);
-
-    /**
-     * Add a new string to the pool.  If mergeDuplicates is true, thenif
-     * the string already exists the existing entry for it will be used;
-     * otherwise, or if the value doesn't already exist, a new entry is
-     * created.
-     *
-     * Returns the index in the entry array of the new string entry.
-     */
-    ssize_t add(const String16& value, bool mergeDuplicates = false,
-            const String8* configTypeName = NULL, const ResTable_config* config = NULL);
-
-    ssize_t add(const String16& value, const Vector<entry_style_span>& spans,
-            const String8* configTypeName = NULL, const ResTable_config* config = NULL);
-
-    status_t addStyleSpan(size_t idx, const String16& name,
-                          uint32_t start, uint32_t end);
-    status_t addStyleSpans(size_t idx, const Vector<entry_style_span>& spans);
-    status_t addStyleSpan(size_t idx, const entry_style_span& span);
-
-    // Sort the contents of the string block by the configuration associated
-    // with each item.  After doing this you can use mapOriginalPosToNewPos()
-    // to find out the new position given the position originally returned by
-    // add().
-    void sortByConfig();
-
-    // For use after sortByConfig() to map from the original position of
-    // a string to its new sorted position.
-    size_t mapOriginalPosToNewPos(size_t originalPos) const {
-        return mOriginalPosToNewPos.itemAt(originalPos);
-    }
-
-    sp<AaptFile> createStringBlock();
-
-    status_t writeStringBlock(const sp<AaptFile>& pool);
-
-    /**
-     * Find out an offset in the pool for a particular string.  If the string
-     * pool is sorted, this can not be called until after createStringBlock()
-     * or writeStringBlock() has been called
-     * (which determines the offsets).  In the case of a string that appears
-     * multiple times in the pool, the first offset will be returned.  Returns
-     * -1 if the string does not exist.
-     */
-    ssize_t offsetForString(const String16& val) const;
-
-    /**
-     * Find all of the offsets in the pool for a particular string.  If the
-     * string pool is sorted, this can not be called until after
-     * createStringBlock() or writeStringBlock() has been called
-     * (which determines the offsets).  Returns NULL if the string does not exist.
-     */
-    const Vector<size_t>* offsetsForString(const String16& val) const;
-
-private:
-    static int config_sort(void* state, const void* lhs, const void* rhs);
-
-    const bool                              mUTF8;
-
-    // The following data structures represent the actual structures
-    // that will be generated for the final string pool.
-
-    // Raw array of unique strings, in some arbitrary order.  This is the
-    // actual strings that appear in the final string pool, in the order
-    // that they will be written.
-    Vector<entry>                           mEntries;
-    // Array of indices into mEntries, in the order they were
-    // added to the pool.  This can be different than mEntries
-    // if the same string was added multiple times (it will appear
-    // once in mEntries, with multiple occurrences in this array).
-    // This is the lookup array that will be written for finding
-    // the string for each offset/position in the string pool.
-    Vector<size_t>                          mEntryArray;
-    // Optional style span information associated with each index of
-    // mEntryArray.
-    Vector<entry_style>                     mEntryStyleArray;
-
-    // The following data structures are used for book-keeping as the
-    // string pool is constructed.
-
-    // Unique set of all the strings added to the pool, mapped to
-    // the first index of mEntryArray where the value was added.
-    DefaultKeyedVector<String16, ssize_t>   mValues;
-    // This array maps from the original position a string was placed at
-    // in mEntryArray to its new position after being sorted with sortByConfig().
-    Vector<size_t>                          mOriginalPosToNewPos;
-};
-
-// The entry types are trivially movable because all fields they contain, including
-// the vectors and strings, are trivially movable.
-namespace android {
-    ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry);
-    ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry_style_span);
-    ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry_style);
-};
-
-#endif
-
diff --git a/tools/aapt/WorkQueue.cpp b/tools/aapt/WorkQueue.cpp
deleted file mode 100644
index 24a962f..0000000
--- a/tools/aapt/WorkQueue.cpp
+++ /dev/null
@@ -1,171 +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.
- */
-
-// #define LOG_NDEBUG 0
-#define LOG_TAG "WorkQueue"
-
-#include <utils/Log.h>
-#include "WorkQueue.h"
-
-namespace android {
-
-// --- WorkQueue ---
-
-WorkQueue::WorkQueue(size_t maxThreads, bool canCallJava) :
-        mMaxThreads(maxThreads), mCanCallJava(canCallJava),
-        mCanceled(false), mFinished(false), mIdleThreads(0) {
-}
-
-WorkQueue::~WorkQueue() {
-    if (!cancel()) {
-        finish();
-    }
-}
-
-status_t WorkQueue::schedule(WorkUnit* workUnit, size_t backlog) {
-    AutoMutex _l(mLock);
-
-    if (mFinished || mCanceled) {
-        return INVALID_OPERATION;
-    }
-
-    if (mWorkThreads.size() < mMaxThreads
-            && mIdleThreads < mWorkUnits.size() + 1) {
-        sp<WorkThread> workThread = new WorkThread(this, mCanCallJava);
-        status_t status = workThread->run("WorkQueue::WorkThread");
-        if (status) {
-            return status;
-        }
-        mWorkThreads.add(workThread);
-        mIdleThreads += 1;
-    } else if (backlog) {
-        while (mWorkUnits.size() >= mMaxThreads * backlog) {
-            mWorkDequeuedCondition.wait(mLock);
-            if (mFinished || mCanceled) {
-                return INVALID_OPERATION;
-            }
-        }
-    }
-
-    mWorkUnits.add(workUnit);
-    mWorkChangedCondition.broadcast();
-    return OK;
-}
-
-status_t WorkQueue::cancel() {
-    AutoMutex _l(mLock);
-
-    return cancelLocked();
-}
-
-status_t WorkQueue::cancelLocked() {
-    if (mFinished) {
-        return INVALID_OPERATION;
-    }
-
-    if (!mCanceled) {
-        mCanceled = true;
-
-        size_t count = mWorkUnits.size();
-        for (size_t i = 0; i < count; i++) {
-            delete mWorkUnits.itemAt(i);
-        }
-        mWorkUnits.clear();
-        mWorkChangedCondition.broadcast();
-        mWorkDequeuedCondition.broadcast();
-    }
-    return OK;
-}
-
-status_t WorkQueue::finish() {
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (mFinished) {
-            return INVALID_OPERATION;
-        }
-
-        mFinished = true;
-        mWorkChangedCondition.broadcast();
-    } // release lock
-
-    // It is not possible for the list of work threads to change once the mFinished
-    // flag has been set, so we can access mWorkThreads outside of the lock here.
-    size_t count = mWorkThreads.size();
-    for (size_t i = 0; i < count; i++) {
-        mWorkThreads.itemAt(i)->join();
-    }
-    mWorkThreads.clear();
-    return OK;
-}
-
-bool WorkQueue::threadLoop() {
-    WorkUnit* workUnit;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        for (;;) {
-            if (mCanceled) {
-                return false;
-            }
-
-            if (!mWorkUnits.isEmpty()) {
-                workUnit = mWorkUnits.itemAt(0);
-                mWorkUnits.removeAt(0);
-                mIdleThreads -= 1;
-                mWorkDequeuedCondition.broadcast();
-                break;
-            }
-
-            if (mFinished) {
-                return false;
-            }
-
-            mWorkChangedCondition.wait(mLock);
-        }
-    } // release lock
-
-    bool shouldContinue = workUnit->run();
-    delete workUnit;
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        mIdleThreads += 1;
-
-        if (!shouldContinue) {
-            cancelLocked();
-            return false;
-        }
-    } // release lock
-
-    return true;
-}
-
-// --- WorkQueue::WorkThread ---
-
-WorkQueue::WorkThread::WorkThread(WorkQueue* workQueue, bool canCallJava) :
-        Thread(canCallJava), mWorkQueue(workQueue) {
-}
-
-WorkQueue::WorkThread::~WorkThread() {
-}
-
-bool WorkQueue::WorkThread::threadLoop() {
-    return mWorkQueue->threadLoop();
-}
-
-};  // namespace android
diff --git a/tools/aapt/WorkQueue.h b/tools/aapt/WorkQueue.h
deleted file mode 100644
index d38f05d..0000000
--- a/tools/aapt/WorkQueue.h
+++ /dev/null
@@ -1,119 +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.
- */
-
-#ifndef AAPT_WORK_QUEUE_H
-#define AAPT_WORK_QUEUE_H
-
-#include <utils/Errors.h>
-#include <utils/Vector.h>
-#include <utils/threads.h>
-
-namespace android {
-
-/*
- * A threaded work queue.
- *
- * This class is designed to make it easy to run a bunch of isolated work
- * units in parallel, using up to the specified number of threads.
- * To use it, write a loop to post work units to the work queue, then synchronize
- * on the queue at the end.
- */
-class WorkQueue {
-public:
-    class WorkUnit {
-    public:
-        WorkUnit() { }
-        virtual ~WorkUnit() { }
-
-        /*
-         * Runs the work unit.
-         * If the result is 'true' then the work queue continues scheduling work as usual.
-         * If the result is 'false' then the work queue is canceled.
-         */
-        virtual bool run() = 0;
-    };
-
-    /* Creates a work queue with the specified maximum number of work threads. */
-    WorkQueue(size_t maxThreads, bool canCallJava = true);
-
-    /* Destroys the work queue.
-     * Cancels pending work and waits for all remaining threads to complete.
-     */
-    ~WorkQueue();
-
-    /* Posts a work unit to run later.
-     * If the work queue has been canceled or is already finished, returns INVALID_OPERATION
-     * and does not take ownership of the work unit (caller must destroy it itself).
-     * Otherwise, returns OK and takes ownership of the work unit (the work queue will
-     * destroy it automatically).
-     *
-     * For flow control, this method blocks when the size of the pending work queue is more
-     * 'backlog' times the number of threads.  This condition reduces the rate of entry into
-     * the pending work queue and prevents it from growing much more rapidly than the
-     * work threads can actually handle.
-     *
-     * If 'backlog' is 0, then no throttle is applied.
-     */
-    status_t schedule(WorkUnit* workUnit, size_t backlog = 2);
-
-    /* Cancels all pending work.
-     * If the work queue is already finished, returns INVALID_OPERATION.
-     * If the work queue is already canceled, returns OK and does nothing else.
-     * Otherwise, returns OK, discards all pending work units and prevents additional
-     * work units from being scheduled.
-     *
-     * Call finish() after cancel() to wait for all remaining work to complete.
-     */
-    status_t cancel();
-
-    /* Waits for all work to complete.
-     * If the work queue is already finished, returns INVALID_OPERATION.
-     * Otherwise, waits for all work to complete and returns OK.
-     */
-    status_t finish();
-
-private:
-    class WorkThread : public Thread {
-    public:
-        WorkThread(WorkQueue* workQueue, bool canCallJava);
-        virtual ~WorkThread();
-
-    private:
-        virtual bool threadLoop();
-
-        WorkQueue* const mWorkQueue;
-    };
-
-    status_t cancelLocked();
-    bool threadLoop(); // called from each work thread
-
-    const size_t mMaxThreads;
-    const bool mCanCallJava;
-
-    Mutex mLock;
-    Condition mWorkChangedCondition;
-    Condition mWorkDequeuedCondition;
-
-    bool mCanceled;
-    bool mFinished;
-    size_t mIdleThreads;
-    Vector<sp<WorkThread> > mWorkThreads;
-    Vector<WorkUnit*> mWorkUnits;
-};
-
-}; // namespace android
-
-#endif // AAPT_WORK_QUEUE_H
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
deleted file mode 100644
index a663ad5..0000000
--- a/tools/aapt/XMLNode.cpp
+++ /dev/null
@@ -1,1510 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Build resource files from raw assets.
-//
-
-#include "XMLNode.h"
-#include "ResourceTable.h"
-#include "pseudolocalize.h"
-
-#include <utils/ByteOrder.h>
-#include <errno.h>
-#include <string.h>
-
-#ifndef HAVE_MS_C_RUNTIME
-#define O_BINARY 0
-#endif
-
-#define NOISY(x) //x
-#define NOISY_PARSE(x) //x
-
-const char* const RESOURCES_ROOT_NAMESPACE = "http://schemas.android.com/apk/res/";
-const char* const RESOURCES_ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android";
-const char* const RESOURCES_AUTO_PACKAGE_NAMESPACE = "http://schemas.android.com/apk/res-auto";
-const char* const RESOURCES_ROOT_PRV_NAMESPACE = "http://schemas.android.com/apk/prv/res/";
-
-const char* const XLIFF_XMLNS = "urn:oasis:names:tc:xliff:document:1.2";
-const char* const ALLOWED_XLIFF_ELEMENTS[] = {
-        "bpt",
-        "ept",
-        "it",
-        "ph",
-        "g",
-        "bx",
-        "ex",
-        "x"
-    };
-
-bool isWhitespace(const char16_t* str)
-{
-    while (*str != 0 && *str < 128 && isspace(*str)) {
-        str++;
-    }
-    return *str == 0;
-}
-
-static const String16 RESOURCES_PREFIX(RESOURCES_ROOT_NAMESPACE);
-static const String16 RESOURCES_PREFIX_AUTO_PACKAGE(RESOURCES_AUTO_PACKAGE_NAMESPACE);
-static const String16 RESOURCES_PRV_PREFIX(RESOURCES_ROOT_PRV_NAMESPACE);
-static const String16 RESOURCES_TOOLS_NAMESPACE("http://schemas.android.com/tools");
-
-String16 getNamespaceResourcePackage(String16 appPackage, String16 namespaceUri, bool* outIsPublic)
-{
-    //printf("%s starts with %s?\n", String8(namespaceUri).string(),
-    //       String8(RESOURCES_PREFIX).string());
-    size_t prefixSize;
-    bool isPublic = true;
-    if(namespaceUri.startsWith(RESOURCES_PREFIX_AUTO_PACKAGE)) {
-        NOISY(printf("Using default application package: %s -> %s\n", String8(namespaceUri).string(), String8(appPackage).string()));
-        isPublic = true;
-        return appPackage;
-    } else if (namespaceUri.startsWith(RESOURCES_PREFIX)) {
-        prefixSize = RESOURCES_PREFIX.size();
-    } else if (namespaceUri.startsWith(RESOURCES_PRV_PREFIX)) {
-        isPublic = false;
-        prefixSize = RESOURCES_PRV_PREFIX.size();
-    } else {
-        if (outIsPublic) *outIsPublic = isPublic; // = true
-        return String16();
-    }
-
-    //printf("YES!\n");
-    //printf("namespace: %s\n", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).string());
-    if (outIsPublic) *outIsPublic = isPublic;
-    return String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize);
-}
-
-status_t hasSubstitutionErrors(const char* fileName,
-                               ResXMLTree* inXml,
-                               String16 str16)
-{
-    const char16_t* str = str16.string();
-    const char16_t* p = str;
-    const char16_t* end = str + str16.size();
-
-    bool nonpositional = false;
-    int argCount = 0;
-
-    while (p < end) {
-        /*
-         * Look for the start of a Java-style substitution sequence.
-         */
-        if (*p == '%' && p + 1 < end) {
-            p++;
-
-            // A literal percent sign represented by %%
-            if (*p == '%') {
-                p++;
-                continue;
-            }
-
-            argCount++;
-
-            if (*p >= '0' && *p <= '9') {
-                do {
-                    p++;
-                } while (*p >= '0' && *p <= '9');
-                if (*p != '$') {
-                    // This must be a size specification instead of position.
-                    nonpositional = true;
-                }
-            } else if (*p == '<') {
-                // Reusing last argument; bad idea since it can be re-arranged.
-                nonpositional = true;
-                p++;
-
-                // Optionally '$' can be specified at the end.
-                if (p < end && *p == '$') {
-                    p++;
-                }
-            } else {
-                nonpositional = true;
-            }
-
-            // Ignore flags and widths
-            while (p < end && (*p == '-' ||
-                    *p == '#' ||
-                    *p == '+' ||
-                    *p == ' ' ||
-                    *p == ',' ||
-                    *p == '(' ||
-                    (*p >= '0' && *p <= '9'))) {
-                p++;
-            }
-
-            /*
-             * This is a shortcut to detect strings that are going to Time.format()
-             * instead of String.format()
-             *
-             * Comparison of String.format() and Time.format() args:
-             *
-             * String: ABC E GH  ST X abcdefgh  nost x
-             *   Time:    DEFGHKMS W Za  d   hkm  s w yz
-             *
-             * Therefore we know it's definitely Time if we have:
-             *     DFKMWZkmwyz
-             */
-            if (p < end) {
-                switch (*p) {
-                case 'D':
-                case 'F':
-                case 'K':
-                case 'M':
-                case 'W':
-                case 'Z':
-                case 'k':
-                case 'm':
-                case 'w':
-                case 'y':
-                case 'z':
-                    return NO_ERROR;
-                }
-            }
-        }
-
-        p++;
-    }
-
-    /*
-     * If we have more than one substitution in this string and any of them
-     * are not in positional form, give the user an error.
-     */
-    if (argCount > 1 && nonpositional) {
-        SourcePos(String8(fileName), inXml->getLineNumber()).error(
-                "Multiple substitutions specified in non-positional format; "
-                "did you mean to add the formatted=\"false\" attribute?\n");
-        return NOT_ENOUGH_DATA;
-    }
-
-    return NO_ERROR;
-}
-
-status_t parseStyledString(Bundle* bundle,
-                           const char* fileName,
-                           ResXMLTree* inXml,
-                           const String16& endTag,
-                           String16* outString,
-                           Vector<StringPool::entry_style_span>* outSpans,
-                           bool isFormatted,
-                           bool pseudolocalize)
-{
-    Vector<StringPool::entry_style_span> spanStack;
-    String16 curString;
-    String16 rawString;
-    const char* errorMsg;
-    int xliffDepth = 0;
-    bool firstTime = true;
-
-    size_t len;
-    ResXMLTree::event_code_t code;
-    while ((code=inXml->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-
-        if (code == ResXMLTree::TEXT) {
-            String16 text(inXml->getText(&len));
-            if (firstTime && text.size() > 0) {
-                firstTime = false;
-                if (text.string()[0] == '@') {
-                    // If this is a resource reference, don't do the pseudoloc.
-                    pseudolocalize = false;
-                }
-            }
-            if (xliffDepth == 0 && pseudolocalize) {
-                std::string orig(String8(text).string());
-                std::string pseudo = pseudolocalize_string(orig);
-                curString.append(String16(String8(pseudo.c_str())));
-            } else {
-                if (isFormatted && hasSubstitutionErrors(fileName, inXml, text) != NO_ERROR) {
-                    return UNKNOWN_ERROR;
-                } else {
-                    curString.append(text);
-                }
-            }
-        } else if (code == ResXMLTree::START_TAG) {
-            const String16 element16(inXml->getElementName(&len));
-            const String8 element8(element16);
-
-            size_t nslen;
-            const uint16_t* ns = inXml->getElementNamespace(&nslen);
-            if (ns == NULL) {
-                ns = (const uint16_t*)"\0\0";
-                nslen = 0;
-            }
-            const String8 nspace(String16(ns, nslen));
-            if (nspace == XLIFF_XMLNS) {
-                const int N = sizeof(ALLOWED_XLIFF_ELEMENTS)/sizeof(ALLOWED_XLIFF_ELEMENTS[0]);
-                for (int i=0; i<N; i++) {
-                    if (element8 == ALLOWED_XLIFF_ELEMENTS[i]) {
-                        xliffDepth++;
-                        // in this case, treat it like it was just text, in other words, do nothing
-                        // here and silently drop this element
-                        goto moveon;
-                    }
-                }
-                {
-                    SourcePos(String8(fileName), inXml->getLineNumber()).error(
-                            "Found unsupported XLIFF tag <%s>\n",
-                            element8.string());
-                    return UNKNOWN_ERROR;
-                }
-moveon:
-                continue;
-            }
-
-            if (outSpans == NULL) {
-                SourcePos(String8(fileName), inXml->getLineNumber()).error(
-                        "Found style tag <%s> where styles are not allowed\n", element8.string());
-                return UNKNOWN_ERROR;
-            }
-
-            if (!ResTable::collectString(outString, curString.string(),
-                                         curString.size(), false, &errorMsg, true)) {
-                SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n",
-                        errorMsg, String8(curString).string());
-                return UNKNOWN_ERROR;
-            }
-            rawString.append(curString);
-            curString = String16();
-
-            StringPool::entry_style_span span;
-            span.name = element16;
-            for (size_t ai=0; ai<inXml->getAttributeCount(); ai++) {
-                span.name.append(String16(";"));
-                const char16_t* str = inXml->getAttributeName(ai, &len);
-                span.name.append(str, len);
-                span.name.append(String16("="));
-                str = inXml->getAttributeStringValue(ai, &len);
-                span.name.append(str, len);
-            }
-            //printf("Span: %s\n", String8(span.name).string());
-            span.span.firstChar = span.span.lastChar = outString->size();
-            spanStack.push(span);
-
-        } else if (code == ResXMLTree::END_TAG) {
-            size_t nslen;
-            const uint16_t* ns = inXml->getElementNamespace(&nslen);
-            if (ns == NULL) {
-                ns = (const uint16_t*)"\0\0";
-                nslen = 0;
-            }
-            const String8 nspace(String16(ns, nslen));
-            if (nspace == XLIFF_XMLNS) {
-                xliffDepth--;
-                continue;
-            }
-            if (!ResTable::collectString(outString, curString.string(),
-                                         curString.size(), false, &errorMsg, true)) {
-                SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n",
-                        errorMsg, String8(curString).string());
-                return UNKNOWN_ERROR;
-            }
-            rawString.append(curString);
-            curString = String16();
-
-            if (spanStack.size() == 0) {
-                if (strcmp16(inXml->getElementName(&len), endTag.string()) != 0) {
-                    SourcePos(String8(fileName), inXml->getLineNumber()).error(
-                            "Found tag %s where <%s> close is expected\n",
-                            String8(inXml->getElementName(&len)).string(),
-                            String8(endTag).string());
-                    return UNKNOWN_ERROR;
-                }
-                break;
-            }
-            StringPool::entry_style_span span = spanStack.top();
-            String16 spanTag;
-            ssize_t semi = span.name.findFirst(';');
-            if (semi >= 0) {
-                spanTag.setTo(span.name.string(), semi);
-            } else {
-                spanTag.setTo(span.name);
-            }
-            if (strcmp16(inXml->getElementName(&len), spanTag.string()) != 0) {
-                SourcePos(String8(fileName), inXml->getLineNumber()).error(
-                        "Found close tag %s where close tag %s is expected\n",
-                        String8(inXml->getElementName(&len)).string(),
-                        String8(spanTag).string());
-                return UNKNOWN_ERROR;
-            }
-            bool empty = true;
-            if (outString->size() > 0) {
-                span.span.lastChar = outString->size()-1;
-                if (span.span.lastChar >= span.span.firstChar) {
-                    empty = false;
-                    outSpans->add(span);
-                }
-            }
-            spanStack.pop();
-
-            /*
-             * This warning seems to be just an irritation to most people,
-             * since it is typically introduced by translators who then never
-             * see the warning.
-             */
-            if (0 && empty) {
-                fprintf(stderr, "%s:%d: warning: empty '%s' span found in text '%s'\n",
-                        fileName, inXml->getLineNumber(),
-                        String8(spanTag).string(), String8(*outString).string());
-
-            }
-        } else if (code == ResXMLTree::START_NAMESPACE) {
-            // nothing
-        }
-    }
-
-    if (code == ResXMLTree::BAD_DOCUMENT) {
-            SourcePos(String8(fileName), inXml->getLineNumber()).error(
-                    "Error parsing XML\n");
-    }
-
-    if (outSpans != NULL && outSpans->size() > 0) {
-        if (curString.size() > 0) {
-            if (!ResTable::collectString(outString, curString.string(),
-                                         curString.size(), false, &errorMsg, true)) {
-                SourcePos(String8(fileName), inXml->getLineNumber()).error(
-                        "%s (in %s)\n",
-                        errorMsg, String8(curString).string());
-                return UNKNOWN_ERROR;
-            }
-        }
-    } else {
-        // There is no style information, so string processing will happen
-        // later as part of the overall type conversion.  Return to the
-        // client the raw unprocessed text.
-        rawString.append(curString);
-        outString->setTo(rawString);
-    }
-
-    return NO_ERROR;
-}
-
-struct namespace_entry {
-    String8 prefix;
-    String8 uri;
-};
-
-static String8 make_prefix(int depth)
-{
-    String8 prefix;
-    int i;
-    for (i=0; i<depth; i++) {
-        prefix.append("  ");
-    }
-    return prefix;
-}
-
-static String8 build_namespace(const Vector<namespace_entry>& namespaces,
-        const uint16_t* ns)
-{
-    String8 str;
-    if (ns != NULL) {
-        str = String8(ns);
-        const size_t N = namespaces.size();
-        for (size_t i=0; i<N; i++) {
-            const namespace_entry& ne = namespaces.itemAt(i);
-            if (ne.uri == str) {
-                str = ne.prefix;
-                break;
-            }
-        }
-        str.append(":");
-    }
-    return str;
-}
-
-void printXMLBlock(ResXMLTree* block)
-{
-    block->restart();
-
-    Vector<namespace_entry> namespaces;
-    
-    ResXMLTree::event_code_t code;
-    int depth = 0;
-    while ((code=block->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
-        String8 prefix = make_prefix(depth);
-        int i;
-        if (code == ResXMLTree::START_TAG) {
-            size_t len;
-            const uint16_t* ns16 = block->getElementNamespace(&len);
-            String8 elemNs = build_namespace(namespaces, ns16);
-            const uint16_t* com16 = block->getComment(&len);
-            if (com16) {
-                printf("%s <!-- %s -->\n", prefix.string(), String8(com16).string());
-            }
-            printf("%sE: %s%s (line=%d)\n", prefix.string(), elemNs.string(),
-                   String8(block->getElementName(&len)).string(),
-                   block->getLineNumber());
-            int N = block->getAttributeCount();
-            depth++;
-            prefix = make_prefix(depth);
-            for (i=0; i<N; i++) {
-                uint32_t res = block->getAttributeNameResID(i);
-                ns16 = block->getAttributeNamespace(i, &len);
-                String8 ns = build_namespace(namespaces, ns16);
-                String8 name(block->getAttributeName(i, &len));
-                printf("%sA: ", prefix.string());
-                if (res) {
-                    printf("%s%s(0x%08x)", ns.string(), name.string(), res);
-                } else {
-                    printf("%s%s", ns.string(), name.string());
-                }
-                Res_value value;
-                block->getAttributeValue(i, &value);
-                if (value.dataType == Res_value::TYPE_NULL) {
-                    printf("=(null)");
-                } else if (value.dataType == Res_value::TYPE_REFERENCE) {
-                    printf("=@0x%x", (int)value.data);
-                } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) {
-                    printf("=?0x%x", (int)value.data);
-                } else if (value.dataType == Res_value::TYPE_STRING) {
-                    printf("=\"%s\"",
-                            ResTable::normalizeForOutput(String8(block->getAttributeStringValue(i,
-                                        &len)).string()).string());
-                } else {
-                    printf("=(type 0x%x)0x%x", (int)value.dataType, (int)value.data);
-                }
-                const char16_t* val = block->getAttributeStringValue(i, &len);
-                if (val != NULL) {
-                    printf(" (Raw: \"%s\")", ResTable::normalizeForOutput(String8(val).string()).
-                            string());
-                }
-                printf("\n");
-            }
-        } else if (code == ResXMLTree::END_TAG) {
-            depth--;
-        } else if (code == ResXMLTree::START_NAMESPACE) {
-            namespace_entry ns;
-            size_t len;
-            const uint16_t* prefix16 = block->getNamespacePrefix(&len);
-            if (prefix16) {
-                ns.prefix = String8(prefix16);
-            } else {
-                ns.prefix = "<DEF>";
-            }
-            ns.uri = String8(block->getNamespaceUri(&len));
-            namespaces.push(ns);
-            printf("%sN: %s=%s\n", prefix.string(), ns.prefix.string(),
-                    ns.uri.string());
-            depth++;
-        } else if (code == ResXMLTree::END_NAMESPACE) {
-            depth--;
-            const namespace_entry& ns = namespaces.top();
-            size_t len;
-            const uint16_t* prefix16 = block->getNamespacePrefix(&len);
-            String8 pr;
-            if (prefix16) {
-                pr = String8(prefix16);
-            } else {
-                pr = "<DEF>";
-            }
-            if (ns.prefix != pr) {
-                prefix = make_prefix(depth);
-                printf("%s*** BAD END NS PREFIX: found=%s, expected=%s\n",
-                        prefix.string(), pr.string(), ns.prefix.string());
-            }
-            String8 uri = String8(block->getNamespaceUri(&len));
-            if (ns.uri != uri) {
-                prefix = make_prefix(depth);
-                printf("%s *** BAD END NS URI: found=%s, expected=%s\n",
-                        prefix.string(), uri.string(), ns.uri.string());
-            }
-            namespaces.pop();
-        } else if (code == ResXMLTree::TEXT) {
-            size_t len;
-            printf("%sC: \"%s\"\n", prefix.string(),
-                    ResTable::normalizeForOutput(String8(block->getText(&len)).string()).string());
-        }
-    }
-
-    block->restart();
-}
-
-status_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree,
-                          bool stripAll, bool keepComments,
-                          const char** cDataTags)
-{
-    sp<XMLNode> root = XMLNode::parse(file);
-    if (root == NULL) {
-        return UNKNOWN_ERROR;
-    }
-    root->removeWhitespace(stripAll, cDataTags);
-
-    NOISY(printf("Input XML from %s:\n", (const char*)file->getPrintableSource()));
-    NOISY(root->print());
-    sp<AaptFile> rsc = new AaptFile(String8(), AaptGroupEntry(), String8());
-    status_t err = root->flatten(rsc, !keepComments, false);
-    if (err != NO_ERROR) {
-        return err;
-    }
-    err = outTree->setTo(rsc->getData(), rsc->getSize(), true);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    NOISY(printf("Output XML:\n"));
-    NOISY(printXMLBlock(outTree));
-
-    return NO_ERROR;
-}
-
-sp<XMLNode> XMLNode::parse(const sp<AaptFile>& file)
-{
-    char buf[16384];
-    int fd = open(file->getSourceFile().string(), O_RDONLY | O_BINARY);
-    if (fd < 0) {
-        SourcePos(file->getSourceFile(), -1).error("Unable to open file for read: %s",
-                strerror(errno));
-        return NULL;
-    }
-
-    XML_Parser parser = XML_ParserCreateNS(NULL, 1);
-    ParseState state;
-    state.filename = file->getPrintableSource();
-    state.parser = parser;
-    XML_SetUserData(parser, &state);
-    XML_SetElementHandler(parser, startElement, endElement);
-    XML_SetNamespaceDeclHandler(parser, startNamespace, endNamespace);
-    XML_SetCharacterDataHandler(parser, characterData);
-    XML_SetCommentHandler(parser, commentData);
-
-    ssize_t len;
-    bool done;
-    do {
-        len = read(fd, buf, sizeof(buf));
-        done = len < (ssize_t)sizeof(buf);
-        if (len < 0) {
-            SourcePos(file->getSourceFile(), -1).error("Error reading file: %s\n", strerror(errno));
-            close(fd);
-            return NULL;
-        }
-        if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) {
-            SourcePos(file->getSourceFile(), (int)XML_GetCurrentLineNumber(parser)).error(
-                    "Error parsing XML: %s\n", XML_ErrorString(XML_GetErrorCode(parser)));
-            close(fd);
-            return NULL;
-        }
-    } while (!done);
-
-    XML_ParserFree(parser);
-    if (state.root == NULL) {
-        SourcePos(file->getSourceFile(), -1).error("No XML data generated when parsing");
-    }
-    close(fd);
-    return state.root;
-}
-
-XMLNode::XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace)
-    : mNextAttributeIndex(0x80000000)
-    , mFilename(filename)
-    , mStartLineNumber(0)
-    , mEndLineNumber(0)
-    , mUTF8(false)
-{
-    if (isNamespace) {
-        mNamespacePrefix = s1;
-        mNamespaceUri = s2;
-    } else {
-        mNamespaceUri = s1;
-        mElementName = s2;
-    }
-}
-
-XMLNode::XMLNode(const String8& filename)
-    : mFilename(filename)
-{
-    memset(&mCharsValue, 0, sizeof(mCharsValue));
-}
-
-XMLNode::type XMLNode::getType() const
-{
-    if (mElementName.size() != 0) {
-        return TYPE_ELEMENT;
-    }
-    if (mNamespaceUri.size() != 0) {
-        return TYPE_NAMESPACE;
-    }
-    return TYPE_CDATA;
-}
-
-const String16& XMLNode::getNamespacePrefix() const
-{
-    return mNamespacePrefix;
-}
-
-const String16& XMLNode::getNamespaceUri() const
-{
-    return mNamespaceUri;
-}
-
-const String16& XMLNode::getElementNamespace() const
-{
-    return mNamespaceUri;
-}
-
-const String16& XMLNode::getElementName() const
-{
-    return mElementName;
-}
-
-const Vector<sp<XMLNode> >& XMLNode::getChildren() const
-{
-    return mChildren;
-}
-
-const String8& XMLNode::getFilename() const
-{
-    return mFilename;
-}
-    
-const Vector<XMLNode::attribute_entry>&
-    XMLNode::getAttributes() const
-{
-    return mAttributes;
-}
-
-const XMLNode::attribute_entry* XMLNode::getAttribute(const String16& ns,
-        const String16& name) const
-{
-    for (size_t i=0; i<mAttributes.size(); i++) {
-        const attribute_entry& ae(mAttributes.itemAt(i));
-        if (ae.ns == ns && ae.name == name) {
-            return &ae;
-        }
-    }
-    
-    return NULL;
-}
-
-XMLNode::attribute_entry* XMLNode::editAttribute(const String16& ns,
-        const String16& name)
-{
-    for (size_t i=0; i<mAttributes.size(); i++) {
-        attribute_entry * ae = &mAttributes.editItemAt(i);
-        if (ae->ns == ns && ae->name == name) {
-            return ae;
-        }
-    }
-
-    return NULL;
-}
-
-const String16& XMLNode::getCData() const
-{
-    return mChars;
-}
-
-const String16& XMLNode::getComment() const
-{
-    return mComment;
-}
-
-int32_t XMLNode::getStartLineNumber() const
-{
-    return mStartLineNumber;
-}
-
-int32_t XMLNode::getEndLineNumber() const
-{
-    return mEndLineNumber;
-}
-
-sp<XMLNode> XMLNode::searchElement(const String16& tagNamespace, const String16& tagName)
-{
-    if (getType() == XMLNode::TYPE_ELEMENT
-            && mNamespaceUri == tagNamespace
-            && mElementName == tagName) {
-        return this;
-    }
-    
-    for (size_t i=0; i<mChildren.size(); i++) {
-        sp<XMLNode> found = mChildren.itemAt(i)->searchElement(tagNamespace, tagName);
-        if (found != NULL) {
-            return found;
-        }
-    }
-    
-    return NULL;
-}
-
-sp<XMLNode> XMLNode::getChildElement(const String16& tagNamespace, const String16& tagName)
-{
-    for (size_t i=0; i<mChildren.size(); i++) {
-        sp<XMLNode> child = mChildren.itemAt(i);
-        if (child->getType() == XMLNode::TYPE_ELEMENT
-                && child->mNamespaceUri == tagNamespace
-                && child->mElementName == tagName) {
-            return child;
-        }
-    }
-    
-    return NULL;
-}
-
-status_t XMLNode::addChild(const sp<XMLNode>& child)
-{
-    if (getType() == TYPE_CDATA) {
-        SourcePos(mFilename, child->getStartLineNumber()).error("Child to CDATA node.");
-        return UNKNOWN_ERROR;
-    }
-    //printf("Adding child %p to parent %p\n", child.get(), this);
-    mChildren.add(child);
-    return NO_ERROR;
-}
-
-status_t XMLNode::insertChildAt(const sp<XMLNode>& child, size_t index)
-{
-    if (getType() == TYPE_CDATA) {
-        SourcePos(mFilename, child->getStartLineNumber()).error("Child to CDATA node.");
-        return UNKNOWN_ERROR;
-    }
-    //printf("Adding child %p to parent %p\n", child.get(), this);
-    mChildren.insertAt(child, index);
-    return NO_ERROR;
-}
-
-status_t XMLNode::addAttribute(const String16& ns, const String16& name,
-                               const String16& value)
-{
-    if (getType() == TYPE_CDATA) {
-        SourcePos(mFilename, getStartLineNumber()).error("Child to CDATA node.");
-        return UNKNOWN_ERROR;
-    }
-
-    if (ns != RESOURCES_TOOLS_NAMESPACE) {
-        attribute_entry e;
-        e.index = mNextAttributeIndex++;
-        e.ns = ns;
-        e.name = name;
-        e.string = value;
-        mAttributes.add(e);
-        mAttributeOrder.add(e.index, mAttributes.size()-1);
-    }
-    return NO_ERROR;
-}
-
-void XMLNode::setAttributeResID(size_t attrIdx, uint32_t resId)
-{
-    attribute_entry& e = mAttributes.editItemAt(attrIdx);
-    if (e.nameResId) {
-        mAttributeOrder.removeItem(e.nameResId);
-    } else {
-        mAttributeOrder.removeItem(e.index);
-    }
-    NOISY(printf("Elem %s %s=\"%s\": set res id = 0x%08x\n",
-            String8(getElementName()).string(),
-            String8(mAttributes.itemAt(attrIdx).name).string(),
-            String8(mAttributes.itemAt(attrIdx).string).string(),
-            resId));
-    mAttributes.editItemAt(attrIdx).nameResId = resId;
-    mAttributeOrder.add(resId, attrIdx);
-}
-
-status_t XMLNode::appendChars(const String16& chars)
-{
-    if (getType() != TYPE_CDATA) {
-        SourcePos(mFilename, getStartLineNumber()).error("Adding characters to element node.");
-        return UNKNOWN_ERROR;
-    }
-    mChars.append(chars);
-    return NO_ERROR;
-}
-
-status_t XMLNode::appendComment(const String16& comment)
-{
-    if (mComment.size() > 0) {
-        mComment.append(String16("\n"));
-    }
-    mComment.append(comment);
-    return NO_ERROR;
-}
-
-void XMLNode::setStartLineNumber(int32_t line)
-{
-    mStartLineNumber = line;
-}
-
-void XMLNode::setEndLineNumber(int32_t line)
-{
-    mEndLineNumber = line;
-}
-
-void XMLNode::removeWhitespace(bool stripAll, const char** cDataTags)
-{
-    //printf("Removing whitespace in %s\n", String8(mElementName).string());
-    size_t N = mChildren.size();
-    if (cDataTags) {
-        String8 tag(mElementName);
-        const char** p = cDataTags;
-        while (*p) {
-            if (tag == *p) {
-                stripAll = false;
-                break;
-            }
-        }
-    }
-    for (size_t i=0; i<N; i++) {
-        sp<XMLNode> node = mChildren.itemAt(i);
-        if (node->getType() == TYPE_CDATA) {
-            // This is a CDATA node...
-            const char16_t* p = node->mChars.string();
-            while (*p != 0 && *p < 128 && isspace(*p)) {
-                p++;
-            }
-            //printf("Space ends at %d in \"%s\"\n",
-            //       (int)(p-node->mChars.string()),
-            //       String8(node->mChars).string());
-            if (*p == 0) {
-                if (stripAll) {
-                    // Remove this node!
-                    mChildren.removeAt(i);
-                    N--;
-                    i--;
-                } else {
-                    node->mChars = String16(" ");
-                }
-            } else {
-                // Compact leading/trailing whitespace.
-                const char16_t* e = node->mChars.string()+node->mChars.size()-1;
-                while (e > p && *e < 128 && isspace(*e)) {
-                    e--;
-                }
-                if (p > node->mChars.string()) {
-                    p--;
-                }
-                if (e < (node->mChars.string()+node->mChars.size()-1)) {
-                    e++;
-                }
-                if (p > node->mChars.string() ||
-                    e < (node->mChars.string()+node->mChars.size()-1)) {
-                    String16 tmp(p, e-p+1);
-                    node->mChars = tmp;
-                }
-            }
-        } else {
-            node->removeWhitespace(stripAll, cDataTags);
-        }
-    }
-}
-
-status_t XMLNode::parseValues(const sp<AaptAssets>& assets,
-                              ResourceTable* table)
-{
-    bool hasErrors = false;
-    
-    if (getType() == TYPE_ELEMENT) {
-        const size_t N = mAttributes.size();
-        String16 defPackage(assets->getPackage());
-        for (size_t i=0; i<N; i++) {
-            attribute_entry& e = mAttributes.editItemAt(i);
-            AccessorCookie ac(SourcePos(mFilename, getStartLineNumber()), String8(e.name),
-                    String8(e.string));
-            table->setCurrentXmlPos(SourcePos(mFilename, getStartLineNumber()));
-            if (!assets->getIncludedResources()
-                    .stringToValue(&e.value, &e.string,
-                                  e.string.string(), e.string.size(), true, true,
-                                  e.nameResId, NULL, &defPackage, table, &ac)) {
-                hasErrors = true;
-            }
-            NOISY(printf("Attr %s: type=0x%x, str=%s\n",
-                   String8(e.name).string(), e.value.dataType,
-                   String8(e.string).string()));
-        }
-    }
-    const size_t N = mChildren.size();
-    for (size_t i=0; i<N; i++) {
-        status_t err = mChildren.itemAt(i)->parseValues(assets, table);
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
-}
-
-status_t XMLNode::assignResourceIds(const sp<AaptAssets>& assets,
-                                    const ResourceTable* table)
-{
-    bool hasErrors = false;
-    
-    if (getType() == TYPE_ELEMENT) {
-        String16 attr("attr");
-        const char* errorMsg;
-        const size_t N = mAttributes.size();
-        for (size_t i=0; i<N; i++) {
-            const attribute_entry& e = mAttributes.itemAt(i);
-            if (e.ns.size() <= 0) continue;
-            bool nsIsPublic;
-            String16 pkg(getNamespaceResourcePackage(String16(assets->getPackage()), e.ns, &nsIsPublic));
-            NOISY(printf("Elem %s %s=\"%s\": namespace(%s) %s ===> %s\n",
-                    String8(getElementName()).string(),
-                    String8(e.name).string(),
-                    String8(e.string).string(),
-                    String8(e.ns).string(),
-                    (nsIsPublic) ? "public" : "private",
-                    String8(pkg).string()));
-            if (pkg.size() <= 0) continue;
-            uint32_t res = table != NULL
-                ? table->getResId(e.name, &attr, &pkg, &errorMsg, nsIsPublic)
-                : assets->getIncludedResources().
-                    identifierForName(e.name.string(), e.name.size(),
-                                      attr.string(), attr.size(),
-                                      pkg.string(), pkg.size());
-            if (res != 0) {
-                NOISY(printf("XML attribute name %s: resid=0x%08x\n",
-                             String8(e.name).string(), res));
-                setAttributeResID(i, res);
-            } else {
-                SourcePos(mFilename, getStartLineNumber()).error(
-                        "No resource identifier found for attribute '%s' in package '%s'\n",
-                        String8(e.name).string(), String8(pkg).string());
-                hasErrors = true;
-            }
-        }
-    }
-    const size_t N = mChildren.size();
-    for (size_t i=0; i<N; i++) {
-        status_t err = mChildren.itemAt(i)->assignResourceIds(assets, table);
-        if (err < NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
-    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
-}
-
-status_t XMLNode::flatten(const sp<AaptFile>& dest,
-        bool stripComments, bool stripRawValues) const
-{
-    StringPool strings(mUTF8);
-    Vector<uint32_t> resids;
-    
-    // First collect just the strings for attribute names that have a
-    // resource ID assigned to them.  This ensures that the resource ID
-    // array is compact, and makes it easier to deal with attribute names
-    // in different namespaces (and thus with different resource IDs).
-    collect_resid_strings(&strings, &resids);
-
-    // Next collect all remainibng strings.
-    collect_strings(&strings, &resids, stripComments, stripRawValues);
-
-#if 0  // No longer compiles
-    NOISY(printf("Found strings:\n");
-        const size_t N = strings.size();
-        for (size_t i=0; i<N; i++) {
-            printf("%s\n", String8(strings.entryAt(i).string).string());
-        }
-    );
-#endif    
-
-    sp<AaptFile> stringPool = strings.createStringBlock();
-    NOISY(aout << "String pool:"
-          << HexDump(stringPool->getData(), stringPool->getSize()) << endl);
-
-    ResXMLTree_header header;
-    memset(&header, 0, sizeof(header));
-    header.header.type = htods(RES_XML_TYPE);
-    header.header.headerSize = htods(sizeof(header));
-
-    const size_t basePos = dest->getSize();
-    dest->writeData(&header, sizeof(header));
-    dest->writeData(stringPool->getData(), stringPool->getSize());
-
-    // If we have resource IDs, write them.
-    if (resids.size() > 0) {
-        const size_t resIdsPos = dest->getSize();
-        const size_t resIdsSize =
-            sizeof(ResChunk_header)+(sizeof(uint32_t)*resids.size());
-        ResChunk_header* idsHeader = (ResChunk_header*)
-            (((const uint8_t*)dest->editData(resIdsPos+resIdsSize))+resIdsPos);
-        idsHeader->type = htods(RES_XML_RESOURCE_MAP_TYPE);
-        idsHeader->headerSize = htods(sizeof(*idsHeader));
-        idsHeader->size = htodl(resIdsSize);
-        uint32_t* ids = (uint32_t*)(idsHeader+1);
-        for (size_t i=0; i<resids.size(); i++) {
-            *ids++ = htodl(resids[i]);
-        }
-    }
-
-    flatten_node(strings, dest, stripComments, stripRawValues);
-
-    void* data = dest->editData();
-    ResXMLTree_header* hd = (ResXMLTree_header*)(((uint8_t*)data)+basePos);
-    size_t size = dest->getSize()-basePos;
-    hd->header.size = htodl(dest->getSize()-basePos);
-
-    NOISY(aout << "XML resource:"
-          << HexDump(dest->getData(), dest->getSize()) << endl);
-
-    #if PRINT_STRING_METRICS
-    fprintf(stderr, "**** total xml size: %d / %d%% strings (in %s)\n",
-        dest->getSize(), (stringPool->getSize()*100)/dest->getSize(),
-        dest->getPath().string());
-    #endif
-        
-    return NO_ERROR;
-}
-
-void XMLNode::print(int indent)
-{
-    String8 prefix;
-    int i;
-    for (i=0; i<indent; i++) {
-        prefix.append("  ");
-    }
-    if (getType() == TYPE_ELEMENT) {
-        String8 elemNs(getNamespaceUri());
-        if (elemNs.size() > 0) {
-            elemNs.append(":");
-        }
-        printf("%s E: %s%s", prefix.string(),
-               elemNs.string(), String8(getElementName()).string());
-        int N = mAttributes.size();
-        for (i=0; i<N; i++) {
-            ssize_t idx = mAttributeOrder.valueAt(i);
-            if (i == 0) {
-                printf(" / ");
-            } else {
-                printf(", ");
-            }
-            const attribute_entry& attr = mAttributes.itemAt(idx);
-            String8 attrNs(attr.ns);
-            if (attrNs.size() > 0) {
-                attrNs.append(":");
-            }
-            if (attr.nameResId) {
-                printf("%s%s(0x%08x)", attrNs.string(),
-                       String8(attr.name).string(), attr.nameResId);
-            } else {
-                printf("%s%s", attrNs.string(), String8(attr.name).string());
-            }
-            printf("=%s", String8(attr.string).string());
-        }
-        printf("\n");
-    } else if (getType() == TYPE_NAMESPACE) {
-        printf("%s N: %s=%s\n", prefix.string(),
-               getNamespacePrefix().size() > 0
-                    ? String8(getNamespacePrefix()).string() : "<DEF>",
-               String8(getNamespaceUri()).string());
-    } else {
-        printf("%s C: \"%s\"\n", prefix.string(), String8(getCData()).string());
-    }
-    int N = mChildren.size();
-    for (i=0; i<N; i++) {
-        mChildren.itemAt(i)->print(indent+1);
-    }
-}
-
-static void splitName(const char* name, String16* outNs, String16* outName)
-{
-    const char* p = name;
-    while (*p != 0 && *p != 1) {
-        p++;
-    }
-    if (*p == 0) {
-        *outNs = String16();
-        *outName = String16(name);
-    } else {
-        *outNs = String16(name, (p-name));
-        *outName = String16(p+1);
-    }
-}
-
-void XMLCALL
-XMLNode::startNamespace(void *userData, const char *prefix, const char *uri)
-{
-    NOISY_PARSE(printf("Start Namespace: %s %s\n", prefix, uri));
-    ParseState* st = (ParseState*)userData;
-    sp<XMLNode> node = XMLNode::newNamespace(st->filename, 
-            String16(prefix != NULL ? prefix : ""), String16(uri));
-    node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));
-    if (st->stack.size() > 0) {
-        st->stack.itemAt(st->stack.size()-1)->addChild(node);
-    } else {
-        st->root = node;
-    }
-    st->stack.push(node);
-}
-
-void XMLCALL
-XMLNode::startElement(void *userData, const char *name, const char **atts)
-{
-    NOISY_PARSE(printf("Start Element: %s\n", name));
-    ParseState* st = (ParseState*)userData;
-    String16 ns16, name16;
-    splitName(name, &ns16, &name16);
-    sp<XMLNode> node = XMLNode::newElement(st->filename, ns16, name16);
-    node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));
-    if (st->pendingComment.size() > 0) {
-        node->appendComment(st->pendingComment);
-        st->pendingComment = String16();
-    }
-    if (st->stack.size() > 0) {
-        st->stack.itemAt(st->stack.size()-1)->addChild(node);
-    } else {
-        st->root = node;
-    }
-    st->stack.push(node);
-
-    for (int i = 0; atts[i]; i += 2) {
-        splitName(atts[i], &ns16, &name16);
-        node->addAttribute(ns16, name16, String16(atts[i+1]));
-    }
-}
-
-void XMLCALL
-XMLNode::characterData(void *userData, const XML_Char *s, int len)
-{
-    NOISY_PARSE(printf("CDATA: \"%s\"\n", String8(s, len).string()));
-    ParseState* st = (ParseState*)userData;
-    sp<XMLNode> node = NULL;
-    if (st->stack.size() == 0) {
-        return;
-    }
-    sp<XMLNode> parent = st->stack.itemAt(st->stack.size()-1);
-    if (parent != NULL && parent->getChildren().size() > 0) {
-        node = parent->getChildren()[parent->getChildren().size()-1];
-        if (node->getType() != TYPE_CDATA) {
-            // Last node is not CDATA, need to make a new node.
-            node = NULL;
-        }
-    }
-
-    if (node == NULL) {
-        node = XMLNode::newCData(st->filename);
-        node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));
-        parent->addChild(node);
-    }
-
-    node->appendChars(String16(s, len));
-}
-
-void XMLCALL
-XMLNode::endElement(void *userData, const char *name)
-{
-    NOISY_PARSE(printf("End Element: %s\n", name));
-    ParseState* st = (ParseState*)userData;
-    sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1);
-    node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser));
-    if (st->pendingComment.size() > 0) {
-        node->appendComment(st->pendingComment);
-        st->pendingComment = String16();
-    }
-    String16 ns16, name16;
-    splitName(name, &ns16, &name16);
-    LOG_ALWAYS_FATAL_IF(node->getElementNamespace() != ns16
-                        || node->getElementName() != name16,
-                        "Bad end element %s", name);
-    st->stack.pop();
-}
-
-void XMLCALL
-XMLNode::endNamespace(void *userData, const char *prefix)
-{
-    const char* nonNullPrefix = prefix != NULL ? prefix : "";
-    NOISY_PARSE(printf("End Namespace: %s\n", prefix));
-    ParseState* st = (ParseState*)userData;
-    sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1);
-    node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser));
-    LOG_ALWAYS_FATAL_IF(node->getNamespacePrefix() != String16(nonNullPrefix),
-                        "Bad end namespace %s", prefix);
-    st->stack.pop();
-}
-
-void XMLCALL
-XMLNode::commentData(void *userData, const char *comment)
-{
-    NOISY_PARSE(printf("Comment: %s\n", comment));
-    ParseState* st = (ParseState*)userData;
-    if (st->pendingComment.size() > 0) {
-        st->pendingComment.append(String16("\n"));
-    }
-    st->pendingComment.append(String16(comment));
-}
-
-status_t XMLNode::collect_strings(StringPool* dest, Vector<uint32_t>* outResIds,
-        bool stripComments, bool stripRawValues) const
-{
-    collect_attr_strings(dest, outResIds, true);
-    
-    int i;
-    if (RESOURCES_TOOLS_NAMESPACE != mNamespaceUri) {
-        if (mNamespacePrefix.size() > 0) {
-            dest->add(mNamespacePrefix, true);
-        }
-        if (mNamespaceUri.size() > 0) {
-            dest->add(mNamespaceUri, true);
-        }
-    }
-    if (mElementName.size() > 0) {
-        dest->add(mElementName, true);
-    }
-
-    if (!stripComments && mComment.size() > 0) {
-        dest->add(mComment, true);
-    }
-
-    const int NA = mAttributes.size();
-
-    for (i=0; i<NA; i++) {
-        const attribute_entry& ae = mAttributes.itemAt(i);
-        if (ae.ns.size() > 0) {
-            dest->add(ae.ns, true);
-        }
-        if (!stripRawValues || ae.needStringValue()) {
-            dest->add(ae.string, true);
-        }
-        /*
-        if (ae.value.dataType == Res_value::TYPE_NULL
-                || ae.value.dataType == Res_value::TYPE_STRING) {
-            dest->add(ae.string, true);
-        }
-        */
-    }
-
-    if (mElementName.size() == 0) {
-        // If not an element, include the CDATA, even if it is empty.
-        dest->add(mChars, true);
-    }
-
-    const int NC = mChildren.size();
-
-    for (i=0; i<NC; i++) {
-        mChildren.itemAt(i)->collect_strings(dest, outResIds,
-                stripComments, stripRawValues);
-    }
-
-    return NO_ERROR;
-}
-
-status_t XMLNode::collect_attr_strings(StringPool* outPool,
-        Vector<uint32_t>* outResIds, bool allAttrs) const {
-    const int NA = mAttributes.size();
-
-    for (int i=0; i<NA; i++) {
-        const attribute_entry& attr = mAttributes.itemAt(i);
-        uint32_t id = attr.nameResId;
-        if (id || allAttrs) {
-            // See if we have already assigned this resource ID to a pooled
-            // string...
-            const Vector<size_t>* indices = outPool->offsetsForString(attr.name);
-            ssize_t idx = -1;
-            if (indices != NULL) {
-                const int NJ = indices->size();
-                const size_t NR = outResIds->size();
-                for (int j=0; j<NJ; j++) {
-                    size_t strIdx = indices->itemAt(j);
-                    if (strIdx >= NR) {
-                        if (id == 0) {
-                            // We don't need to assign a resource ID for this one.
-                            idx = strIdx;
-                            break;
-                        }
-                        // Just ignore strings that are out of range of
-                        // the currently assigned resource IDs...  we add
-                        // strings as we assign the first ID.
-                    } else if (outResIds->itemAt(strIdx) == id) {
-                        idx = strIdx;
-                        break;
-                    }
-                }
-            }
-            if (idx < 0) {
-                idx = outPool->add(attr.name);
-                NOISY(printf("Adding attr %s (resid 0x%08x) to pool: idx=%d\n",
-                        String8(attr.name).string(), id, idx));
-                if (id != 0) {
-                    while ((ssize_t)outResIds->size() <= idx) {
-                        outResIds->add(0);
-                    }
-                    outResIds->replaceAt(id, idx);
-                }
-            }
-            attr.namePoolIdx = idx;
-            NOISY(printf("String %s offset=0x%08x\n",
-                         String8(attr.name).string(), idx));
-        }
-    }
-
-    return NO_ERROR;
-}
-
-status_t XMLNode::collect_resid_strings(StringPool* outPool,
-        Vector<uint32_t>* outResIds) const
-{
-    collect_attr_strings(outPool, outResIds, false);
-
-    const int NC = mChildren.size();
-
-    for (int i=0; i<NC; i++) {
-        mChildren.itemAt(i)->collect_resid_strings(outPool, outResIds);
-    }
-
-    return NO_ERROR;
-}
-
-status_t XMLNode::flatten_node(const StringPool& strings, const sp<AaptFile>& dest,
-        bool stripComments, bool stripRawValues) const
-{
-    ResXMLTree_node node;
-    ResXMLTree_cdataExt cdataExt;
-    ResXMLTree_namespaceExt namespaceExt;
-    ResXMLTree_attrExt attrExt;
-    const void* extData = NULL;
-    size_t extSize = 0;
-    ResXMLTree_attribute attr;
-    bool writeCurrentNode = true;
-
-    const size_t NA = mAttributes.size();
-    const size_t NC = mChildren.size();
-    size_t i;
-
-    LOG_ALWAYS_FATAL_IF(NA != mAttributeOrder.size(), "Attributes messed up!");
-
-    const String16 id16("id");
-    const String16 class16("class");
-    const String16 style16("style");
-
-    const type type = getType();
-
-    memset(&node, 0, sizeof(node));
-    memset(&attr, 0, sizeof(attr));
-    node.header.headerSize = htods(sizeof(node));
-    node.lineNumber = htodl(getStartLineNumber());
-    if (!stripComments) {
-        node.comment.index = htodl(
-            mComment.size() > 0 ? strings.offsetForString(mComment) : -1);
-        //if (mComment.size() > 0) {
-        //  printf("Flattening comment: %s\n", String8(mComment).string());
-        //}
-    } else {
-        node.comment.index = htodl((uint32_t)-1);
-    }
-    if (type == TYPE_ELEMENT) {
-        node.header.type = htods(RES_XML_START_ELEMENT_TYPE);
-        extData = &attrExt;
-        extSize = sizeof(attrExt);
-        memset(&attrExt, 0, sizeof(attrExt));
-        if (mNamespaceUri.size() > 0) {
-            attrExt.ns.index = htodl(strings.offsetForString(mNamespaceUri));
-        } else {
-            attrExt.ns.index = htodl((uint32_t)-1);
-        }
-        attrExt.name.index = htodl(strings.offsetForString(mElementName));
-        attrExt.attributeStart = htods(sizeof(attrExt));
-        attrExt.attributeSize = htods(sizeof(attr));
-        attrExt.attributeCount = htods(NA);
-        attrExt.idIndex = htods(0);
-        attrExt.classIndex = htods(0);
-        attrExt.styleIndex = htods(0);
-        for (i=0; i<NA; i++) {
-            ssize_t idx = mAttributeOrder.valueAt(i);
-            const attribute_entry& ae = mAttributes.itemAt(idx);
-            if (ae.ns.size() == 0) {
-                if (ae.name == id16) {
-                    attrExt.idIndex = htods(i+1);
-                } else if (ae.name == class16) {
-                    attrExt.classIndex = htods(i+1);
-                } else if (ae.name == style16) {
-                    attrExt.styleIndex = htods(i+1);
-                }
-            }
-        }
-    } else if (type == TYPE_NAMESPACE) {
-        if (mNamespaceUri == RESOURCES_TOOLS_NAMESPACE) {
-            writeCurrentNode = false;
-        } else {
-            node.header.type = htods(RES_XML_START_NAMESPACE_TYPE);
-            extData = &namespaceExt;
-            extSize = sizeof(namespaceExt);
-            memset(&namespaceExt, 0, sizeof(namespaceExt));
-            if (mNamespacePrefix.size() > 0) {
-                namespaceExt.prefix.index = htodl(strings.offsetForString(mNamespacePrefix));
-            } else {
-                namespaceExt.prefix.index = htodl((uint32_t)-1);
-            }
-            namespaceExt.prefix.index = htodl(strings.offsetForString(mNamespacePrefix));
-            namespaceExt.uri.index = htodl(strings.offsetForString(mNamespaceUri));
-        }
-        LOG_ALWAYS_FATAL_IF(NA != 0, "Namespace nodes can't have attributes!");
-    } else if (type == TYPE_CDATA) {
-        node.header.type = htods(RES_XML_CDATA_TYPE);
-        extData = &cdataExt;
-        extSize = sizeof(cdataExt);
-        memset(&cdataExt, 0, sizeof(cdataExt));
-        cdataExt.data.index = htodl(strings.offsetForString(mChars));
-        cdataExt.typedData.size = htods(sizeof(cdataExt.typedData));
-        cdataExt.typedData.res0 = 0;
-        cdataExt.typedData.dataType = mCharsValue.dataType;
-        cdataExt.typedData.data = htodl(mCharsValue.data);
-        LOG_ALWAYS_FATAL_IF(NA != 0, "CDATA nodes can't have attributes!");
-    }
-
-    node.header.size = htodl(sizeof(node) + extSize + (sizeof(attr)*NA));
-
-    if (writeCurrentNode) {
-        dest->writeData(&node, sizeof(node));
-        if (extSize > 0) {
-            dest->writeData(extData, extSize);
-        }
-    }
-
-    for (i=0; i<NA; i++) {
-        ssize_t idx = mAttributeOrder.valueAt(i);
-        const attribute_entry& ae = mAttributes.itemAt(idx);
-        if (ae.ns.size() > 0) {
-            attr.ns.index = htodl(strings.offsetForString(ae.ns));
-        } else {
-            attr.ns.index = htodl((uint32_t)-1);
-        }
-        attr.name.index = htodl(ae.namePoolIdx);
-
-        if (!stripRawValues || ae.needStringValue()) {
-            attr.rawValue.index = htodl(strings.offsetForString(ae.string));
-        } else {
-            attr.rawValue.index = htodl((uint32_t)-1);
-        }
-        attr.typedValue.size = htods(sizeof(attr.typedValue));
-        if (ae.value.dataType == Res_value::TYPE_NULL
-                || ae.value.dataType == Res_value::TYPE_STRING) {
-            attr.typedValue.res0 = 0;
-            attr.typedValue.dataType = Res_value::TYPE_STRING;
-            attr.typedValue.data = htodl(strings.offsetForString(ae.string));
-        } else {
-            attr.typedValue.res0 = 0;
-            attr.typedValue.dataType = ae.value.dataType;
-            attr.typedValue.data = htodl(ae.value.data);
-        }
-        dest->writeData(&attr, sizeof(attr));
-    }
-
-    for (i=0; i<NC; i++) {
-        status_t err = mChildren.itemAt(i)->flatten_node(strings, dest,
-                stripComments, stripRawValues);
-        if (err != NO_ERROR) {
-            return err;
-        }
-    }
-
-    if (type == TYPE_ELEMENT) {
-        ResXMLTree_endElementExt endElementExt;
-        memset(&endElementExt, 0, sizeof(endElementExt));
-        node.header.type = htods(RES_XML_END_ELEMENT_TYPE);
-        node.header.size = htodl(sizeof(node)+sizeof(endElementExt));
-        node.lineNumber = htodl(getEndLineNumber());
-        node.comment.index = htodl((uint32_t)-1);
-        endElementExt.ns.index = attrExt.ns.index;
-        endElementExt.name.index = attrExt.name.index;
-        dest->writeData(&node, sizeof(node));
-        dest->writeData(&endElementExt, sizeof(endElementExt));
-    } else if (type == TYPE_NAMESPACE) {
-        if (writeCurrentNode) {
-            node.header.type = htods(RES_XML_END_NAMESPACE_TYPE);
-            node.lineNumber = htodl(getEndLineNumber());
-            node.comment.index = htodl((uint32_t)-1);
-            node.header.size = htodl(sizeof(node)+extSize);
-            dest->writeData(&node, sizeof(node));
-            dest->writeData(extData, extSize);
-        }
-    }
-
-    return NO_ERROR;
-}
diff --git a/tools/aapt/XMLNode.h b/tools/aapt/XMLNode.h
deleted file mode 100644
index 05624b7..0000000
--- a/tools/aapt/XMLNode.h
+++ /dev/null
@@ -1,202 +0,0 @@
-//
-// Copyright 2006 The Android Open Source Project
-//
-// Build resource files from raw assets.
-//
-
-#ifndef XML_NODE_H
-#define XML_NODE_H
-
-#include "StringPool.h"
-#include "ResourceTable.h"
-
-class XMLNode;
-
-extern const char* const RESOURCES_ROOT_NAMESPACE;
-extern const char* const RESOURCES_ANDROID_NAMESPACE;
-
-bool isWhitespace(const char16_t* str);
-
-String16 getNamespaceResourcePackage(String16 namespaceUri, bool* outIsPublic = NULL);
-
-status_t parseStyledString(Bundle* bundle,
-                           const char* fileName,
-                           ResXMLTree* inXml,
-                           const String16& endTag,
-                           String16* outString,
-                           Vector<StringPool::entry_style_span>* outSpans,
-                           bool isFormatted,
-                           bool isPseudolocalizable);
-
-void printXMLBlock(ResXMLTree* block);
-
-status_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree,
-                          bool stripAll=true, bool keepComments=false,
-                          const char** cDataTags=NULL);
-
-class XMLNode : public RefBase
-{
-public:
-    static sp<XMLNode> parse(const sp<AaptFile>& file);
-
-    static inline
-    sp<XMLNode> newNamespace(const String8& filename, const String16& prefix, const String16& uri) {
-        return new XMLNode(filename, prefix, uri, true);
-    }
-    
-    static inline
-    sp<XMLNode> newElement(const String8& filename, const String16& ns, const String16& name) {
-        return new XMLNode(filename, ns, name, false);
-    }
-    
-    static inline
-    sp<XMLNode> newCData(const String8& filename) {
-        return new XMLNode(filename);
-    }
-    
-    enum type {
-        TYPE_NAMESPACE,
-        TYPE_ELEMENT,
-        TYPE_CDATA
-    };
-    
-    type getType() const;
-    
-    const String16& getNamespacePrefix() const;
-    const String16& getNamespaceUri() const;
-    
-    const String16& getElementNamespace() const;
-    const String16& getElementName() const;
-    const Vector<sp<XMLNode> >& getChildren() const;
-
-    const String8& getFilename() const;
-    
-    struct attribute_entry {
-        attribute_entry() : index(~(uint32_t)0), nameResId(0)
-        {
-            value.dataType = Res_value::TYPE_NULL;
-        }
-
-        bool needStringValue() const {
-            return nameResId == 0
-                || value.dataType == Res_value::TYPE_NULL
-                || value.dataType == Res_value::TYPE_STRING;
-        }
-        
-        String16 ns;
-        String16 name;
-        String16 string;
-        Res_value value;
-        uint32_t index;
-        uint32_t nameResId;
-        mutable uint32_t namePoolIdx;
-    };
-
-    const Vector<attribute_entry>& getAttributes() const;
-
-    const attribute_entry* getAttribute(const String16& ns, const String16& name) const;
-    
-    attribute_entry* editAttribute(const String16& ns, const String16& name);
-
-    const String16& getCData() const;
-
-    const String16& getComment() const;
-
-    int32_t getStartLineNumber() const;
-    int32_t getEndLineNumber() const;
-
-    sp<XMLNode> searchElement(const String16& tagNamespace, const String16& tagName);
-    
-    sp<XMLNode> getChildElement(const String16& tagNamespace, const String16& tagName);
-    
-    status_t addChild(const sp<XMLNode>& child);
-
-    status_t insertChildAt(const sp<XMLNode>& child, size_t index);
-
-    status_t addAttribute(const String16& ns, const String16& name,
-                          const String16& value);
-
-    void setAttributeResID(size_t attrIdx, uint32_t resId);
-
-    status_t appendChars(const String16& chars);
-
-    status_t appendComment(const String16& comment);
-
-    void setStartLineNumber(int32_t line);
-    void setEndLineNumber(int32_t line);
-
-    void removeWhitespace(bool stripAll=true, const char** cDataTags=NULL);
-
-    void setUTF8(bool val) { mUTF8 = val; }
-
-    status_t parseValues(const sp<AaptAssets>& assets, ResourceTable* table);
-
-    status_t assignResourceIds(const sp<AaptAssets>& assets,
-                               const ResourceTable* table = NULL);
-
-    status_t flatten(const sp<AaptFile>& dest, bool stripComments,
-            bool stripRawValues) const;
-
-    void print(int indent=0);
-
-private:
-    struct ParseState
-    {
-        String8 filename;
-        XML_Parser parser;
-        sp<XMLNode> root;
-        Vector<sp<XMLNode> > stack;
-        String16 pendingComment;
-    };
-
-    static void XMLCALL
-    startNamespace(void *userData, const char *prefix, const char *uri);
-    static void XMLCALL
-    startElement(void *userData, const char *name, const char **atts);
-    static void XMLCALL
-    characterData(void *userData, const XML_Char *s, int len);
-    static void XMLCALL
-    endElement(void *userData, const char *name);
-    static void XMLCALL
-    endNamespace(void *userData, const char *prefix);
-    
-    static void XMLCALL
-    commentData(void *userData, const char *comment);
-    
-    // Creating an element node.
-    XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace);
-    
-    // Creating a CDATA node.
-    XMLNode(const String8& filename);
-    
-    status_t collect_strings(StringPool* dest, Vector<uint32_t>* outResIds,
-            bool stripComments, bool stripRawValues) const;
-
-    status_t collect_attr_strings(StringPool* outPool,
-        Vector<uint32_t>* outResIds, bool allAttrs) const;
-        
-    status_t collect_resid_strings(StringPool* outPool,
-            Vector<uint32_t>* outResIds) const;
-
-    status_t flatten_node(const StringPool& strings, const sp<AaptFile>& dest,
-            bool stripComments, bool stripRawValues) const;
-
-    String16 mNamespacePrefix;
-    String16 mNamespaceUri;
-    String16 mElementName;
-    Vector<sp<XMLNode> > mChildren;
-    Vector<attribute_entry> mAttributes;
-    KeyedVector<uint32_t, uint32_t> mAttributeOrder;
-    uint32_t mNextAttributeIndex;
-    String16 mChars;
-    Res_value mCharsValue;
-    String16 mComment;
-    String8 mFilename;
-    int32_t mStartLineNumber;
-    int32_t mEndLineNumber;
-
-    // Encode compiled XML with UTF-8 StringPools?
-    bool mUTF8;
-};
-
-#endif
diff --git a/tools/aapt/ZipEntry.cpp b/tools/aapt/ZipEntry.cpp
deleted file mode 100644
index b575988..0000000
--- a/tools/aapt/ZipEntry.cpp
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Access to entries in a Zip archive.
-//
-
-#define LOG_TAG "zip"
-
-#include "ZipEntry.h"
-#include <utils/Log.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-using namespace android;
-
-/*
- * Initialize a new ZipEntry structure from a FILE* positioned at a
- * CentralDirectoryEntry.
- *
- * On exit, the file pointer will be at the start of the next CDE or
- * at the EOCD.
- */
-status_t ZipEntry::initFromCDE(FILE* fp)
-{
-    status_t result;
-    long posn;
-    bool hasDD;
-
-    //ALOGV("initFromCDE ---\n");
-
-    /* read the CDE */
-    result = mCDE.read(fp);
-    if (result != NO_ERROR) {
-        ALOGD("mCDE.read failed\n");
-        return result;
-    }
-
-    //mCDE.dump();
-
-    /* using the info in the CDE, go load up the LFH */
-    posn = ftell(fp);
-    if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
-        ALOGD("local header seek failed (%ld)\n",
-            mCDE.mLocalHeaderRelOffset);
-        return UNKNOWN_ERROR;
-    }
-
-    result = mLFH.read(fp);
-    if (result != NO_ERROR) {
-        ALOGD("mLFH.read failed\n");
-        return result;
-    }
-
-    if (fseek(fp, posn, SEEK_SET) != 0)
-        return UNKNOWN_ERROR;
-
-    //mLFH.dump();
-
-    /*
-     * We *might* need to read the Data Descriptor at this point and
-     * integrate it into the LFH.  If this bit is set, the CRC-32,
-     * compressed size, and uncompressed size will be zero.  In practice
-     * these seem to be rare.
-     */
-    hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;
-    if (hasDD) {
-        // do something clever
-        //ALOGD("+++ has data descriptor\n");
-    }
-
-    /*
-     * Sanity-check the LFH.  Note that this will fail if the "kUsesDataDescr"
-     * flag is set, because the LFH is incomplete.  (Not a problem, since we
-     * prefer the CDE values.)
-     */
-    if (!hasDD && !compareHeaders()) {
-        ALOGW("warning: header mismatch\n");
-        // keep going?
-    }
-
-    /*
-     * If the mVersionToExtract is greater than 20, we may have an
-     * issue unpacking the record -- could be encrypted, compressed
-     * with something we don't support, or use Zip64 extensions.  We
-     * can defer worrying about that to when we're extracting data.
-     */
-
-    return NO_ERROR;
-}
-
-/*
- * Initialize a new entry.  Pass in the file name and an optional comment.
- *
- * Initializes the CDE and the LFH.
- */
-void ZipEntry::initNew(const char* fileName, const char* comment)
-{
-    assert(fileName != NULL && *fileName != '\0');  // name required
-
-    /* most fields are properly initialized by constructor */
-    mCDE.mVersionMadeBy = kDefaultMadeBy;
-    mCDE.mVersionToExtract = kDefaultVersion;
-    mCDE.mCompressionMethod = kCompressStored;
-    mCDE.mFileNameLength = strlen(fileName);
-    if (comment != NULL)
-        mCDE.mFileCommentLength = strlen(comment);
-    mCDE.mExternalAttrs = 0x81b60020;   // matches what WinZip does
-
-    if (mCDE.mFileNameLength > 0) {
-        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
-        strcpy((char*) mCDE.mFileName, fileName);
-    }
-    if (mCDE.mFileCommentLength > 0) {
-        /* TODO: stop assuming null-terminated ASCII here? */
-        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
-        strcpy((char*) mCDE.mFileComment, comment);
-    }
-
-    copyCDEtoLFH();
-}
-
-/*
- * Initialize a new entry, starting with the ZipEntry from a different
- * archive.
- *
- * Initializes the CDE and the LFH.
- */
-status_t ZipEntry::initFromExternal(const ZipFile* pZipFile,
-    const ZipEntry* pEntry)
-{
-    /*
-     * Copy everything in the CDE over, then fix up the hairy bits.
-     */
-    memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE));
-
-    if (mCDE.mFileNameLength > 0) {
-        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
-        if (mCDE.mFileName == NULL)
-            return NO_MEMORY;
-        strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName);
-    }
-    if (mCDE.mFileCommentLength > 0) {
-        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
-        if (mCDE.mFileComment == NULL)
-            return NO_MEMORY;
-        strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment);
-    }
-    if (mCDE.mExtraFieldLength > 0) {
-        /* we null-terminate this, though it may not be a string */
-        mCDE.mExtraField = new unsigned char[mCDE.mExtraFieldLength+1];
-        if (mCDE.mExtraField == NULL)
-            return NO_MEMORY;
-        memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField,
-            mCDE.mExtraFieldLength+1);
-    }
-
-    /* construct the LFH from the CDE */
-    copyCDEtoLFH();
-
-    /*
-     * The LFH "extra" field is independent of the CDE "extra", so we
-     * handle it here.
-     */
-    assert(mLFH.mExtraField == NULL);
-    mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength;
-    if (mLFH.mExtraFieldLength > 0) {
-        mLFH.mExtraField = new unsigned char[mLFH.mExtraFieldLength+1];
-        if (mLFH.mExtraField == NULL)
-            return NO_MEMORY;
-        memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField,
-            mLFH.mExtraFieldLength+1);
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Insert pad bytes in the LFH by tweaking the "extra" field.  This will
- * potentially confuse something that put "extra" data in here earlier,
- * but I can't find an actual problem.
- */
-status_t ZipEntry::addPadding(int padding)
-{
-    if (padding <= 0)
-        return INVALID_OPERATION;
-
-    //ALOGI("HEY: adding %d pad bytes to existing %d in %s\n",
-    //    padding, mLFH.mExtraFieldLength, mCDE.mFileName);
-
-    if (mLFH.mExtraFieldLength > 0) {
-        /* extend existing field */
-        unsigned char* newExtra;
-
-        newExtra = new unsigned char[mLFH.mExtraFieldLength + padding];
-        if (newExtra == NULL)
-            return NO_MEMORY;
-        memset(newExtra + mLFH.mExtraFieldLength, 0, padding);
-        memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength);
-
-        delete[] mLFH.mExtraField;
-        mLFH.mExtraField = newExtra;
-        mLFH.mExtraFieldLength += padding;
-    } else {
-        /* create new field */
-        mLFH.mExtraField = new unsigned char[padding];
-        memset(mLFH.mExtraField, 0, padding);
-        mLFH.mExtraFieldLength = padding;
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Set the fields in the LFH equal to the corresponding fields in the CDE.
- *
- * This does not touch the LFH "extra" field.
- */
-void ZipEntry::copyCDEtoLFH(void)
-{
-    mLFH.mVersionToExtract  = mCDE.mVersionToExtract;
-    mLFH.mGPBitFlag         = mCDE.mGPBitFlag;
-    mLFH.mCompressionMethod = mCDE.mCompressionMethod;
-    mLFH.mLastModFileTime   = mCDE.mLastModFileTime;
-    mLFH.mLastModFileDate   = mCDE.mLastModFileDate;
-    mLFH.mCRC32             = mCDE.mCRC32;
-    mLFH.mCompressedSize    = mCDE.mCompressedSize;
-    mLFH.mUncompressedSize  = mCDE.mUncompressedSize;
-    mLFH.mFileNameLength    = mCDE.mFileNameLength;
-    // the "extra field" is independent
-
-    delete[] mLFH.mFileName;
-    if (mLFH.mFileNameLength > 0) {
-        mLFH.mFileName = new unsigned char[mLFH.mFileNameLength+1];
-        strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName);
-    } else {
-        mLFH.mFileName = NULL;
-    }
-}
-
-/*
- * Set some information about a file after we add it.
- */
-void ZipEntry::setDataInfo(long uncompLen, long compLen, unsigned long crc32,
-    int compressionMethod)
-{
-    mCDE.mCompressionMethod = compressionMethod;
-    mCDE.mCRC32 = crc32;
-    mCDE.mCompressedSize = compLen;
-    mCDE.mUncompressedSize = uncompLen;
-    mCDE.mCompressionMethod = compressionMethod;
-    if (compressionMethod == kCompressDeflated) {
-        mCDE.mGPBitFlag |= 0x0002;      // indicates maximum compression used
-    }
-    copyCDEtoLFH();
-}
-
-/*
- * See if the data in mCDE and mLFH match up.  This is mostly useful for
- * debugging these classes, but it can be used to identify damaged
- * archives.
- *
- * Returns "false" if they differ.
- */
-bool ZipEntry::compareHeaders(void) const
-{
-    if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) {
-        ALOGV("cmp: VersionToExtract\n");
-        return false;
-    }
-    if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) {
-        ALOGV("cmp: GPBitFlag\n");
-        return false;
-    }
-    if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) {
-        ALOGV("cmp: CompressionMethod\n");
-        return false;
-    }
-    if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) {
-        ALOGV("cmp: LastModFileTime\n");
-        return false;
-    }
-    if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) {
-        ALOGV("cmp: LastModFileDate\n");
-        return false;
-    }
-    if (mCDE.mCRC32 != mLFH.mCRC32) {
-        ALOGV("cmp: CRC32\n");
-        return false;
-    }
-    if (mCDE.mCompressedSize != mLFH.mCompressedSize) {
-        ALOGV("cmp: CompressedSize\n");
-        return false;
-    }
-    if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) {
-        ALOGV("cmp: UncompressedSize\n");
-        return false;
-    }
-    if (mCDE.mFileNameLength != mLFH.mFileNameLength) {
-        ALOGV("cmp: FileNameLength\n");
-        return false;
-    }
-#if 0       // this seems to be used for padding, not real data
-    if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) {
-        ALOGV("cmp: ExtraFieldLength\n");
-        return false;
-    }
-#endif
-    if (mCDE.mFileName != NULL) {
-        if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) {
-            ALOGV("cmp: FileName\n");
-            return false;
-        }
-    }
-
-    return true;
-}
-
-
-/*
- * Convert the DOS date/time stamp into a UNIX time stamp.
- */
-time_t ZipEntry::getModWhen(void) const
-{
-    struct tm parts;
-
-    parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1;
-    parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5;
-    parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11;
-    parts.tm_mday = (mCDE.mLastModFileDate & 0x001f);
-    parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1;
-    parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80;
-    parts.tm_wday = parts.tm_yday = 0;
-    parts.tm_isdst = -1;        // DST info "not available"
-
-    return mktime(&parts);
-}
-
-/*
- * Set the CDE/LFH timestamp from UNIX time.
- */
-void ZipEntry::setModWhen(time_t when)
-{
-#ifdef HAVE_LOCALTIME_R
-    struct tm tmResult;
-#endif
-    time_t even;
-    unsigned short zdate, ztime;
-
-    struct tm* ptm;
-
-    /* round up to an even number of seconds */
-    even = (time_t)(((unsigned long)(when) + 1) & (~1));
-
-    /* expand */
-#ifdef HAVE_LOCALTIME_R
-    ptm = localtime_r(&even, &tmResult);
-#else
-    ptm = localtime(&even);
-#endif
-
-    int year;
-    year = ptm->tm_year;
-    if (year < 80)
-        year = 80;
-
-    zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday;
-    ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
-
-    mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime;
-    mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate;
-}
-
-
-/*
- * ===========================================================================
- *      ZipEntry::LocalFileHeader
- * ===========================================================================
- */
-
-/*
- * Read a local file header.
- *
- * On entry, "fp" points to the signature at the start of the header.
- * On exit, "fp" points to the start of data.
- */
-status_t ZipEntry::LocalFileHeader::read(FILE* fp)
-{
-    status_t result = NO_ERROR;
-    unsigned char buf[kLFHLen];
-
-    assert(mFileName == NULL);
-    assert(mExtraField == NULL);
-
-    if (fread(buf, 1, kLFHLen, fp) != kLFHLen) {
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
-        ALOGD("whoops: didn't find expected signature\n");
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]);
-    mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]);
-    mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]);
-    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]);
-    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]);
-    mCRC32 = ZipEntry::getLongLE(&buf[0x0e]);
-    mCompressedSize = ZipEntry::getLongLE(&buf[0x12]);
-    mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]);
-    mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]);
-    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]);
-
-    // TODO: validate sizes
-
-    /* grab filename */
-    if (mFileNameLength != 0) {
-        mFileName = new unsigned char[mFileNameLength+1];
-        if (mFileName == NULL) {
-            result = NO_MEMORY;
-            goto bail;
-        }
-        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-        mFileName[mFileNameLength] = '\0';
-    }
-
-    /* grab extra field */
-    if (mExtraFieldLength != 0) {
-        mExtraField = new unsigned char[mExtraFieldLength+1];
-        if (mExtraField == NULL) {
-            result = NO_MEMORY;
-            goto bail;
-        }
-        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-        mExtraField[mExtraFieldLength] = '\0';
-    }
-
-bail:
-    return result;
-}
-
-/*
- * Write a local file header.
- */
-status_t ZipEntry::LocalFileHeader::write(FILE* fp)
-{
-    unsigned char buf[kLFHLen];
-
-    ZipEntry::putLongLE(&buf[0x00], kSignature);
-    ZipEntry::putShortLE(&buf[0x04], mVersionToExtract);
-    ZipEntry::putShortLE(&buf[0x06], mGPBitFlag);
-    ZipEntry::putShortLE(&buf[0x08], mCompressionMethod);
-    ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime);
-    ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate);
-    ZipEntry::putLongLE(&buf[0x0e], mCRC32);
-    ZipEntry::putLongLE(&buf[0x12], mCompressedSize);
-    ZipEntry::putLongLE(&buf[0x16], mUncompressedSize);
-    ZipEntry::putShortLE(&buf[0x1a], mFileNameLength);
-    ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength);
-
-    if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen)
-        return UNKNOWN_ERROR;
-
-    /* write filename */
-    if (mFileNameLength != 0) {
-        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
-            return UNKNOWN_ERROR;
-    }
-
-    /* write "extra field" */
-    if (mExtraFieldLength != 0) {
-        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
-            return UNKNOWN_ERROR;
-    }
-
-    return NO_ERROR;
-}
-
-
-/*
- * Dump the contents of a LocalFileHeader object.
- */
-void ZipEntry::LocalFileHeader::dump(void) const
-{
-    ALOGD(" LocalFileHeader contents:\n");
-    ALOGD("  versToExt=%u gpBits=0x%04x compression=%u\n",
-        mVersionToExtract, mGPBitFlag, mCompressionMethod);
-    ALOGD("  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
-        mLastModFileTime, mLastModFileDate, mCRC32);
-    ALOGD("  compressedSize=%lu uncompressedSize=%lu\n",
-        mCompressedSize, mUncompressedSize);
-    ALOGD("  filenameLen=%u extraLen=%u\n",
-        mFileNameLength, mExtraFieldLength);
-    if (mFileName != NULL)
-        ALOGD("  filename: '%s'\n", mFileName);
-}
-
-
-/*
- * ===========================================================================
- *      ZipEntry::CentralDirEntry
- * ===========================================================================
- */
-
-/*
- * Read the central dir entry that appears next in the file.
- *
- * On entry, "fp" should be positioned on the signature bytes for the
- * entry.  On exit, "fp" will point at the signature word for the next
- * entry or for the EOCD.
- */
-status_t ZipEntry::CentralDirEntry::read(FILE* fp)
-{
-    status_t result = NO_ERROR;
-    unsigned char buf[kCDELen];
-
-    /* no re-use */
-    assert(mFileName == NULL);
-    assert(mExtraField == NULL);
-    assert(mFileComment == NULL);
-
-    if (fread(buf, 1, kCDELen, fp) != kCDELen) {
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
-        ALOGD("Whoops: didn't find expected signature\n");
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]);
-    mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]);
-    mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]);
-    mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]);
-    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]);
-    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]);
-    mCRC32 = ZipEntry::getLongLE(&buf[0x10]);
-    mCompressedSize = ZipEntry::getLongLE(&buf[0x14]);
-    mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]);
-    mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]);
-    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]);
-    mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]);
-    mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]);
-    mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]);
-    mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]);
-    mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]);
-
-    // TODO: validate sizes and offsets
-
-    /* grab filename */
-    if (mFileNameLength != 0) {
-        mFileName = new unsigned char[mFileNameLength+1];
-        if (mFileName == NULL) {
-            result = NO_MEMORY;
-            goto bail;
-        }
-        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-        mFileName[mFileNameLength] = '\0';
-    }
-
-    /* read "extra field" */
-    if (mExtraFieldLength != 0) {
-        mExtraField = new unsigned char[mExtraFieldLength+1];
-        if (mExtraField == NULL) {
-            result = NO_MEMORY;
-            goto bail;
-        }
-        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-        mExtraField[mExtraFieldLength] = '\0';
-    }
-
-
-    /* grab comment, if any */
-    if (mFileCommentLength != 0) {
-        mFileComment = new unsigned char[mFileCommentLength+1];
-        if (mFileComment == NULL) {
-            result = NO_MEMORY;
-            goto bail;
-        }
-        if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
-        {
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-        mFileComment[mFileCommentLength] = '\0';
-    }
-
-bail:
-    return result;
-}
-
-/*
- * Write a central dir entry.
- */
-status_t ZipEntry::CentralDirEntry::write(FILE* fp)
-{
-    unsigned char buf[kCDELen];
-
-    ZipEntry::putLongLE(&buf[0x00], kSignature);
-    ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy);
-    ZipEntry::putShortLE(&buf[0x06], mVersionToExtract);
-    ZipEntry::putShortLE(&buf[0x08], mGPBitFlag);
-    ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod);
-    ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime);
-    ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate);
-    ZipEntry::putLongLE(&buf[0x10], mCRC32);
-    ZipEntry::putLongLE(&buf[0x14], mCompressedSize);
-    ZipEntry::putLongLE(&buf[0x18], mUncompressedSize);
-    ZipEntry::putShortLE(&buf[0x1c], mFileNameLength);
-    ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength);
-    ZipEntry::putShortLE(&buf[0x20], mFileCommentLength);
-    ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart);
-    ZipEntry::putShortLE(&buf[0x24], mInternalAttrs);
-    ZipEntry::putLongLE(&buf[0x26], mExternalAttrs);
-    ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset);
-
-    if (fwrite(buf, 1, kCDELen, fp) != kCDELen)
-        return UNKNOWN_ERROR;
-
-    /* write filename */
-    if (mFileNameLength != 0) {
-        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
-            return UNKNOWN_ERROR;
-    }
-
-    /* write "extra field" */
-    if (mExtraFieldLength != 0) {
-        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
-            return UNKNOWN_ERROR;
-    }
-
-    /* write comment */
-    if (mFileCommentLength != 0) {
-        if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
-            return UNKNOWN_ERROR;
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Dump the contents of a CentralDirEntry object.
- */
-void ZipEntry::CentralDirEntry::dump(void) const
-{
-    ALOGD(" CentralDirEntry contents:\n");
-    ALOGD("  versMadeBy=%u versToExt=%u gpBits=0x%04x compression=%u\n",
-        mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod);
-    ALOGD("  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
-        mLastModFileTime, mLastModFileDate, mCRC32);
-    ALOGD("  compressedSize=%lu uncompressedSize=%lu\n",
-        mCompressedSize, mUncompressedSize);
-    ALOGD("  filenameLen=%u extraLen=%u commentLen=%u\n",
-        mFileNameLength, mExtraFieldLength, mFileCommentLength);
-    ALOGD("  diskNumStart=%u intAttr=0x%04x extAttr=0x%08lx relOffset=%lu\n",
-        mDiskNumberStart, mInternalAttrs, mExternalAttrs,
-        mLocalHeaderRelOffset);
-
-    if (mFileName != NULL)
-        ALOGD("  filename: '%s'\n", mFileName);
-    if (mFileComment != NULL)
-        ALOGD("  comment: '%s'\n", mFileComment);
-}
-
diff --git a/tools/aapt/ZipEntry.h b/tools/aapt/ZipEntry.h
deleted file mode 100644
index c2f3227..0000000
--- a/tools/aapt/ZipEntry.h
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Zip archive entries.
-//
-// The ZipEntry class is tightly meshed with the ZipFile class.
-//
-#ifndef __LIBS_ZIPENTRY_H
-#define __LIBS_ZIPENTRY_H
-
-#include <utils/Errors.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-
-namespace android {
-
-class ZipFile;
-
-/*
- * ZipEntry objects represent a single entry in a Zip archive.
- *
- * You can use one of these to get or set information about an entry, but
- * there are no functions here for accessing the data itself.  (We could
- * tuck a pointer to the ZipFile in here for convenience, but that raises
- * the likelihood of using ZipEntry objects after discarding the ZipFile.)
- *
- * File information is stored in two places: next to the file data (the Local
- * File Header, and possibly a Data Descriptor), and at the end of the file
- * (the Central Directory Entry).  The two must be kept in sync.
- */
-class ZipEntry {
-public:
-    friend class ZipFile;
-
-    ZipEntry(void)
-        : mDeleted(false), mMarked(false)
-        {}
-    ~ZipEntry(void) {}
-
-    /*
-     * Returns "true" if the data is compressed.
-     */
-    bool isCompressed(void) const {
-        return mCDE.mCompressionMethod != kCompressStored;
-    }
-    int getCompressionMethod(void) const { return mCDE.mCompressionMethod; }
-
-    /*
-     * Return the uncompressed length.
-     */
-    off_t getUncompressedLen(void) const { return mCDE.mUncompressedSize; }
-
-    /*
-     * Return the compressed length.  For uncompressed data, this returns
-     * the same thing as getUncompresesdLen().
-     */
-    off_t getCompressedLen(void) const { return mCDE.mCompressedSize; }
-
-    /*
-     * Return the offset of the local file header.
-     */
-    off_t getLFHOffset(void) const { return mCDE.mLocalHeaderRelOffset; }
-
-    /*
-     * Return the absolute file offset of the start of the compressed or
-     * uncompressed data.
-     */
-    off_t getFileOffset(void) const {
-        return mCDE.mLocalHeaderRelOffset +
-                LocalFileHeader::kLFHLen +
-                mLFH.mFileNameLength +
-                mLFH.mExtraFieldLength;
-    }
-
-    /*
-     * Return the data CRC.
-     */
-    unsigned long getCRC32(void) const { return mCDE.mCRC32; }
-
-    /*
-     * Return file modification time in UNIX seconds-since-epoch.
-     */
-    time_t getModWhen(void) const;
-
-    /*
-     * Return the archived file name.
-     */
-    const char* getFileName(void) const { return (const char*) mCDE.mFileName; }
-
-    /*
-     * Application-defined "mark".  Can be useful when synchronizing the
-     * contents of an archive with contents on disk.
-     */
-    bool getMarked(void) const { return mMarked; }
-    void setMarked(bool val) { mMarked = val; }
-
-    /*
-     * Some basic functions for raw data manipulation.  "LE" means
-     * Little Endian.
-     */
-    static inline unsigned short getShortLE(const unsigned char* buf) {
-        return buf[0] | (buf[1] << 8);
-    }
-    static inline unsigned long getLongLE(const unsigned char* buf) {
-        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
-    }
-    static inline void putShortLE(unsigned char* buf, short val) {
-        buf[0] = (unsigned char) val;
-        buf[1] = (unsigned char) (val >> 8);
-    }
-    static inline void putLongLE(unsigned char* buf, long val) {
-        buf[0] = (unsigned char) val;
-        buf[1] = (unsigned char) (val >> 8);
-        buf[2] = (unsigned char) (val >> 16);
-        buf[3] = (unsigned char) (val >> 24);
-    }
-
-    /* defined for Zip archives */
-    enum {
-        kCompressStored     = 0,        // no compression
-        // shrunk           = 1,
-        // reduced 1        = 2,
-        // reduced 2        = 3,
-        // reduced 3        = 4,
-        // reduced 4        = 5,
-        // imploded         = 6,
-        // tokenized        = 7,
-        kCompressDeflated   = 8,        // standard deflate
-        // Deflate64        = 9,
-        // lib imploded     = 10,
-        // reserved         = 11,
-        // bzip2            = 12,
-    };
-
-    /*
-     * Deletion flag.  If set, the entry will be removed on the next
-     * call to "flush".
-     */
-    bool getDeleted(void) const { return mDeleted; }
-
-protected:
-    /*
-     * Initialize the structure from the file, which is pointing at
-     * our Central Directory entry.
-     */
-    status_t initFromCDE(FILE* fp);
-
-    /*
-     * Initialize the structure for a new file.  We need the filename
-     * and comment so that we can properly size the LFH area.  The
-     * filename is mandatory, the comment is optional.
-     */
-    void initNew(const char* fileName, const char* comment);
-
-    /*
-     * Initialize the structure with the contents of a ZipEntry from
-     * another file.
-     */
-    status_t initFromExternal(const ZipFile* pZipFile, const ZipEntry* pEntry);
-
-    /*
-     * Add some pad bytes to the LFH.  We do this by adding or resizing
-     * the "extra" field.
-     */
-    status_t addPadding(int padding);
-
-    /*
-     * Set information about the data for this entry.
-     */
-    void setDataInfo(long uncompLen, long compLen, unsigned long crc32,
-        int compressionMethod);
-
-    /*
-     * Set the modification date.
-     */
-    void setModWhen(time_t when);
-
-    /*
-     * Set the offset of the local file header, relative to the start of
-     * the current file.
-     */
-    void setLFHOffset(off_t offset) {
-        mCDE.mLocalHeaderRelOffset = (long) offset;
-    }
-
-    /* mark for deletion; used by ZipFile::remove() */
-    void setDeleted(void) { mDeleted = true; }
-
-private:
-    /* these are private and not defined */
-    ZipEntry(const ZipEntry& src);
-    ZipEntry& operator=(const ZipEntry& src);
-
-    /* returns "true" if the CDE and the LFH agree */
-    bool compareHeaders(void) const;
-    void copyCDEtoLFH(void);
-
-    bool        mDeleted;       // set if entry is pending deletion
-    bool        mMarked;        // app-defined marker
-
-    /*
-     * Every entry in the Zip archive starts off with one of these.
-     */
-    class LocalFileHeader {
-    public:
-        LocalFileHeader(void) :
-            mVersionToExtract(0),
-            mGPBitFlag(0),
-            mCompressionMethod(0),
-            mLastModFileTime(0),
-            mLastModFileDate(0),
-            mCRC32(0),
-            mCompressedSize(0),
-            mUncompressedSize(0),
-            mFileNameLength(0),
-            mExtraFieldLength(0),
-            mFileName(NULL),
-            mExtraField(NULL)
-        {}
-        virtual ~LocalFileHeader(void) {
-            delete[] mFileName;
-            delete[] mExtraField;
-        }
-
-        status_t read(FILE* fp);
-        status_t write(FILE* fp);
-
-        // unsigned long mSignature;
-        unsigned short  mVersionToExtract;
-        unsigned short  mGPBitFlag;
-        unsigned short  mCompressionMethod;
-        unsigned short  mLastModFileTime;
-        unsigned short  mLastModFileDate;
-        unsigned long   mCRC32;
-        unsigned long   mCompressedSize;
-        unsigned long   mUncompressedSize;
-        unsigned short  mFileNameLength;
-        unsigned short  mExtraFieldLength;
-        unsigned char*  mFileName;
-        unsigned char*  mExtraField;
-
-        enum {
-            kSignature      = 0x04034b50,
-            kLFHLen         = 30,       // LocalFileHdr len, excl. var fields
-        };
-
-        void dump(void) const;
-    };
-
-    /*
-     * Every entry in the Zip archive has one of these in the "central
-     * directory" at the end of the file.
-     */
-    class CentralDirEntry {
-    public:
-        CentralDirEntry(void) :
-            mVersionMadeBy(0),
-            mVersionToExtract(0),
-            mGPBitFlag(0),
-            mCompressionMethod(0),
-            mLastModFileTime(0),
-            mLastModFileDate(0),
-            mCRC32(0),
-            mCompressedSize(0),
-            mUncompressedSize(0),
-            mFileNameLength(0),
-            mExtraFieldLength(0),
-            mFileCommentLength(0),
-            mDiskNumberStart(0),
-            mInternalAttrs(0),
-            mExternalAttrs(0),
-            mLocalHeaderRelOffset(0),
-            mFileName(NULL),
-            mExtraField(NULL),
-            mFileComment(NULL)
-        {}
-        virtual ~CentralDirEntry(void) {
-            delete[] mFileName;
-            delete[] mExtraField;
-            delete[] mFileComment;
-        }
-
-        status_t read(FILE* fp);
-        status_t write(FILE* fp);
-
-        // unsigned long mSignature;
-        unsigned short  mVersionMadeBy;
-        unsigned short  mVersionToExtract;
-        unsigned short  mGPBitFlag;
-        unsigned short  mCompressionMethod;
-        unsigned short  mLastModFileTime;
-        unsigned short  mLastModFileDate;
-        unsigned long   mCRC32;
-        unsigned long   mCompressedSize;
-        unsigned long   mUncompressedSize;
-        unsigned short  mFileNameLength;
-        unsigned short  mExtraFieldLength;
-        unsigned short  mFileCommentLength;
-        unsigned short  mDiskNumberStart;
-        unsigned short  mInternalAttrs;
-        unsigned long   mExternalAttrs;
-        unsigned long   mLocalHeaderRelOffset;
-        unsigned char*  mFileName;
-        unsigned char*  mExtraField;
-        unsigned char*  mFileComment;
-
-        void dump(void) const;
-
-        enum {
-            kSignature      = 0x02014b50,
-            kCDELen         = 46,       // CentralDirEnt len, excl. var fields
-        };
-    };
-
-    enum {
-        //kDataDescriptorSignature  = 0x08074b50,   // currently unused
-        kDataDescriptorLen  = 16,           // four 32-bit fields
-
-        kDefaultVersion     = 20,           // need deflate, nothing much else
-        kDefaultMadeBy      = 0x0317,       // 03=UNIX, 17=spec v2.3
-        kUsesDataDescr      = 0x0008,       // GPBitFlag bit 3
-    };
-
-    LocalFileHeader     mLFH;
-    CentralDirEntry     mCDE;
-};
-
-}; // namespace android
-
-#endif // __LIBS_ZIPENTRY_H
diff --git a/tools/aapt/ZipFile.cpp b/tools/aapt/ZipFile.cpp
deleted file mode 100644
index 8057068..0000000
--- a/tools/aapt/ZipFile.cpp
+++ /dev/null
@@ -1,1297 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Access to Zip archives.
-//
-
-#define LOG_TAG "zip"
-
-#include <androidfw/ZipUtils.h>
-#include <utils/Log.h>
-
-#include "ZipFile.h"
-
-#include <zlib.h>
-#define DEF_MEM_LEVEL 8                // normally in zutil.h?
-
-#include <memory.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <assert.h>
-
-using namespace android;
-
-/*
- * Some environments require the "b", some choke on it.
- */
-#define FILE_OPEN_RO        "rb"
-#define FILE_OPEN_RW        "r+b"
-#define FILE_OPEN_RW_CREATE "w+b"
-
-/* should live somewhere else? */
-static status_t errnoToStatus(int err)
-{
-    if (err == ENOENT)
-        return NAME_NOT_FOUND;
-    else if (err == EACCES)
-        return PERMISSION_DENIED;
-    else
-        return UNKNOWN_ERROR;
-}
-
-/*
- * Open a file and parse its guts.
- */
-status_t ZipFile::open(const char* zipFileName, int flags)
-{
-    bool newArchive = false;
-
-    assert(mZipFp == NULL);     // no reopen
-
-    if ((flags & kOpenTruncate))
-        flags |= kOpenCreate;           // trunc implies create
-
-    if ((flags & kOpenReadOnly) && (flags & kOpenReadWrite))
-        return INVALID_OPERATION;       // not both
-    if (!((flags & kOpenReadOnly) || (flags & kOpenReadWrite)))
-        return INVALID_OPERATION;       // not neither
-    if ((flags & kOpenCreate) && !(flags & kOpenReadWrite))
-        return INVALID_OPERATION;       // create requires write
-
-    if (flags & kOpenTruncate) {
-        newArchive = true;
-    } else {
-        newArchive = (access(zipFileName, F_OK) != 0);
-        if (!(flags & kOpenCreate) && newArchive) {
-            /* not creating, must already exist */
-            ALOGD("File %s does not exist", zipFileName);
-            return NAME_NOT_FOUND;
-        }
-    }
-
-    /* open the file */
-    const char* openflags;
-    if (flags & kOpenReadWrite) {
-        if (newArchive)
-            openflags = FILE_OPEN_RW_CREATE;
-        else
-            openflags = FILE_OPEN_RW;
-    } else {
-        openflags = FILE_OPEN_RO;
-    }
-    mZipFp = fopen(zipFileName, openflags);
-    if (mZipFp == NULL) {
-        int err = errno;
-        ALOGD("fopen failed: %d\n", err);
-        return errnoToStatus(err);
-    }
-
-    status_t result;
-    if (!newArchive) {
-        /*
-         * Load the central directory.  If that fails, then this probably
-         * isn't a Zip archive.
-         */
-        result = readCentralDir();
-    } else {
-        /*
-         * Newly-created.  The EndOfCentralDir constructor actually
-         * sets everything to be the way we want it (all zeroes).  We
-         * set mNeedCDRewrite so that we create *something* if the
-         * caller doesn't add any files.  (We could also just unlink
-         * the file if it's brand new and nothing was added, but that's
-         * probably doing more than we really should -- the user might
-         * have a need for empty zip files.)
-         */
-        mNeedCDRewrite = true;
-        result = NO_ERROR;
-    }
-
-    if (flags & kOpenReadOnly)
-        mReadOnly = true;
-    else
-        assert(!mReadOnly);
-
-    return result;
-}
-
-/*
- * Return the Nth entry in the archive.
- */
-ZipEntry* ZipFile::getEntryByIndex(int idx) const
-{
-    if (idx < 0 || idx >= (int) mEntries.size())
-        return NULL;
-
-    return mEntries[idx];
-}
-
-/*
- * Find an entry by name.
- */
-ZipEntry* ZipFile::getEntryByName(const char* fileName) const
-{
-    /*
-     * Do a stupid linear string-compare search.
-     *
-     * There are various ways to speed this up, especially since it's rare
-     * to intermingle changes to the archive with "get by name" calls.  We
-     * don't want to sort the mEntries vector itself, however, because
-     * it's used to recreate the Central Directory.
-     *
-     * (Hash table works, parallel list of pointers in sorted order is good.)
-     */
-    int idx;
-
-    for (idx = mEntries.size()-1; idx >= 0; idx--) {
-        ZipEntry* pEntry = mEntries[idx];
-        if (!pEntry->getDeleted() &&
-            strcmp(fileName, pEntry->getFileName()) == 0)
-        {
-            return pEntry;
-        }
-    }
-
-    return NULL;
-}
-
-/*
- * Empty the mEntries vector.
- */
-void ZipFile::discardEntries(void)
-{
-    int count = mEntries.size();
-
-    while (--count >= 0)
-        delete mEntries[count];
-
-    mEntries.clear();
-}
-
-
-/*
- * Find the central directory and read the contents.
- *
- * The fun thing about ZIP archives is that they may or may not be
- * readable from start to end.  In some cases, notably for archives
- * that were written to stdout, the only length information is in the
- * central directory at the end of the file.
- *
- * Of course, the central directory can be followed by a variable-length
- * comment field, so we have to scan through it backwards.  The comment
- * is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff
- * itself, plus apparently sometimes people throw random junk on the end
- * just for the fun of it.
- *
- * This is all a little wobbly.  If the wrong value ends up in the EOCD
- * area, we're hosed.  This appears to be the way that everbody handles
- * it though, so we're in pretty good company if this fails.
- */
-status_t ZipFile::readCentralDir(void)
-{
-    status_t result = NO_ERROR;
-    unsigned char* buf = NULL;
-    off_t fileLength, seekStart;
-    long readAmount;
-    int i;
-
-    fseek(mZipFp, 0, SEEK_END);
-    fileLength = ftell(mZipFp);
-    rewind(mZipFp);
-
-    /* too small to be a ZIP archive? */
-    if (fileLength < EndOfCentralDir::kEOCDLen) {
-        ALOGD("Length is %ld -- too small\n", (long)fileLength);
-        result = INVALID_OPERATION;
-        goto bail;
-    }
-
-    buf = new unsigned char[EndOfCentralDir::kMaxEOCDSearch];
-    if (buf == NULL) {
-        ALOGD("Failure allocating %d bytes for EOCD search",
-             EndOfCentralDir::kMaxEOCDSearch);
-        result = NO_MEMORY;
-        goto bail;
-    }
-
-    if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {
-        seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;
-        readAmount = EndOfCentralDir::kMaxEOCDSearch;
-    } else {
-        seekStart = 0;
-        readAmount = (long) fileLength;
-    }
-    if (fseek(mZipFp, seekStart, SEEK_SET) != 0) {
-        ALOGD("Failure seeking to end of zip at %ld", (long) seekStart);
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    /* read the last part of the file into the buffer */
-    if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) {
-        ALOGD("short file? wanted %ld\n", readAmount);
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    /* find the end-of-central-dir magic */
-    for (i = readAmount - 4; i >= 0; i--) {
-        if (buf[i] == 0x50 &&
-            ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)
-        {
-            ALOGV("+++ Found EOCD at buf+%d\n", i);
-            break;
-        }
-    }
-    if (i < 0) {
-        ALOGD("EOCD not found, not Zip\n");
-        result = INVALID_OPERATION;
-        goto bail;
-    }
-
-    /* extract eocd values */
-    result = mEOCD.readBuf(buf + i, readAmount - i);
-    if (result != NO_ERROR) {
-        ALOGD("Failure reading %ld bytes of EOCD values", readAmount - i);
-        goto bail;
-    }
-    //mEOCD.dump();
-
-    if (mEOCD.mDiskNumber != 0 || mEOCD.mDiskWithCentralDir != 0 ||
-        mEOCD.mNumEntries != mEOCD.mTotalNumEntries)
-    {
-        ALOGD("Archive spanning not supported\n");
-        result = INVALID_OPERATION;
-        goto bail;
-    }
-
-    /*
-     * So far so good.  "mCentralDirSize" is the size in bytes of the
-     * central directory, so we can just seek back that far to find it.
-     * We can also seek forward mCentralDirOffset bytes from the
-     * start of the file.
-     *
-     * We're not guaranteed to have the rest of the central dir in the
-     * buffer, nor are we guaranteed that the central dir will have any
-     * sort of convenient size.  We need to skip to the start of it and
-     * read the header, then the other goodies.
-     *
-     * The only thing we really need right now is the file comment, which
-     * we're hoping to preserve.
-     */
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
-        ALOGD("Failure seeking to central dir offset %ld\n",
-             mEOCD.mCentralDirOffset);
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    /*
-     * Loop through and read the central dir entries.
-     */
-    ALOGV("Scanning %d entries...\n", mEOCD.mTotalNumEntries);
-    int entry;
-    for (entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {
-        ZipEntry* pEntry = new ZipEntry;
-
-        result = pEntry->initFromCDE(mZipFp);
-        if (result != NO_ERROR) {
-            ALOGD("initFromCDE failed\n");
-            delete pEntry;
-            goto bail;
-        }
-
-        mEntries.add(pEntry);
-    }
-
-
-    /*
-     * If all went well, we should now be back at the EOCD.
-     */
-    {
-        unsigned char checkBuf[4];
-        if (fread(checkBuf, 1, 4, mZipFp) != 4) {
-            ALOGD("EOCD check read failed\n");
-            result = INVALID_OPERATION;
-            goto bail;
-        }
-        if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {
-            ALOGD("EOCD read check failed\n");
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-        ALOGV("+++ EOCD read check passed\n");
-    }
-
-bail:
-    delete[] buf;
-    return result;
-}
-
-
-/*
- * Add a new file to the archive.
- *
- * This requires creating and populating a ZipEntry structure, and copying
- * the data into the file at the appropriate position.  The "appropriate
- * position" is the current location of the central directory, which we
- * casually overwrite (we can put it back later).
- *
- * If we were concerned about safety, we would want to make all changes
- * in a temp file and then overwrite the original after everything was
- * safely written.  Not really a concern for us.
- */
-status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size,
-    const char* storageName, int sourceType, int compressionMethod,
-    ZipEntry** ppEntry)
-{
-    ZipEntry* pEntry = NULL;
-    status_t result = NO_ERROR;
-    long lfhPosn, startPosn, endPosn, uncompressedLen;
-    FILE* inputFp = NULL;
-    unsigned long crc;
-    time_t modWhen;
-
-    if (mReadOnly)
-        return INVALID_OPERATION;
-
-    assert(compressionMethod == ZipEntry::kCompressDeflated ||
-           compressionMethod == ZipEntry::kCompressStored);
-
-    /* make sure we're in a reasonable state */
-    assert(mZipFp != NULL);
-    assert(mEntries.size() == mEOCD.mTotalNumEntries);
-
-    /* make sure it doesn't already exist */
-    if (getEntryByName(storageName) != NULL)
-        return ALREADY_EXISTS;
-
-    if (!data) {
-        inputFp = fopen(fileName, FILE_OPEN_RO);
-        if (inputFp == NULL)
-            return errnoToStatus(errno);
-    }
-
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    pEntry = new ZipEntry;
-    pEntry->initNew(storageName, NULL);
-
-    /*
-     * From here on out, failures are more interesting.
-     */
-    mNeedCDRewrite = true;
-
-    /*
-     * Write the LFH, even though it's still mostly blank.  We need it
-     * as a place-holder.  In theory the LFH isn't necessary, but in
-     * practice some utilities demand it.
-     */
-    lfhPosn = ftell(mZipFp);
-    pEntry->mLFH.write(mZipFp);
-    startPosn = ftell(mZipFp);
-
-    /*
-     * Copy the data in, possibly compressing it as we go.
-     */
-    if (sourceType == ZipEntry::kCompressStored) {
-        if (compressionMethod == ZipEntry::kCompressDeflated) {
-            bool failed = false;
-            result = compressFpToFp(mZipFp, inputFp, data, size, &crc);
-            if (result != NO_ERROR) {
-                ALOGD("compression failed, storing\n");
-                failed = true;
-            } else {
-                /*
-                 * Make sure it has compressed "enough".  This probably ought
-                 * to be set through an API call, but I don't expect our
-                 * criteria to change over time.
-                 */
-                long src = inputFp ? ftell(inputFp) : size;
-                long dst = ftell(mZipFp) - startPosn;
-                if (dst + (dst / 10) > src) {
-                    ALOGD("insufficient compression (src=%ld dst=%ld), storing\n",
-                        src, dst);
-                    failed = true;
-                }
-            }
-
-            if (failed) {
-                compressionMethod = ZipEntry::kCompressStored;
-                if (inputFp) rewind(inputFp);
-                fseek(mZipFp, startPosn, SEEK_SET);
-                /* fall through to kCompressStored case */
-            }
-        }
-        /* handle "no compression" request, or failed compression from above */
-        if (compressionMethod == ZipEntry::kCompressStored) {
-            if (inputFp) {
-                result = copyFpToFp(mZipFp, inputFp, &crc);
-            } else {
-                result = copyDataToFp(mZipFp, data, size, &crc);
-            }
-            if (result != NO_ERROR) {
-                // don't need to truncate; happens in CDE rewrite
-                ALOGD("failed copying data in\n");
-                goto bail;
-            }
-        }
-
-        // currently seeked to end of file
-        uncompressedLen = inputFp ? ftell(inputFp) : size;
-    } else if (sourceType == ZipEntry::kCompressDeflated) {
-        /* we should support uncompressed-from-compressed, but it's not
-         * important right now */
-        assert(compressionMethod == ZipEntry::kCompressDeflated);
-
-        bool scanResult;
-        int method;
-        long compressedLen;
-
-        scanResult = ZipUtils::examineGzip(inputFp, &method, &uncompressedLen,
-                        &compressedLen, &crc);
-        if (!scanResult || method != ZipEntry::kCompressDeflated) {
-            ALOGD("this isn't a deflated gzip file?");
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-
-        result = copyPartialFpToFp(mZipFp, inputFp, compressedLen, NULL);
-        if (result != NO_ERROR) {
-            ALOGD("failed copying gzip data in\n");
-            goto bail;
-        }
-    } else {
-        assert(false);
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    /*
-     * We could write the "Data Descriptor", but there doesn't seem to
-     * be any point since we're going to go back and write the LFH.
-     *
-     * Update file offsets.
-     */
-    endPosn = ftell(mZipFp);            // seeked to end of compressed data
-
-    /*
-     * Success!  Fill out new values.
-     */
-    pEntry->setDataInfo(uncompressedLen, endPosn - startPosn, crc,
-        compressionMethod);
-    modWhen = getModTime(inputFp ? fileno(inputFp) : fileno(mZipFp));
-    pEntry->setModWhen(modWhen);
-    pEntry->setLFHOffset(lfhPosn);
-    mEOCD.mNumEntries++;
-    mEOCD.mTotalNumEntries++;
-    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
-    mEOCD.mCentralDirOffset = endPosn;
-
-    /*
-     * Go back and write the LFH.
-     */
-    if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-    pEntry->mLFH.write(mZipFp);
-
-    /*
-     * Add pEntry to the list.
-     */
-    mEntries.add(pEntry);
-    if (ppEntry != NULL)
-        *ppEntry = pEntry;
-    pEntry = NULL;
-
-bail:
-    if (inputFp != NULL)
-        fclose(inputFp);
-    delete pEntry;
-    return result;
-}
-
-/*
- * Add an entry by copying it from another zip file.  If "padding" is
- * nonzero, the specified number of bytes will be added to the "extra"
- * field in the header.
- *
- * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
- */
-status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
-    int padding, ZipEntry** ppEntry)
-{
-    ZipEntry* pEntry = NULL;
-    status_t result;
-    long lfhPosn, endPosn;
-
-    if (mReadOnly)
-        return INVALID_OPERATION;
-
-    /* make sure we're in a reasonable state */
-    assert(mZipFp != NULL);
-    assert(mEntries.size() == mEOCD.mTotalNumEntries);
-
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    pEntry = new ZipEntry;
-    if (pEntry == NULL) {
-        result = NO_MEMORY;
-        goto bail;
-    }
-
-    result = pEntry->initFromExternal(pSourceZip, pSourceEntry);
-    if (result != NO_ERROR)
-        goto bail;
-    if (padding != 0) {
-        result = pEntry->addPadding(padding);
-        if (result != NO_ERROR)
-            goto bail;
-    }
-
-    /*
-     * From here on out, failures are more interesting.
-     */
-    mNeedCDRewrite = true;
-
-    /*
-     * Write the LFH.  Since we're not recompressing the data, we already
-     * have all of the fields filled out.
-     */
-    lfhPosn = ftell(mZipFp);
-    pEntry->mLFH.write(mZipFp);
-
-    /*
-     * Copy the data over.
-     *
-     * If the "has data descriptor" flag is set, we want to copy the DD
-     * fields as well.  This is a fixed-size area immediately following
-     * the data.
-     */
-    if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)
-    {
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    off_t copyLen;
-    copyLen = pSourceEntry->getCompressedLen();
-    if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)
-        copyLen += ZipEntry::kDataDescriptorLen;
-
-    if (copyPartialFpToFp(mZipFp, pSourceZip->mZipFp, copyLen, NULL)
-        != NO_ERROR)
-    {
-        ALOGW("copy of '%s' failed\n", pEntry->mCDE.mFileName);
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    /*
-     * Update file offsets.
-     */
-    endPosn = ftell(mZipFp);
-
-    /*
-     * Success!  Fill out new values.
-     */
-    pEntry->setLFHOffset(lfhPosn);      // sets mCDE.mLocalHeaderRelOffset
-    mEOCD.mNumEntries++;
-    mEOCD.mTotalNumEntries++;
-    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
-    mEOCD.mCentralDirOffset = endPosn;
-
-    /*
-     * Add pEntry to the list.
-     */
-    mEntries.add(pEntry);
-    if (ppEntry != NULL)
-        *ppEntry = pEntry;
-    pEntry = NULL;
-
-    result = NO_ERROR;
-
-bail:
-    delete pEntry;
-    return result;
-}
-
-/*
- * Copy all of the bytes in "src" to "dst".
- *
- * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
- * will be seeked immediately past the data.
- */
-status_t ZipFile::copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32)
-{
-    unsigned char tmpBuf[32768];
-    size_t count;
-
-    *pCRC32 = crc32(0L, Z_NULL, 0);
-
-    while (1) {
-        count = fread(tmpBuf, 1, sizeof(tmpBuf), srcFp);
-        if (ferror(srcFp) || ferror(dstFp))
-            return errnoToStatus(errno);
-        if (count == 0)
-            break;
-
-        *pCRC32 = crc32(*pCRC32, tmpBuf, count);
-
-        if (fwrite(tmpBuf, 1, count, dstFp) != count) {
-            ALOGD("fwrite %d bytes failed\n", (int) count);
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Copy all of the bytes in "src" to "dst".
- *
- * On exit, "dstFp" will be seeked immediately past the data.
- */
-status_t ZipFile::copyDataToFp(FILE* dstFp,
-    const void* data, size_t size, unsigned long* pCRC32)
-{
-    size_t count;
-
-    *pCRC32 = crc32(0L, Z_NULL, 0);
-    if (size > 0) {
-        *pCRC32 = crc32(*pCRC32, (const unsigned char*)data, size);
-        if (fwrite(data, 1, size, dstFp) != size) {
-            ALOGD("fwrite %d bytes failed\n", (int) size);
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Copy some of the bytes in "src" to "dst".
- *
- * If "pCRC32" is NULL, the CRC will not be computed.
- *
- * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
- * will be seeked immediately past the data just written.
- */
-status_t ZipFile::copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,
-    unsigned long* pCRC32)
-{
-    unsigned char tmpBuf[32768];
-    size_t count;
-
-    if (pCRC32 != NULL)
-        *pCRC32 = crc32(0L, Z_NULL, 0);
-
-    while (length) {
-        long readSize;
-        
-        readSize = sizeof(tmpBuf);
-        if (readSize > length)
-            readSize = length;
-
-        count = fread(tmpBuf, 1, readSize, srcFp);
-        if ((long) count != readSize) {     // error or unexpected EOF
-            ALOGD("fread %d bytes failed\n", (int) readSize);
-            return UNKNOWN_ERROR;
-        }
-
-        if (pCRC32 != NULL)
-            *pCRC32 = crc32(*pCRC32, tmpBuf, count);
-
-        if (fwrite(tmpBuf, 1, count, dstFp) != count) {
-            ALOGD("fwrite %d bytes failed\n", (int) count);
-            return UNKNOWN_ERROR;
-        }
-
-        length -= readSize;
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Compress all of the data in "srcFp" and write it to "dstFp".
- *
- * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
- * will be seeked immediately past the compressed data.
- */
-status_t ZipFile::compressFpToFp(FILE* dstFp, FILE* srcFp,
-    const void* data, size_t size, unsigned long* pCRC32)
-{
-    status_t result = NO_ERROR;
-    const size_t kBufSize = 32768;
-    unsigned char* inBuf = NULL;
-    unsigned char* outBuf = NULL;
-    z_stream zstream;
-    bool atEof = false;     // no feof() aviailable yet
-    unsigned long crc;
-    int zerr;
-
-    /*
-     * Create an input buffer and an output buffer.
-     */
-    inBuf = new unsigned char[kBufSize];
-    outBuf = new unsigned char[kBufSize];
-    if (inBuf == NULL || outBuf == NULL) {
-        result = NO_MEMORY;
-        goto bail;
-    }
-
-    /*
-     * Initialize the zlib stream.
-     */
-    memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = NULL;
-    zstream.avail_in = 0;
-    zstream.next_out = outBuf;
-    zstream.avail_out = kBufSize;
-    zstream.data_type = Z_UNKNOWN;
-
-    zerr = deflateInit2(&zstream, Z_BEST_COMPRESSION,
-        Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
-    if (zerr != Z_OK) {
-        result = UNKNOWN_ERROR;
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGD("Call to deflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    crc = crc32(0L, Z_NULL, 0);
-
-    /*
-     * Loop while we have data.
-     */
-    do {
-        size_t getSize;
-        int flush;
-
-        /* only read if the input buffer is empty */
-        if (zstream.avail_in == 0 && !atEof) {
-            ALOGV("+++ reading %d bytes\n", (int)kBufSize);
-            if (data) {
-                getSize = size > kBufSize ? kBufSize : size;
-                memcpy(inBuf, data, getSize);
-                data = ((const char*)data) + getSize;
-                size -= getSize;
-            } else {
-                getSize = fread(inBuf, 1, kBufSize, srcFp);
-                if (ferror(srcFp)) {
-                    ALOGD("deflate read failed (errno=%d)\n", errno);
-                    goto z_bail;
-                }
-            }
-            if (getSize < kBufSize) {
-                ALOGV("+++  got %d bytes, EOF reached\n",
-                    (int)getSize);
-                atEof = true;
-            }
-
-            crc = crc32(crc, inBuf, getSize);
-
-            zstream.next_in = inBuf;
-            zstream.avail_in = getSize;
-        }
-
-        if (atEof)
-            flush = Z_FINISH;       /* tell zlib that we're done */
-        else
-            flush = Z_NO_FLUSH;     /* more to come! */
-
-        zerr = deflate(&zstream, flush);
-        if (zerr != Z_OK && zerr != Z_STREAM_END) {
-            ALOGD("zlib deflate call failed (zerr=%d)\n", zerr);
-            result = UNKNOWN_ERROR;
-            goto z_bail;
-        }
-
-        /* write when we're full or when we're done */
-        if (zstream.avail_out == 0 ||
-            (zerr == Z_STREAM_END && zstream.avail_out != (uInt) kBufSize))
-        {
-            ALOGV("+++ writing %d bytes\n", (int) (zstream.next_out - outBuf));
-            if (fwrite(outBuf, 1, zstream.next_out - outBuf, dstFp) !=
-                (size_t)(zstream.next_out - outBuf))
-            {
-                ALOGD("write %d failed in deflate\n",
-                    (int) (zstream.next_out - outBuf));
-                goto z_bail;
-            }
-
-            zstream.next_out = outBuf;
-            zstream.avail_out = kBufSize;
-        }
-    } while (zerr == Z_OK);
-
-    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
-
-    *pCRC32 = crc;
-
-z_bail:
-    deflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-    delete[] inBuf;
-    delete[] outBuf;
-
-    return result;
-}
-
-/*
- * Mark an entry as deleted.
- *
- * We will eventually need to crunch the file down, but if several files
- * are being removed (perhaps as part of an "update" process) we can make
- * things considerably faster by deferring the removal to "flush" time.
- */
-status_t ZipFile::remove(ZipEntry* pEntry)
-{
-    /*
-     * Should verify that pEntry is actually part of this archive, and
-     * not some stray ZipEntry from a different file.
-     */
-
-    /* mark entry as deleted, and mark archive as dirty */
-    pEntry->setDeleted();
-    mNeedCDRewrite = true;
-    return NO_ERROR;
-}
-
-/*
- * Flush any pending writes.
- *
- * In particular, this will crunch out deleted entries, and write the
- * Central Directory and EOCD if we have stomped on them.
- */
-status_t ZipFile::flush(void)
-{
-    status_t result = NO_ERROR;
-    long eocdPosn;
-    int i, count;
-
-    if (mReadOnly)
-        return INVALID_OPERATION;
-    if (!mNeedCDRewrite)
-        return NO_ERROR;
-
-    assert(mZipFp != NULL);
-
-    result = crunchArchive();
-    if (result != NO_ERROR)
-        return result;
-
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0)
-        return UNKNOWN_ERROR;
-
-    count = mEntries.size();
-    for (i = 0; i < count; i++) {
-        ZipEntry* pEntry = mEntries[i];
-        pEntry->mCDE.write(mZipFp);
-    }
-
-    eocdPosn = ftell(mZipFp);
-    mEOCD.mCentralDirSize = eocdPosn - mEOCD.mCentralDirOffset;
-
-    mEOCD.write(mZipFp);
-
-    /*
-     * If we had some stuff bloat up during compression and get replaced
-     * with plain files, or if we deleted some entries, there's a lot
-     * of wasted space at the end of the file.  Remove it now.
-     */
-    if (ftruncate(fileno(mZipFp), ftell(mZipFp)) != 0) {
-        ALOGW("ftruncate failed %ld: %s\n", ftell(mZipFp), strerror(errno));
-        // not fatal
-    }
-
-    /* should we clear the "newly added" flag in all entries now? */
-
-    mNeedCDRewrite = false;
-    return NO_ERROR;
-}
-
-/*
- * Crunch deleted files out of an archive by shifting the later files down.
- *
- * Because we're not using a temp file, we do the operation inside the
- * current file.
- */
-status_t ZipFile::crunchArchive(void)
-{
-    status_t result = NO_ERROR;
-    int i, count;
-    long delCount, adjust;
-
-#if 0
-    printf("CONTENTS:\n");
-    for (i = 0; i < (int) mEntries.size(); i++) {
-        printf(" %d: lfhOff=%ld del=%d\n",
-            i, mEntries[i]->getLFHOffset(), mEntries[i]->getDeleted());
-    }
-    printf("  END is %ld\n", (long) mEOCD.mCentralDirOffset);
-#endif
-
-    /*
-     * Roll through the set of files, shifting them as appropriate.  We
-     * could probably get a slight performance improvement by sliding
-     * multiple files down at once (because we could use larger reads
-     * when operating on batches of small files), but it's not that useful.
-     */
-    count = mEntries.size();
-    delCount = adjust = 0;
-    for (i = 0; i < count; i++) {
-        ZipEntry* pEntry = mEntries[i];
-        long span;
-
-        if (pEntry->getLFHOffset() != 0) {
-            long nextOffset;
-
-            /* Get the length of this entry by finding the offset
-             * of the next entry.  Directory entries don't have
-             * file offsets, so we need to find the next non-directory
-             * entry.
-             */
-            nextOffset = 0;
-            for (int ii = i+1; nextOffset == 0 && ii < count; ii++)
-                nextOffset = mEntries[ii]->getLFHOffset();
-            if (nextOffset == 0)
-                nextOffset = mEOCD.mCentralDirOffset;
-            span = nextOffset - pEntry->getLFHOffset();
-
-            assert(span >= ZipEntry::LocalFileHeader::kLFHLen);
-        } else {
-            /* This is a directory entry.  It doesn't have
-             * any actual file contents, so there's no need to
-             * move anything.
-             */
-            span = 0;
-        }
-
-        //printf("+++ %d: off=%ld span=%ld del=%d [count=%d]\n",
-        //    i, pEntry->getLFHOffset(), span, pEntry->getDeleted(), count);
-
-        if (pEntry->getDeleted()) {
-            adjust += span;
-            delCount++;
-
-            delete pEntry;
-            mEntries.removeAt(i);
-
-            /* adjust loop control */
-            count--;
-            i--;
-        } else if (span != 0 && adjust > 0) {
-            /* shuffle this entry back */
-            //printf("+++ Shuffling '%s' back %ld\n",
-            //    pEntry->getFileName(), adjust);
-            result = filemove(mZipFp, pEntry->getLFHOffset() - adjust,
-                        pEntry->getLFHOffset(), span);
-            if (result != NO_ERROR) {
-                /* this is why you use a temp file */
-                ALOGE("error during crunch - archive is toast\n");
-                return result;
-            }
-
-            pEntry->setLFHOffset(pEntry->getLFHOffset() - adjust);
-        }
-    }
-
-    /*
-     * Fix EOCD info.  We have to wait until the end to do some of this
-     * because we use mCentralDirOffset to determine "span" for the
-     * last entry.
-     */
-    mEOCD.mCentralDirOffset -= adjust;
-    mEOCD.mNumEntries -= delCount;
-    mEOCD.mTotalNumEntries -= delCount;
-    mEOCD.mCentralDirSize = 0;  // mark invalid; set by flush()
-
-    assert(mEOCD.mNumEntries == mEOCD.mTotalNumEntries);
-    assert(mEOCD.mNumEntries == count);
-
-    return result;
-}
-
-/*
- * Works like memmove(), but on pieces of a file.
- */
-status_t ZipFile::filemove(FILE* fp, off_t dst, off_t src, size_t n)
-{
-    if (dst == src || n <= 0)
-        return NO_ERROR;
-
-    unsigned char readBuf[32768];
-
-    if (dst < src) {
-        /* shift stuff toward start of file; must read from start */
-        while (n != 0) {
-            size_t getSize = sizeof(readBuf);
-            if (getSize > n)
-                getSize = n;
-
-            if (fseek(fp, (long) src, SEEK_SET) != 0) {
-                ALOGD("filemove src seek %ld failed\n", (long) src);
-                return UNKNOWN_ERROR;
-            }
-
-            if (fread(readBuf, 1, getSize, fp) != getSize) {
-                ALOGD("filemove read %ld off=%ld failed\n",
-                    (long) getSize, (long) src);
-                return UNKNOWN_ERROR;
-            }
-
-            if (fseek(fp, (long) dst, SEEK_SET) != 0) {
-                ALOGD("filemove dst seek %ld failed\n", (long) dst);
-                return UNKNOWN_ERROR;
-            }
-
-            if (fwrite(readBuf, 1, getSize, fp) != getSize) {
-                ALOGD("filemove write %ld off=%ld failed\n",
-                    (long) getSize, (long) dst);
-                return UNKNOWN_ERROR;
-            }
-
-            src += getSize;
-            dst += getSize;
-            n -= getSize;
-        }
-    } else {
-        /* shift stuff toward end of file; must read from end */
-        assert(false);      // write this someday, maybe
-        return UNKNOWN_ERROR;
-    }
-
-    return NO_ERROR;
-}
-
-
-/*
- * Get the modification time from a file descriptor.
- */
-time_t ZipFile::getModTime(int fd)
-{
-    struct stat sb;
-
-    if (fstat(fd, &sb) < 0) {
-        ALOGD("HEY: fstat on fd %d failed\n", fd);
-        return (time_t) -1;
-    }
-
-    return sb.st_mtime;
-}
-
-
-#if 0       /* this is a bad idea */
-/*
- * Get a copy of the Zip file descriptor.
- *
- * We don't allow this if the file was opened read-write because we tend
- * to leave the file contents in an uncertain state between calls to
- * flush().  The duplicated file descriptor should only be valid for reads.
- */
-int ZipFile::getZipFd(void) const
-{
-    if (!mReadOnly)
-        return INVALID_OPERATION;
-    assert(mZipFp != NULL);
-
-    int fd;
-    fd = dup(fileno(mZipFp));
-    if (fd < 0) {
-        ALOGD("didn't work, errno=%d\n", errno);
-    }
-
-    return fd;
-}
-#endif
-
-
-#if 0
-/*
- * Expand data.
- */
-bool ZipFile::uncompress(const ZipEntry* pEntry, void* buf) const
-{
-    return false;
-}
-#endif
-
-// free the memory when you're done
-void* ZipFile::uncompress(const ZipEntry* entry)
-{
-    size_t unlen = entry->getUncompressedLen();
-    size_t clen = entry->getCompressedLen();
-
-    void* buf = malloc(unlen);
-    if (buf == NULL) {
-        return NULL;
-    }
-
-    fseek(mZipFp, 0, SEEK_SET);
-
-    off_t offset = entry->getFileOffset();
-    if (fseek(mZipFp, offset, SEEK_SET) != 0) {
-        goto bail;
-    }
-
-    switch (entry->getCompressionMethod())
-    {
-        case ZipEntry::kCompressStored: {
-            ssize_t amt = fread(buf, 1, unlen, mZipFp);
-            if (amt != (ssize_t)unlen) {
-                goto bail;
-            }
-#if 0
-            printf("data...\n");
-            const unsigned char* p = (unsigned char*)buf;
-            const unsigned char* end = p+unlen;
-            for (int i=0; i<32 && p < end; i++) {
-                printf("0x%08x ", (int)(offset+(i*0x10)));
-                for (int j=0; j<0x10 && p < end; j++) {
-                    printf(" %02x", *p);
-                    p++;
-                }
-                printf("\n");
-            }
-#endif
-
-            }
-            break;
-        case ZipEntry::kCompressDeflated: {
-            if (!ZipUtils::inflateToBuffer(mZipFp, buf, unlen, clen)) {
-                goto bail;
-            }
-            }
-            break;
-        default:
-            goto bail;
-    }
-    return buf;
-
-bail:
-    free(buf);
-    return NULL;
-}
-
-
-/*
- * ===========================================================================
- *      ZipFile::EndOfCentralDir
- * ===========================================================================
- */
-
-/*
- * Read the end-of-central-dir fields.
- *
- * "buf" should be positioned at the EOCD signature, and should contain
- * the entire EOCD area including the comment.
- */
-status_t ZipFile::EndOfCentralDir::readBuf(const unsigned char* buf, int len)
-{
-    /* don't allow re-use */
-    assert(mComment == NULL);
-
-    if (len < kEOCDLen) {
-        /* looks like ZIP file got truncated */
-        ALOGD(" Zip EOCD: expected >= %d bytes, found %d\n",
-            kEOCDLen, len);
-        return INVALID_OPERATION;
-    }
-
-    /* this should probably be an assert() */
-    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature)
-        return UNKNOWN_ERROR;
-
-    mDiskNumber = ZipEntry::getShortLE(&buf[0x04]);
-    mDiskWithCentralDir = ZipEntry::getShortLE(&buf[0x06]);
-    mNumEntries = ZipEntry::getShortLE(&buf[0x08]);
-    mTotalNumEntries = ZipEntry::getShortLE(&buf[0x0a]);
-    mCentralDirSize = ZipEntry::getLongLE(&buf[0x0c]);
-    mCentralDirOffset = ZipEntry::getLongLE(&buf[0x10]);
-    mCommentLen = ZipEntry::getShortLE(&buf[0x14]);
-
-    // TODO: validate mCentralDirOffset
-
-    if (mCommentLen > 0) {
-        if (kEOCDLen + mCommentLen > len) {
-            ALOGD("EOCD(%d) + comment(%d) exceeds len (%d)\n",
-                kEOCDLen, mCommentLen, len);
-            return UNKNOWN_ERROR;
-        }
-        mComment = new unsigned char[mCommentLen];
-        memcpy(mComment, buf + kEOCDLen, mCommentLen);
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Write an end-of-central-directory section.
- */
-status_t ZipFile::EndOfCentralDir::write(FILE* fp)
-{
-    unsigned char buf[kEOCDLen];
-
-    ZipEntry::putLongLE(&buf[0x00], kSignature);
-    ZipEntry::putShortLE(&buf[0x04], mDiskNumber);
-    ZipEntry::putShortLE(&buf[0x06], mDiskWithCentralDir);
-    ZipEntry::putShortLE(&buf[0x08], mNumEntries);
-    ZipEntry::putShortLE(&buf[0x0a], mTotalNumEntries);
-    ZipEntry::putLongLE(&buf[0x0c], mCentralDirSize);
-    ZipEntry::putLongLE(&buf[0x10], mCentralDirOffset);
-    ZipEntry::putShortLE(&buf[0x14], mCommentLen);
-
-    if (fwrite(buf, 1, kEOCDLen, fp) != kEOCDLen)
-        return UNKNOWN_ERROR;
-    if (mCommentLen > 0) {
-        assert(mComment != NULL);
-        if (fwrite(mComment, mCommentLen, 1, fp) != mCommentLen)
-            return UNKNOWN_ERROR;
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Dump the contents of an EndOfCentralDir object.
- */
-void ZipFile::EndOfCentralDir::dump(void) const
-{
-    ALOGD(" EndOfCentralDir contents:\n");
-    ALOGD("  diskNum=%u diskWCD=%u numEnt=%u totalNumEnt=%u\n",
-        mDiskNumber, mDiskWithCentralDir, mNumEntries, mTotalNumEntries);
-    ALOGD("  centDirSize=%lu centDirOff=%lu commentLen=%u\n",
-        mCentralDirSize, mCentralDirOffset, mCommentLen);
-}
-
diff --git a/tools/aapt/ZipFile.h b/tools/aapt/ZipFile.h
deleted file mode 100644
index 7877550..0000000
--- a/tools/aapt/ZipFile.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * 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.
- */
-
-//
-// General-purpose Zip archive access.  This class allows both reading and
-// writing to Zip archives, including deletion of existing entries.
-//
-#ifndef __LIBS_ZIPFILE_H
-#define __LIBS_ZIPFILE_H
-
-#include <utils/Vector.h>
-#include <utils/Errors.h>
-#include <stdio.h>
-
-#include "ZipEntry.h"
-
-namespace android {
-
-/*
- * Manipulate a Zip archive.
- *
- * Some changes will not be visible in the until until "flush" is called.
- *
- * The correct way to update a file archive is to make all changes to a
- * copy of the archive in a temporary file, and then unlink/rename over
- * the original after everything completes.  Because we're only interested
- * in using this for packaging, we don't worry about such things.  Crashing
- * after making changes and before flush() completes could leave us with
- * an unusable Zip archive.
- */
-class ZipFile {
-public:
-    ZipFile(void)
-      : mZipFp(NULL), mReadOnly(false), mNeedCDRewrite(false)
-      {}
-    ~ZipFile(void) {
-        if (!mReadOnly)
-            flush();
-        if (mZipFp != NULL)
-            fclose(mZipFp);
-        discardEntries();
-    }
-
-    /*
-     * Open a new or existing archive.
-     */
-    enum {
-        kOpenReadOnly   = 0x01,
-        kOpenReadWrite  = 0x02,
-        kOpenCreate     = 0x04,     // create if it doesn't exist
-        kOpenTruncate   = 0x08,     // if it exists, empty it
-    };
-    status_t open(const char* zipFileName, int flags);
-
-    /*
-     * Add a file to the end of the archive.  Specify whether you want the
-     * library to try to store it compressed.
-     *
-     * If "storageName" is specified, the archive will use that instead
-     * of "fileName".
-     *
-     * If there is already an entry with the same name, the call fails.
-     * Existing entries with the same name must be removed first.
-     *
-     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
-     */
-    status_t add(const char* fileName, int compressionMethod,
-        ZipEntry** ppEntry)
-    {
-        return add(fileName, fileName, compressionMethod, ppEntry);
-    }
-    status_t add(const char* fileName, const char* storageName,
-        int compressionMethod, ZipEntry** ppEntry)
-    {
-        return addCommon(fileName, NULL, 0, storageName,
-                         ZipEntry::kCompressStored,
-                         compressionMethod, ppEntry);
-    }
-
-    /*
-     * Add a file that is already compressed with gzip.
-     *
-     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
-     */
-    status_t addGzip(const char* fileName, const char* storageName,
-        ZipEntry** ppEntry)
-    {
-        return addCommon(fileName, NULL, 0, storageName,
-                         ZipEntry::kCompressDeflated,
-                         ZipEntry::kCompressDeflated, ppEntry);
-    }
-
-    /*
-     * Add a file from an in-memory data buffer.
-     *
-     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
-     */
-    status_t add(const void* data, size_t size, const char* storageName,
-        int compressionMethod, ZipEntry** ppEntry)
-    {
-        return addCommon(NULL, data, size, storageName,
-                         ZipEntry::kCompressStored,
-                         compressionMethod, ppEntry);
-    }
-
-    /*
-     * Add an entry by copying it from another zip file.  If "padding" is
-     * nonzero, the specified number of bytes will be added to the "extra"
-     * field in the header.
-     *
-     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
-     */
-    status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
-        int padding, ZipEntry** ppEntry);
-
-    /*
-     * Mark an entry as having been removed.  It is not actually deleted
-     * from the archive or our internal data structures until flush() is
-     * called.
-     */
-    status_t remove(ZipEntry* pEntry);
-
-    /*
-     * Flush changes.  If mNeedCDRewrite is set, this writes the central dir.
-     */
-    status_t flush(void);
-
-    /*
-     * Expand the data into the buffer provided.  The buffer must hold
-     * at least <uncompressed len> bytes.  Variation expands directly
-     * to a file.
-     *
-     * Returns "false" if an error was encountered in the compressed data.
-     */
-    //bool uncompress(const ZipEntry* pEntry, void* buf) const;
-    //bool uncompress(const ZipEntry* pEntry, FILE* fp) const;
-    void* uncompress(const ZipEntry* pEntry);
-
-    /*
-     * Get an entry, by name.  Returns NULL if not found.
-     *
-     * Does not return entries pending deletion.
-     */
-    ZipEntry* getEntryByName(const char* fileName) const;
-
-    /*
-     * Get the Nth entry in the archive.
-     *
-     * This will return an entry that is pending deletion.
-     */
-    int getNumEntries(void) const { return mEntries.size(); }
-    ZipEntry* getEntryByIndex(int idx) const;
-
-private:
-    /* these are private and not defined */
-    ZipFile(const ZipFile& src);
-    ZipFile& operator=(const ZipFile& src);
-
-    class EndOfCentralDir {
-    public:
-        EndOfCentralDir(void) :
-            mDiskNumber(0),
-            mDiskWithCentralDir(0),
-            mNumEntries(0),
-            mTotalNumEntries(0),
-            mCentralDirSize(0),
-            mCentralDirOffset(0),
-            mCommentLen(0),
-            mComment(NULL)
-            {}
-        virtual ~EndOfCentralDir(void) {
-            delete[] mComment;
-        }
-
-        status_t readBuf(const unsigned char* buf, int len);
-        status_t write(FILE* fp);
-
-        //unsigned long   mSignature;
-        unsigned short  mDiskNumber;
-        unsigned short  mDiskWithCentralDir;
-        unsigned short  mNumEntries;
-        unsigned short  mTotalNumEntries;
-        unsigned long   mCentralDirSize;
-        unsigned long   mCentralDirOffset;      // offset from first disk
-        unsigned short  mCommentLen;
-        unsigned char*  mComment;
-
-        enum {
-            kSignature      = 0x06054b50,
-            kEOCDLen        = 22,       // EndOfCentralDir len, excl. comment
-
-            kMaxCommentLen  = 65535,    // longest possible in ushort
-            kMaxEOCDSearch  = kMaxCommentLen + EndOfCentralDir::kEOCDLen,
-
-        };
-
-        void dump(void) const;
-    };
-
-
-    /* read all entries in the central dir */
-    status_t readCentralDir(void);
-
-    /* crunch deleted entries out */
-    status_t crunchArchive(void);
-
-    /* clean up mEntries */
-    void discardEntries(void);
-
-    /* common handler for all "add" functions */
-    status_t addCommon(const char* fileName, const void* data, size_t size,
-        const char* storageName, int sourceType, int compressionMethod,
-        ZipEntry** ppEntry);
-
-    /* copy all of "srcFp" into "dstFp" */
-    status_t copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32);
-    /* copy all of "data" into "dstFp" */
-    status_t copyDataToFp(FILE* dstFp,
-        const void* data, size_t size, unsigned long* pCRC32);
-    /* copy some of "srcFp" into "dstFp" */
-    status_t copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,
-        unsigned long* pCRC32);
-    /* like memmove(), but on parts of a single file */
-    status_t filemove(FILE* fp, off_t dest, off_t src, size_t n);
-    /* compress all of "srcFp" into "dstFp", using Deflate */
-    status_t compressFpToFp(FILE* dstFp, FILE* srcFp,
-        const void* data, size_t size, unsigned long* pCRC32);
-
-    /* get modification date from a file descriptor */
-    time_t getModTime(int fd);
-
-    /*
-     * We use stdio FILE*, which gives us buffering but makes dealing
-     * with files >2GB awkward.  Until we support Zip64, we're fine.
-     */
-    FILE*           mZipFp;             // Zip file pointer
-
-    /* one of these per file */
-    EndOfCentralDir mEOCD;
-
-    /* did we open this read-only? */
-    bool            mReadOnly;
-
-    /* set this when we trash the central dir */
-    bool            mNeedCDRewrite;
-
-    /*
-     * One ZipEntry per entry in the zip file.  I'm using pointers instead
-     * of objects because it's easier than making operator= work for the
-     * classes and sub-classes.
-     */
-    Vector<ZipEntry*>   mEntries;
-};
-
-}; // namespace android
-
-#endif // __LIBS_ZIPFILE_H
diff --git a/tools/aapt/printapk.cpp b/tools/aapt/printapk.cpp
deleted file mode 100644
index 4cf73d8..0000000
--- a/tools/aapt/printapk.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-#include <utils/ResourceTypes.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
-#include <zipfile/zipfile.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-using namespace android;
-
-static int
-usage()
-{
-    fprintf(stderr,
-            "usage: apk APKFILE\n"
-            "\n"
-            "APKFILE   an android packge file produced by aapt.\n"
-            );
-    return 1;
-}
-
-
-int
-main(int argc, char** argv)
-{
-    const char* filename;
-    int fd;
-    ssize_t amt;
-    off_t size;
-    void* buf;
-    zipfile_t zip;
-    zipentry_t entry;
-    void* cookie;
-    void* resfile;
-    int bufsize;
-    int err;
-
-    if (argc != 2) {
-        return usage();
-    }
-
-    filename = argv[1];
-    fd = open(filename, O_RDONLY);
-    if (fd == -1) {
-        fprintf(stderr, "apk: couldn't open file for read: %s\n", filename);
-        return 1;
-    }
-
-    size = lseek(fd, 0, SEEK_END);
-    amt = lseek(fd, 0, SEEK_SET);
-
-    if (size < 0 || amt < 0) {
-        fprintf(stderr, "apk: error determining file size: %s\n", filename);
-        return 1;
-    }
-
-    buf = malloc(size);
-    if (buf == NULL) {
-        fprintf(stderr, "apk: file too big: %s\n", filename);
-        return 1;
-    }
-
-    amt = read(fd, buf, size);
-    if (amt != size) {
-        fprintf(stderr, "apk: error reading file: %s\n", filename);
-        return 1;
-    }
-
-    close(fd);
-
-    zip = init_zipfile(buf, size);
-    if (zip == NULL) {
-        fprintf(stderr, "apk: file doesn't seem to be a zip file: %s\n",
-                filename);
-        return 1;
-    }
-
-    printf("files:\n");
-    cookie = NULL;
-    while ((entry = iterate_zipfile(zip, &cookie))) {
-        char* name = get_zipentry_name(entry);
-        printf("  %s\n", name);
-        free(name);
-    }
-
-    entry = lookup_zipentry(zip, "resources.arsc");
-    if (entry != NULL) {
-        size = get_zipentry_size(entry);
-        bufsize = size + (size / 1000) + 1;
-        resfile = malloc(bufsize);
-
-        err = decompress_zipentry(entry, resfile, bufsize);
-        if (err != 0) {
-            fprintf(stderr, "apk: error decompressing resources.arsc");
-            return 1;
-        }
-
-        ResTable res(resfile, size, resfile);
-        res.print();
-#if 0
-        size_t tableCount = res.getTableCount();
-        printf("Tables: %d\n", (int)tableCount);
-        for (size_t tableIndex=0; tableIndex<tableCount; tableIndex++) {
-            const ResStringPool* strings = res.getTableStringBlock(tableIndex);
-            size_t stringCount = strings->size();
-            for (size_t stringIndex=0; stringIndex<stringCount; stringIndex++) {
-                size_t len;
-                const char16_t* ch = strings->stringAt(stringIndex, &len);
-                String8 s(String16(ch, len));
-                printf("  [%3d] %s\n", (int)stringIndex, s.string());
-            }
-        }
-
-        size_t basePackageCount = res.getBasePackageCount();
-        printf("Base Packages: %d\n", (int)basePackageCount);
-        for (size_t bpIndex=0; bpIndex<basePackageCount; bpIndex++) {
-            const char16_t* ch = res.getBasePackageName(bpIndex);
-            String8 s = String8(String16(ch));
-            printf("  [%3d] %s\n", (int)bpIndex, s.string());
-        }
-#endif
-    }
-
-
-    return 0;
-}
diff --git a/tools/aapt/pseudolocalize.cpp b/tools/aapt/pseudolocalize.cpp
deleted file mode 100644
index 9e50c5a..0000000
--- a/tools/aapt/pseudolocalize.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-#include "pseudolocalize.h"
-
-using namespace std;
-
-static const char*
-pseudolocalize_char(char c)
-{
-    switch (c) {
-        case 'a':   return "\xc4\x83";
-        case 'b':   return "\xcf\x84";
-        case 'c':   return "\xc4\x8b";
-        case 'd':   return "\xc4\x8f";
-        case 'e':   return "\xc4\x99";
-        case 'f':   return "\xc6\x92";
-        case 'g':   return "\xc4\x9d";
-        case 'h':   return "\xd1\x9b";
-        case 'i':   return "\xcf\x8a";
-        case 'j':   return "\xc4\xb5";
-        case 'k':   return "\xc4\xb8";
-        case 'l':   return "\xc4\xba";
-        case 'm':   return "\xe1\xb8\xbf";
-        case 'n':   return "\xd0\xb8";
-        case 'o':   return "\xcf\x8c";
-        case 'p':   return "\xcf\x81";
-        case 'q':   return "\x51";
-        case 'r':   return "\xd2\x91";
-        case 's':   return "\xc5\xa1";
-        case 't':   return "\xd1\x82";
-        case 'u':   return "\xce\xb0";
-        case 'v':   return "\x56";
-        case 'w':   return "\xe1\xba\x85";
-        case 'x':   return "\xd1\x85";
-        case 'y':   return "\xe1\xbb\xb3";
-        case 'z':   return "\xc5\xba";
-        case 'A':   return "\xc3\x85";
-        case 'B':   return "\xce\xb2";
-        case 'C':   return "\xc4\x88";
-        case 'D':   return "\xc4\x90";
-        case 'E':   return "\xd0\x84";
-        case 'F':   return "\xce\x93";
-        case 'G':   return "\xc4\x9e";
-        case 'H':   return "\xc4\xa6";
-        case 'I':   return "\xd0\x87";
-        case 'J':   return "\xc4\xb5";
-        case 'K':   return "\xc4\xb6";
-        case 'L':   return "\xc5\x81";
-        case 'M':   return "\xe1\xb8\xbe";
-        case 'N':   return "\xc5\x83";
-        case 'O':   return "\xce\x98";
-        case 'P':   return "\xcf\x81";
-        case 'Q':   return "\x71";
-        case 'R':   return "\xd0\xaf";
-        case 'S':   return "\xc8\x98";
-        case 'T':   return "\xc5\xa6";
-        case 'U':   return "\xc5\xa8";
-        case 'V':   return "\xce\xbd";
-        case 'W':   return "\xe1\xba\x84";
-        case 'X':   return "\xc3\x97";
-        case 'Y':   return "\xc2\xa5";
-        case 'Z':   return "\xc5\xbd";
-        default:    return NULL;
-    }
-}
-
-/**
- * Converts characters so they look like they've been localized.
- *
- * Note: This leaves escape sequences untouched so they can later be
- * processed by ResTable::collectString in the normal way.
- */
-string
-pseudolocalize_string(const string& source)
-{
-    const char* s = source.c_str();
-    string result;
-    const size_t I = source.length();
-    for (size_t i=0; i<I; i++) {
-        char c = s[i];
-        if (c == '\\') {
-            if (i<I-1) {
-                result += '\\';
-                i++;
-                c = s[i];
-                switch (c) {
-                    case 'u':
-                        // this one takes up 5 chars
-                        result += string(s+i, 5);
-                        i += 4;
-                        break;
-                    case 't':
-                    case 'n':
-                    case '#':
-                    case '@':
-                    case '?':
-                    case '"':
-                    case '\'':
-                    case '\\':
-                    default:
-                        result += c;
-                        break;
-                }
-            } else {
-                result += c;
-            }
-        } else {
-            const char* p = pseudolocalize_char(c);
-            if (p != NULL) {
-                result += p;
-            } else {
-                result += c;
-            }
-        }
-    }
-
-    //printf("result=\'%s\'\n", result.c_str());
-    return result;
-}
-
-
diff --git a/tools/aapt/pseudolocalize.h b/tools/aapt/pseudolocalize.h
deleted file mode 100644
index 94cb034..0000000
--- a/tools/aapt/pseudolocalize.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef HOST_PSEUDOLOCALIZE_H
-#define HOST_PSEUDOLOCALIZE_H
-
-#include <string>
-
-std::string pseudolocalize_string(const std::string& source);
-
-#endif // HOST_PSEUDOLOCALIZE_H
-
diff --git a/tools/aapt/qsort_r_compat.c b/tools/aapt/qsort_r_compat.c
deleted file mode 100644
index 2a8dbe8..0000000
--- a/tools/aapt/qsort_r_compat.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include "qsort_r_compat.h"
-
-/*
- * Note: This code is only used on the host, and is primarily here for
- * Mac OS compatibility. Apparently, glibc and Apple's libc disagree on
- * the parameter order for qsort_r.
- */
-
-#if HAVE_BSD_QSORT_R
-
-/*
- * BSD qsort_r parameter order is as we have defined here.
- */
-
-void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
-        int (*compar)(void*, const void* , const void*)) {
-    qsort_r(base, nel, width, thunk, compar);
-}
-
-#elif HAVE_GNU_QSORT_R
-
-/*
- * GNU qsort_r parameter order places the thunk parameter last.
- */
-
-struct compar_data {
-    void* thunk;
-    int (*compar)(void*, const void* , const void*);
-};
-
-static int compar_wrapper(const void* a, const void* b, void* data) {
-    struct compar_data* compar_data = (struct compar_data*)data;
-    return compar_data->compar(compar_data->thunk, a, b);
-}
-
-void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
-        int (*compar)(void*, const void* , const void*)) {
-    struct compar_data compar_data;
-    compar_data.thunk = thunk;
-    compar_data.compar = compar;
-    qsort_r(base, nel, width, compar_wrapper, &compar_data);
-}
-
-#else
-
-/*
- * Emulate qsort_r using thread local storage to access the thunk data.
- */
-
-#include <cutils/threads.h>
-
-static thread_store_t compar_data_key = THREAD_STORE_INITIALIZER;
-
-struct compar_data {
-    void* thunk;
-    int (*compar)(void*, const void* , const void*);
-};
-
-static int compar_wrapper(const void* a, const void* b) {
-    struct compar_data* compar_data = (struct compar_data*)thread_store_get(&compar_data_key);
-    return compar_data->compar(compar_data->thunk, a, b);
-}
-
-void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
-        int (*compar)(void*, const void* , const void*)) {
-    struct compar_data compar_data;
-    compar_data.thunk = thunk;
-    compar_data.compar = compar;
-    thread_store_set(&compar_data_key, &compar_data, NULL);
-    qsort(base, nel, width, compar_wrapper);
-}
-
-#endif
diff --git a/tools/aapt/qsort_r_compat.h b/tools/aapt/qsort_r_compat.h
deleted file mode 100644
index e14f999..0000000
--- a/tools/aapt/qsort_r_compat.h
+++ /dev/null
@@ -1,39 +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.
- */
-
-/*
- * Provides a portable version of qsort_r, called qsort_r_compat, which is a
- * reentrant variant of qsort that passes a user data pointer to its comparator.
- * This implementation follows the BSD parameter convention.
- */
-
-#ifndef ___QSORT_R_COMPAT_H
-#define ___QSORT_R_COMPAT_H
-
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
-        int (*compar)(void*, const void* , const void* ));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // ___QSORT_R_COMPAT_H
diff --git a/tools/aapt/tests/CrunchCache_test.cpp b/tools/aapt/tests/CrunchCache_test.cpp
deleted file mode 100644
index 20b5022..0000000
--- a/tools/aapt/tests/CrunchCache_test.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-#include <utils/String8.h>
-#include <iostream>
-#include <errno.h>
-
-#include "CrunchCache.h"
-#include "FileFinder.h"
-#include "MockFileFinder.h"
-#include "CacheUpdater.h"
-#include "MockCacheUpdater.h"
-
-using namespace android;
-using std::cout;
-using std::endl;
-
-void expectEqual(int got, int expected, const char* desc) {
-    cout << "Checking " << desc << ": ";
-    cout << "Got " << got << ", expected " << expected << "...";
-    cout << ( (got == expected) ? "PASSED" : "FAILED") << endl;
-    errno += ((got == expected) ? 0 : 1);
-}
-
-int main() {
-
-    errno = 0;
-
-    String8 source("res");
-    String8 dest("res2");
-
-    // Create data for MockFileFinder to feed to the cache
-    KeyedVector<String8, time_t> sourceData;
-    // This shouldn't be updated
-    sourceData.add(String8("res/drawable/hello.png"),3);
-    // This should be updated
-    sourceData.add(String8("res/drawable/world.png"),5);
-    // This should cause make directory to be called
-    sourceData.add(String8("res/drawable-cool/hello.png"),3);
-
-    KeyedVector<String8, time_t> destData;
-    destData.add(String8("res2/drawable/hello.png"),3);
-    destData.add(String8("res2/drawable/world.png"),3);
-    // this should call delete
-    destData.add(String8("res2/drawable/dead.png"),3);
-
-    // Package up data and create mock file finder
-    KeyedVector<String8, KeyedVector<String8,time_t> > data;
-    data.add(source,sourceData);
-    data.add(dest,destData);
-    FileFinder* ff = new MockFileFinder(data);
-    CrunchCache cc(source,dest,ff);
-
-    MockCacheUpdater* mcu = new MockCacheUpdater();
-    CacheUpdater* cu(mcu);
-
-    cout << "Running Crunch...";
-    int result = cc.crunch(cu);
-    cout << ((result > 0) ? "PASSED" : "FAILED") << endl;
-    errno += ((result > 0) ? 0 : 1);
-
-    const int EXPECTED_RESULT = 2;
-    expectEqual(result, EXPECTED_RESULT, "number of files touched");
-
-    cout << "Checking calls to deleteFile and processImage:" << endl;
-    const int EXPECTED_DELETES = 1;
-    const int EXPECTED_PROCESSED = 2;
-    // Deletes
-    expectEqual(mcu->deleteCount, EXPECTED_DELETES, "deleteFile");
-    // processImage
-    expectEqual(mcu->processCount, EXPECTED_PROCESSED, "processImage");
-
-    const int EXPECTED_OVERWRITES = 3;
-    result = cc.crunch(cu, true);
-    expectEqual(result, EXPECTED_OVERWRITES, "number of files touched with overwrite");
-    \
-
-    if (errno == 0)
-        cout << "ALL TESTS PASSED!" << endl;
-    else
-        cout << errno << " TESTS FAILED" << endl;
-
-    delete ff;
-    delete cu;
-
-    // TESTS BELOW WILL GO AWAY SOON
-
-    String8 source2("ApiDemos/res");
-    String8 dest2("ApiDemos/res2");
-
-    FileFinder* sff = new SystemFileFinder();
-    CacheUpdater* scu = new SystemCacheUpdater();
-
-    CrunchCache scc(source2,dest2,sff);
-
-    scc.crunch(scu);
-}
\ No newline at end of file
diff --git a/tools/aapt/tests/FileFinder_test.cpp b/tools/aapt/tests/FileFinder_test.cpp
deleted file mode 100644
index 07bd665..0000000
--- a/tools/aapt/tests/FileFinder_test.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-#include <utils/Vector.h>
-#include <utils/KeyedVector.h>
-#include <iostream>
-#include <cassert>
-#include <utils/String8.h>
-#include <utility>
-
-#include "DirectoryWalker.h"
-#include "MockDirectoryWalker.h"
-#include "FileFinder.h"
-
-using namespace android;
-
-using std::pair;
-using std::cout;
-using std::endl;
-
-
-
-int main()
-{
-
-    cout << "\n\n STARTING FILE FINDER TESTS" << endl;
-    String8 path("ApiDemos");
-
-    // Storage to pass to findFiles()
-    KeyedVector<String8,time_t> testStorage;
-
-    // Mock Directory Walker initialization. First data, then sdw
-    Vector< pair<String8,time_t> > data;
-    data.push( pair<String8,time_t>(String8("hello.png"),3) );
-    data.push( pair<String8,time_t>(String8("world.PNG"),3) );
-    data.push( pair<String8,time_t>(String8("foo.pNg"),3) );
-    // Neither of these should be found
-    data.push( pair<String8,time_t>(String8("hello.jpg"),3) );
-    data.push( pair<String8,time_t>(String8(".hidden.png"),3));
-
-    DirectoryWalker* sdw = new StringDirectoryWalker(path,data);
-
-    // Extensions to look for
-    Vector<String8> exts;
-    exts.push(String8(".png"));
-
-    errno = 0;
-
-    // Make sure we get a valid mock directory walker
-    // Make sure we finish without errors
-    cout << "Checking DirectoryWalker...";
-    assert(sdw != NULL);
-    cout << "PASSED" << endl;
-
-    // Make sure we finish without errors
-    cout << "Running findFiles()...";
-    bool findStatus = FileFinder::findFiles(path,exts, testStorage, sdw);
-    assert(findStatus);
-    cout << "PASSED" << endl;
-
-    const size_t SIZE_EXPECTED = 3;
-    // Check to make sure we have the right number of things in our storage
-    cout << "Running size comparison: Size is " << testStorage.size() << ", ";
-    cout << "Expected " << SIZE_EXPECTED << "...";
-    if(testStorage.size() == SIZE_EXPECTED)
-        cout << "PASSED" << endl;
-    else {
-        cout << "FAILED" << endl;
-        errno++;
-    }
-
-    // Check to make sure that each of our found items has the right extension
-    cout << "Checking Returned Extensions...";
-    bool extsOkay = true;
-    String8 wrongExts;
-    for (size_t i = 0; i < SIZE_EXPECTED; ++i) {
-        String8 testExt(testStorage.keyAt(i).getPathExtension());
-        testExt.toLower();
-        if (testExt != ".png") {
-            wrongExts += testStorage.keyAt(i);
-            wrongExts += "\n";
-            extsOkay = false;
-        }
-    }
-    if (extsOkay)
-        cout << "PASSED" << endl;
-    else {
-        cout << "FAILED" << endl;
-        cout << "The following extensions didn't check out" << endl << wrongExts;
-    }
-
-    // Clean up
-    delete sdw;
-
-    if(errno == 0) {
-        cout << "ALL TESTS PASSED" << endl;
-    } else {
-        cout << errno << " TESTS FAILED" << endl;
-    }
-    return errno;
-}
\ No newline at end of file
diff --git a/tools/aapt/tests/MockCacheUpdater.h b/tools/aapt/tests/MockCacheUpdater.h
deleted file mode 100644
index c7f4bd7..0000000
--- a/tools/aapt/tests/MockCacheUpdater.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-#ifndef MOCKCACHEUPDATER_H
-#define MOCKCACHEUPDATER_H
-
-#include <utils/String8.h>
-#include "CacheUpdater.h"
-
-using namespace android;
-
-class MockCacheUpdater : public CacheUpdater {
-public:
-
-    MockCacheUpdater()
-        : deleteCount(0), processCount(0) { };
-
-    // Make sure all the directories along this path exist
-    virtual void ensureDirectoriesExist(String8 path)
-    {
-        // Nothing to do
-    };
-
-    // Delete a file
-    virtual void deleteFile(String8 path) {
-        deleteCount++;
-    };
-
-    // Process an image from source out to dest
-    virtual void processImage(String8 source, String8 dest) {
-        processCount++;
-    };
-
-    // DATA MEMBERS
-    int deleteCount;
-    int processCount;
-private:
-};
-
-#endif // MOCKCACHEUPDATER_H
\ No newline at end of file
diff --git a/tools/aapt/tests/MockDirectoryWalker.h b/tools/aapt/tests/MockDirectoryWalker.h
deleted file mode 100644
index 5900cf3..0000000
--- a/tools/aapt/tests/MockDirectoryWalker.h
+++ /dev/null
@@ -1,85 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-#ifndef MOCKDIRECTORYWALKER_H
-#define MOCKDIRECTORYWALKER_H
-
-#include <utils/Vector.h>
-#include <utils/String8.h>
-#include <utility>
-#include "DirectoryWalker.h"
-
-using namespace android;
-using std::pair;
-
-// String8 Directory Walker
-// This is an implementation of the Directory Walker abstraction that is built
-// for testing.
-// Instead of system calls it queries a private data structure for the directory
-// entries. It takes a path and a map of filenames and their modification times.
-// functions are inlined since they are short and simple
-
-class StringDirectoryWalker : public DirectoryWalker {
-public:
-    StringDirectoryWalker(String8& path, Vector< pair<String8,time_t> >& data)
-        :  mPos(0), mBasePath(path), mData(data) {
-        //fprintf(stdout,"StringDW built to mimic %s with %d files\n",
-        //       mBasePath.string());
-    };
-    // Default copy constructor, and destructor are fine
-
-    virtual bool openDir(String8 path) {
-        // If the user is trying to query the "directory" that this
-        // walker was initialized with, then return success. Else fail.
-        return path == mBasePath;
-    };
-    virtual bool openDir(const char* path) {
-        String8 p(path);
-        openDir(p);
-        return true;
-    };
-    // Advance to next entry in the Vector
-    virtual struct dirent* nextEntry() {
-        // Advance position and check to see if we're done
-        if (mPos >= mData.size())
-            return NULL;
-
-        // Place data in the entry descriptor. This class only returns files.
-        mEntry.d_type = DT_REG;
-        mEntry.d_ino = mPos;
-        // Copy chars from the string name to the entry name
-        size_t i = 0;
-        for (i; i < mData[mPos].first.size(); ++i)
-            mEntry.d_name[i] = mData[mPos].first[i];
-        mEntry.d_name[i] = '\0';
-
-        // Place data in stats
-        mStats.st_ino = mPos;
-        mStats.st_mtime = mData[mPos].second;
-
-        // Get ready to move to the next entry
-        mPos++;
-
-        return &mEntry;
-    };
-    // Get the stats for the current entry
-    virtual struct stat*   entryStats() {
-        return &mStats;
-    };
-    // Nothing to do in clean up
-    virtual void closeDir() {
-        // Nothing to do
-    };
-    virtual DirectoryWalker* clone() {
-        return new StringDirectoryWalker(*this);
-    };
-private:
-    // Current position in the Vector
-    size_t mPos;
-    // Base path
-    String8 mBasePath;
-    // Data to simulate a directory full of files.
-    Vector< pair<String8,time_t> > mData;
-};
-
-#endif // MOCKDIRECTORYWALKER_H
\ No newline at end of file
diff --git a/tools/aapt/tests/MockFileFinder.h b/tools/aapt/tests/MockFileFinder.h
deleted file mode 100644
index da5ea4f..0000000
--- a/tools/aapt/tests/MockFileFinder.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Copyright 2011 The Android Open Source Project
-//
-
-#ifndef MOCKFILEFINDER_H
-#define MOCKFILEFINDER_H
-
-#include <utils/Vector.h>
-#include <utils/KeyedVector.h>
-#include <utils/String8.h>
-
-#include "DirectoryWalker.h"
-
-using namespace android;
-
-class MockFileFinder : public FileFinder {
-public:
-    MockFileFinder (KeyedVector<String8, KeyedVector<String8,time_t> >& files)
-        : mFiles(files)
-    {
-        // Nothing left to do
-    };
-
-    /**
-     * findFiles implementation for the abstraction.
-     * PRECONDITIONS:
-     *  No checking is done, so there MUST be an entry in mFiles with
-     *  path matching basePath.
-     *
-     * POSTCONDITIONS:
-     *  fileStore is filled with a copy of the data in mFiles corresponding
-     *  to the basePath.
-     */
-
-    virtual bool findFiles(String8 basePath, Vector<String8>& extensions,
-                           KeyedVector<String8,time_t>& fileStore,
-                           DirectoryWalker* dw)
-    {
-        const KeyedVector<String8,time_t>* payload(&mFiles.valueFor(basePath));
-        // Since KeyedVector doesn't implement swap
-        // (who doesn't use swap??) we loop and add one at a time.
-        for (size_t i = 0; i < payload->size(); ++i) {
-            fileStore.add(payload->keyAt(i),payload->valueAt(i));
-        }
-        return true;
-    }
-
-private:
-    // Virtual mapping between "directories" and the "files" contained
-    // in them
-    KeyedVector<String8, KeyedVector<String8,time_t> > mFiles;
-};
-
-
-#endif // MOCKFILEFINDER_H
\ No newline at end of file
diff --git a/tools/aapt/tests/plurals/AndroidManifest.xml b/tools/aapt/tests/plurals/AndroidManifest.xml
deleted file mode 100644
index c721dee..0000000
--- a/tools/aapt/tests/plurals/AndroidManifest.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.aapt.test.plurals">
-
-</manifest>
diff --git a/tools/aapt/tests/plurals/res/values/strings.xml b/tools/aapt/tests/plurals/res/values/strings.xml
deleted file mode 100644
index 1c1fc19..0000000
--- a/tools/aapt/tests/plurals/res/values/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="ok">OK</string>
-    <plurals name="a_plural">
-        <item quantity="one">A dog</item>
-        <item quantity="other">Some dogs</item>
-    </plurals>
-</resources>
diff --git a/tools/aapt/tests/plurals/run.sh b/tools/aapt/tests/plurals/run.sh
deleted file mode 100755
index 4d39e10..0000000
--- a/tools/aapt/tests/plurals/run.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-TEST_DIR=tools/aapt/tests/plurals
-TEST_OUT_DIR=out/plurals_test
-
-rm -rf $TEST_OUT_DIR
-mkdir -p $TEST_OUT_DIR
-mkdir -p $TEST_OUT_DIR/java
-
-#gdb --args \
-aapt package -v -x -m -z  -J $TEST_OUT_DIR/java -M $TEST_DIR/AndroidManifest.xml \
-             -I out/target/common/obj/APPS/framework-res_intermediates/package-export.apk \
-             -P $TEST_OUT_DIR/public_resources.xml \
-             -S $TEST_DIR/res
-
-echo
-echo "==================== FILES CREATED ==================== "
-find $TEST_OUT_DIR -type f
diff --git a/tools/aidl/AST.cpp b/tools/aidl/AST.cpp
deleted file mode 100644
index bfa6765..0000000
--- a/tools/aidl/AST.cpp
+++ /dev/null
@@ -1,912 +0,0 @@
-#include "AST.h"
-#include "Type.h"
-
-void
-WriteModifiers(FILE* to, int mod, int mask)
-{
-    int m = mod & mask;
-
-    if (m & OVERRIDE) {
-        fprintf(to, "@Override ");
-    }
-
-    if ((m & SCOPE_MASK) == PUBLIC) {
-        fprintf(to, "public ");
-    }
-    else if ((m & SCOPE_MASK) == PRIVATE) {
-        fprintf(to, "private ");
-    }
-    else if ((m & SCOPE_MASK) == PROTECTED) {
-        fprintf(to, "protected ");
-    }
-
-    if (m & STATIC) {
-        fprintf(to, "static ");
-    }
-    
-    if (m & FINAL) {
-        fprintf(to, "final ");
-    }
-
-    if (m & ABSTRACT) {
-        fprintf(to, "abstract ");
-    }
-}
-
-void
-WriteArgumentList(FILE* to, const vector<Expression*>& arguments)
-{
-    size_t N = arguments.size();
-    for (size_t i=0; i<N; i++) {
-        arguments[i]->Write(to);
-        if (i != N-1) {
-            fprintf(to, ", ");
-        }
-    }
-}
-
-ClassElement::ClassElement()
-{
-}
-
-ClassElement::~ClassElement()
-{
-}
-
-Field::Field()
-    :ClassElement(),
-     modifiers(0),
-     variable(NULL)
-{
-}
-
-Field::Field(int m, Variable* v)
-    :ClassElement(),
-     modifiers(m),
-     variable(v)
-{
-}
-
-Field::~Field()
-{
-}
-
-void
-Field::GatherTypes(set<Type*>* types) const
-{
-    types->insert(this->variable->type);
-}
-
-void
-Field::Write(FILE* to)
-{
-    if (this->comment.length() != 0) {
-        fprintf(to, "%s\n", this->comment.c_str());
-    }
-    WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL | OVERRIDE);
-    fprintf(to, "%s %s", this->variable->type->QualifiedName().c_str(),
-            this->variable->name.c_str());
-    if (this->value.length() != 0) {
-        fprintf(to, " = %s", this->value.c_str());
-    }
-    fprintf(to, ";\n");
-}
-
-Expression::~Expression()
-{
-}
-
-LiteralExpression::LiteralExpression(const string& v)
-    :value(v)
-{
-}
-
-LiteralExpression::~LiteralExpression()
-{
-}
-
-void
-LiteralExpression::Write(FILE* to)
-{
-    fprintf(to, "%s", this->value.c_str());
-}
-
-StringLiteralExpression::StringLiteralExpression(const string& v)
-    :value(v)
-{
-}
-
-StringLiteralExpression::~StringLiteralExpression()
-{
-}
-
-void
-StringLiteralExpression::Write(FILE* to)
-{
-    fprintf(to, "\"%s\"", this->value.c_str());
-}
-
-Variable::Variable()
-    :type(NULL),
-     name(),
-     dimension(0)
-{
-}
-
-Variable::Variable(Type* t, const string& n)
-    :type(t),
-     name(n),
-     dimension(0)
-{
-}
-
-Variable::Variable(Type* t, const string& n, int d)
-    :type(t),
-     name(n),
-     dimension(d)
-{
-}
-
-Variable::~Variable()
-{
-}
-
-void
-Variable::GatherTypes(set<Type*>* types) const
-{
-    types->insert(this->type);
-}
-
-void
-Variable::WriteDeclaration(FILE* to)
-{
-    string dim;
-    for (int i=0; i<this->dimension; i++) {
-        dim += "[]";
-    }
-    fprintf(to, "%s%s %s", this->type->QualifiedName().c_str(), dim.c_str(),
-            this->name.c_str());
-}
-
-void
-Variable::Write(FILE* to)
-{
-    fprintf(to, "%s", name.c_str());
-}
-
-FieldVariable::FieldVariable(Expression* o, const string& n)
-    :object(o),
-     clazz(NULL),
-     name(n)
-{
-}
-
-FieldVariable::FieldVariable(Type* c, const string& n)
-    :object(NULL),
-     clazz(c),
-     name(n)
-{
-}
-
-FieldVariable::~FieldVariable()
-{
-}
-
-void
-FieldVariable::Write(FILE* to)
-{
-    if (this->object != NULL) {
-        this->object->Write(to);
-    }
-    else if (this->clazz != NULL) {
-        fprintf(to, "%s", this->clazz->QualifiedName().c_str());
-    }
-    fprintf(to, ".%s", name.c_str());
-}
-
-
-Statement::~Statement()
-{
-}
-
-StatementBlock::StatementBlock()
-{
-}
-
-StatementBlock::~StatementBlock()
-{
-}
-
-void
-StatementBlock::Write(FILE* to)
-{
-    fprintf(to, "{\n");
-    int N = this->statements.size();
-    for (int i=0; i<N; i++) {
-        this->statements[i]->Write(to);
-    }
-    fprintf(to, "}\n");
-}
-
-void
-StatementBlock::Add(Statement* statement)
-{
-    this->statements.push_back(statement);
-}
-
-void
-StatementBlock::Add(Expression* expression)
-{
-    this->statements.push_back(new ExpressionStatement(expression));
-}
-
-ExpressionStatement::ExpressionStatement(Expression* e)
-    :expression(e)
-{
-}
-
-ExpressionStatement::~ExpressionStatement()
-{
-}
-
-void
-ExpressionStatement::Write(FILE* to)
-{
-    this->expression->Write(to);
-    fprintf(to, ";\n");
-}
-
-Assignment::Assignment(Variable* l, Expression* r)
-    :lvalue(l),
-     rvalue(r),
-     cast(NULL)
-{
-}
-
-Assignment::Assignment(Variable* l, Expression* r, Type* c)
-    :lvalue(l),
-     rvalue(r),
-     cast(c)
-{
-}
-
-Assignment::~Assignment()
-{
-}
-
-void
-Assignment::Write(FILE* to)
-{
-    this->lvalue->Write(to);
-    fprintf(to, " = ");
-    if (this->cast != NULL) {
-        fprintf(to, "(%s)", this->cast->QualifiedName().c_str());
-    }
-    this->rvalue->Write(to);
-}
-
-MethodCall::MethodCall(const string& n)
-    :obj(NULL),
-     clazz(NULL),
-     name(n)
-{
-}
-
-MethodCall::MethodCall(const string& n, int argc = 0, ...)
-    :obj(NULL),
-     clazz(NULL),
-     name(n)
-{
-  va_list args;
-  va_start(args, argc);
-  init(argc, args);
-  va_end(args);
-}
-
-MethodCall::MethodCall(Expression* o, const string& n)
-    :obj(o),
-     clazz(NULL),
-     name(n)
-{
-}
-
-MethodCall::MethodCall(Type* t, const string& n)
-    :obj(NULL),
-     clazz(t),
-     name(n)
-{
-}
-
-MethodCall::MethodCall(Expression* o, const string& n, int argc = 0, ...)
-    :obj(o),
-     clazz(NULL),
-     name(n)
-{
-  va_list args;
-  va_start(args, argc);
-  init(argc, args);
-  va_end(args);
-}
-
-MethodCall::MethodCall(Type* t, const string& n, int argc = 0, ...)
-    :obj(NULL),
-     clazz(t),
-     name(n)
-{
-  va_list args;
-  va_start(args, argc);
-  init(argc, args);
-  va_end(args);
-}
-
-MethodCall::~MethodCall()
-{
-}
-
-void
-MethodCall::init(int n, va_list args)
-{
-    for (int i=0; i<n; i++) {
-        Expression* expression = (Expression*)va_arg(args, void*);
-        this->arguments.push_back(expression);
-    }
-}
-
-void
-MethodCall::Write(FILE* to)
-{
-    if (this->obj != NULL) {
-        this->obj->Write(to);
-        fprintf(to, ".");
-    }
-    else if (this->clazz != NULL) {
-        fprintf(to, "%s.", this->clazz->QualifiedName().c_str());
-    }
-    fprintf(to, "%s(", this->name.c_str());
-    WriteArgumentList(to, this->arguments);
-    fprintf(to, ")");
-}
-
-Comparison::Comparison(Expression* l, const string& o, Expression* r)
-    :lvalue(l),
-     op(o),
-     rvalue(r)
-{
-}
-
-Comparison::~Comparison()
-{
-}
-
-void
-Comparison::Write(FILE* to)
-{
-    fprintf(to, "(");
-    this->lvalue->Write(to);
-    fprintf(to, "%s", this->op.c_str());
-    this->rvalue->Write(to);
-    fprintf(to, ")");
-}
-
-NewExpression::NewExpression(Type* t)
-    :type(t)
-{
-}
-
-NewExpression::NewExpression(Type* t, int argc = 0, ...)
-    :type(t)
-{
-  va_list args;
-  va_start(args, argc);
-  init(argc, args);
-  va_end(args);
-}
-
-NewExpression::~NewExpression()
-{
-}
-
-void
-NewExpression::init(int n, va_list args)
-{
-    for (int i=0; i<n; i++) {
-        Expression* expression = (Expression*)va_arg(args, void*);
-        this->arguments.push_back(expression);
-    }
-}
-
-void
-NewExpression::Write(FILE* to)
-{
-    fprintf(to, "new %s(", this->type->InstantiableName().c_str());
-    WriteArgumentList(to, this->arguments);
-    fprintf(to, ")");
-}
-
-NewArrayExpression::NewArrayExpression(Type* t, Expression* s)
-    :type(t),
-     size(s)
-{
-}
-
-NewArrayExpression::~NewArrayExpression()
-{
-}
-
-void
-NewArrayExpression::Write(FILE* to)
-{
-    fprintf(to, "new %s[", this->type->QualifiedName().c_str());
-    size->Write(to);
-    fprintf(to, "]");
-}
-
-Ternary::Ternary()
-    :condition(NULL),
-     ifpart(NULL),
-     elsepart(NULL)
-{
-}
-
-Ternary::Ternary(Expression* a, Expression* b, Expression* c)
-    :condition(a),
-     ifpart(b),
-     elsepart(c)
-{
-}
-
-Ternary::~Ternary()
-{
-}
-
-void
-Ternary::Write(FILE* to)
-{
-    fprintf(to, "((");
-    this->condition->Write(to);
-    fprintf(to, ")?(");
-    this->ifpart->Write(to);
-    fprintf(to, "):(");
-    this->elsepart->Write(to);
-    fprintf(to, "))");
-}
-
-Cast::Cast()
-    :type(NULL),
-     expression(NULL)
-{
-}
-
-Cast::Cast(Type* t, Expression* e)
-    :type(t),
-     expression(e)
-{
-}
-
-Cast::~Cast()
-{
-}
-
-void
-Cast::Write(FILE* to)
-{
-    fprintf(to, "((%s)", this->type->QualifiedName().c_str());
-    expression->Write(to);
-    fprintf(to, ")");
-}
-
-VariableDeclaration::VariableDeclaration(Variable* l, Expression* r, Type* c)
-    :lvalue(l),
-     cast(c),
-     rvalue(r)
-{
-}
-
-VariableDeclaration::VariableDeclaration(Variable* l)
-    :lvalue(l),
-     cast(NULL),
-     rvalue(NULL)
-{
-}
-
-VariableDeclaration::~VariableDeclaration()
-{
-}
-
-void
-VariableDeclaration::Write(FILE* to)
-{
-    this->lvalue->WriteDeclaration(to);
-    if (this->rvalue != NULL) {
-        fprintf(to, " = ");
-        if (this->cast != NULL) {
-            fprintf(to, "(%s)", this->cast->QualifiedName().c_str());
-        }
-        this->rvalue->Write(to);
-    }
-    fprintf(to, ";\n");
-}
-
-IfStatement::IfStatement()
-    :expression(NULL),
-     statements(new StatementBlock),
-     elseif(NULL)
-{
-}
-
-IfStatement::~IfStatement()
-{
-}
-
-void
-IfStatement::Write(FILE* to)
-{
-    if (this->expression != NULL) {
-        fprintf(to, "if (");
-        this->expression->Write(to);
-        fprintf(to, ") ");
-    }
-    this->statements->Write(to);
-    if (this->elseif != NULL) {
-        fprintf(to, "else ");
-        this->elseif->Write(to);
-    }
-}
-
-ReturnStatement::ReturnStatement(Expression* e)
-    :expression(e)
-{
-}
-
-ReturnStatement::~ReturnStatement()
-{
-}
-
-void
-ReturnStatement::Write(FILE* to)
-{
-    fprintf(to, "return ");
-    this->expression->Write(to);
-    fprintf(to, ";\n");
-}
-
-TryStatement::TryStatement()
-    :statements(new StatementBlock)
-{
-}
-
-TryStatement::~TryStatement()
-{
-}
-
-void
-TryStatement::Write(FILE* to)
-{
-    fprintf(to, "try ");
-    this->statements->Write(to);
-}
-
-CatchStatement::CatchStatement(Variable* e)
-    :statements(new StatementBlock),
-     exception(e)
-{
-}
-
-CatchStatement::~CatchStatement()
-{
-}
-
-void
-CatchStatement::Write(FILE* to)
-{
-    fprintf(to, "catch ");
-    if (this->exception != NULL) {
-        fprintf(to, "(");
-        this->exception->WriteDeclaration(to);
-        fprintf(to, ") ");
-    }
-    this->statements->Write(to);
-}
-
-FinallyStatement::FinallyStatement()
-    :statements(new StatementBlock)
-{
-}
-
-FinallyStatement::~FinallyStatement()
-{
-}
-
-void
-FinallyStatement::Write(FILE* to)
-{
-    fprintf(to, "finally ");
-    this->statements->Write(to);
-}
-
-Case::Case()
-    :statements(new StatementBlock)
-{
-}
-
-Case::Case(const string& c)
-    :statements(new StatementBlock)
-{
-    cases.push_back(c);
-}
-
-Case::~Case()
-{
-}
-
-void
-Case::Write(FILE* to)
-{
-    int N = this->cases.size();
-    if (N > 0) {
-        for (int i=0; i<N; i++) {
-            string s = this->cases[i];
-            if (s.length() != 0) {
-                fprintf(to, "case %s:\n", s.c_str());
-            } else {
-                fprintf(to, "default:\n");
-            }
-        }
-    } else {
-        fprintf(to, "default:\n");
-    }
-    statements->Write(to);
-}
-
-SwitchStatement::SwitchStatement(Expression* e)
-    :expression(e)
-{
-}
-
-SwitchStatement::~SwitchStatement()
-{
-}
-
-void
-SwitchStatement::Write(FILE* to)
-{
-    fprintf(to, "switch (");
-    this->expression->Write(to);
-    fprintf(to, ")\n{\n");
-    int N = this->cases.size();
-    for (int i=0; i<N; i++) {
-        this->cases[i]->Write(to);
-    }
-    fprintf(to, "}\n");
-}
-
-Break::Break()
-{
-}
-
-Break::~Break()
-{
-}
-
-void
-Break::Write(FILE* to)
-{
-    fprintf(to, "break;\n");
-}
-
-Method::Method()
-    :ClassElement(),
-     modifiers(0),
-     returnType(NULL), // (NULL means constructor)
-     returnTypeDimension(0),
-     statements(NULL)
-{
-}
-
-Method::~Method()
-{
-}
-
-void
-Method::GatherTypes(set<Type*>* types) const
-{
-    size_t N, i;
-
-    if (this->returnType) {
-        types->insert(this->returnType);
-    }
-
-    N = this->parameters.size();
-    for (i=0; i<N; i++) {
-        this->parameters[i]->GatherTypes(types);
-    }
-
-    N = this->exceptions.size();
-    for (i=0; i<N; i++) {
-        types->insert(this->exceptions[i]);
-    }
-}
-
-void
-Method::Write(FILE* to)
-{
-    size_t N, i;
-
-    if (this->comment.length() != 0) {
-        fprintf(to, "%s\n", this->comment.c_str());
-    }
-
-    WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | ABSTRACT | FINAL | OVERRIDE);
-
-    if (this->returnType != NULL) {
-        string dim;
-        for (i=0; i<this->returnTypeDimension; i++) {
-            dim += "[]";
-        }
-        fprintf(to, "%s%s ", this->returnType->QualifiedName().c_str(),
-                dim.c_str());
-    }
-   
-    fprintf(to, "%s(", this->name.c_str());
-
-    N = this->parameters.size();
-    for (i=0; i<N; i++) {
-        this->parameters[i]->WriteDeclaration(to);
-        if (i != N-1) {
-            fprintf(to, ", ");
-        }
-    }
-
-    fprintf(to, ")");
-
-    N = this->exceptions.size();
-    for (i=0; i<N; i++) {
-        if (i == 0) {
-            fprintf(to, " throws ");
-        } else {
-            fprintf(to, ", ");
-        }
-        fprintf(to, "%s", this->exceptions[i]->QualifiedName().c_str());
-    }
-
-    if (this->statements == NULL) {
-        fprintf(to, ";\n");
-    } else {
-        fprintf(to, "\n");
-        this->statements->Write(to);
-    }
-}
-
-Class::Class()
-    :modifiers(0),
-     what(CLASS),
-     type(NULL),
-     extends(NULL)
-{
-}
-
-Class::~Class()
-{
-}
-
-void
-Class::GatherTypes(set<Type*>* types) const
-{
-    int N, i;
-
-    types->insert(this->type);
-    if (this->extends != NULL) {
-        types->insert(this->extends);
-    }
-
-    N = this->interfaces.size();
-    for (i=0; i<N; i++) {
-        types->insert(this->interfaces[i]);
-    }
-
-    N = this->elements.size();
-    for (i=0; i<N; i++) {
-        this->elements[i]->GatherTypes(types);
-    }
-}
-
-void
-Class::Write(FILE* to)
-{
-    size_t N, i;
-
-    if (this->comment.length() != 0) {
-        fprintf(to, "%s\n", this->comment.c_str());
-    }
-
-    WriteModifiers(to, this->modifiers, ALL_MODIFIERS);
-
-    if (this->what == Class::CLASS) {
-        fprintf(to, "class ");
-    } else {
-        fprintf(to, "interface ");
-    }
-
-    string name = this->type->Name();
-    size_t pos = name.rfind('.');
-    if (pos != string::npos) {
-        name = name.c_str() + pos + 1;
-    }
-
-    fprintf(to, "%s", name.c_str());
-
-    if (this->extends != NULL) {
-        fprintf(to, " extends %s", this->extends->QualifiedName().c_str());
-    }
-
-    N = this->interfaces.size();
-    if (N != 0) {
-        if (this->what == Class::CLASS) {
-            fprintf(to, " implements");
-        } else {
-            fprintf(to, " extends");
-        }
-        for (i=0; i<N; i++) {
-            fprintf(to, " %s", this->interfaces[i]->QualifiedName().c_str());
-        }
-    }
-
-    fprintf(to, "\n");
-    fprintf(to, "{\n");
-
-    N = this->elements.size();
-    for (i=0; i<N; i++) {
-        this->elements[i]->Write(to);
-    }
-
-    fprintf(to, "}\n");
-
-}
-
-Document::Document()
-{
-}
-
-Document::~Document()
-{
-}
-
-static string
-escape_backslashes(const string& str)
-{
-    string result;
-    const size_t I=str.length();
-    for (size_t i=0; i<I; i++) {
-        char c = str[i];
-        if (c == '\\') {
-            result += "\\\\";
-        } else {
-            result += c;
-        }
-    }
-    return result;
-}
-
-void
-Document::Write(FILE* to)
-{
-    size_t N, i;
-
-    if (this->comment.length() != 0) {
-        fprintf(to, "%s\n", this->comment.c_str());
-    }
-    fprintf(to, "/*\n"
-                " * This file is auto-generated.  DO NOT MODIFY.\n"
-                " * Original file: %s\n"
-                " */\n", escape_backslashes(this->originalSrc).c_str());
-    if (this->package.length() != 0) {
-        fprintf(to, "package %s;\n", this->package.c_str());
-    }
-
-    N = this->classes.size();
-    for (i=0; i<N; i++) {
-        Class* c = this->classes[i];
-        c->Write(to);
-    }
-}
-
diff --git a/tools/aidl/AST.h b/tools/aidl/AST.h
deleted file mode 100644
index ead5e7a..0000000
--- a/tools/aidl/AST.h
+++ /dev/null
@@ -1,371 +0,0 @@
-#ifndef AIDL_AST_H
-#define AIDL_AST_H
-
-#include <string>
-#include <vector>
-#include <set>
-#include <stdarg.h>
-#include <stdio.h>
-
-using namespace std;
-
-class Type;
-
-enum {
-    PACKAGE_PRIVATE = 0x00000000,
-    PUBLIC          = 0x00000001,
-    PRIVATE         = 0x00000002,
-    PROTECTED       = 0x00000003,
-    SCOPE_MASK      = 0x00000003,
-
-    STATIC          = 0x00000010,
-    FINAL           = 0x00000020,
-    ABSTRACT        = 0x00000040,
-
-    OVERRIDE        = 0x00000100,
-
-    ALL_MODIFIERS   = 0xffffffff
-};
-
-// Write the modifiers that are set in both mod and mask
-void WriteModifiers(FILE* to, int mod, int mask);
-
-struct ClassElement
-{
-    ClassElement();
-    virtual ~ClassElement();
-
-    virtual void GatherTypes(set<Type*>* types) const = 0;
-    virtual void Write(FILE* to) = 0;
-};
-
-struct Expression
-{
-    virtual ~Expression();
-    virtual void Write(FILE* to) = 0;
-};
-
-struct LiteralExpression : public Expression
-{
-    string value;
-
-    LiteralExpression(const string& value);
-    virtual ~LiteralExpression();
-    virtual void Write(FILE* to);
-};
-
-// TODO: also escape the contents.  not needed for now
-struct StringLiteralExpression : public Expression
-{
-    string value;
-
-    StringLiteralExpression(const string& value);
-    virtual ~StringLiteralExpression();
-    virtual void Write(FILE* to);
-};
-
-struct Variable : public Expression
-{
-    Type* type;
-    string name;
-    int dimension;
-
-    Variable();
-    Variable(Type* type, const string& name);
-    Variable(Type* type, const string& name, int dimension);
-    virtual ~Variable();
-
-    virtual void GatherTypes(set<Type*>* types) const;
-    void WriteDeclaration(FILE* to);
-    void Write(FILE* to);
-};
-
-struct FieldVariable : public Expression
-{
-    Expression* object;
-    Type* clazz;
-    string name;
-
-    FieldVariable(Expression* object, const string& name);
-    FieldVariable(Type* clazz, const string& name);
-    virtual ~FieldVariable();
-
-    void Write(FILE* to);
-};
-
-struct Field : public ClassElement
-{
-    string comment;
-    int modifiers;
-    Variable *variable;
-    string value;
-
-    Field();
-    Field(int modifiers, Variable* variable);
-    virtual ~Field();
-
-    virtual void GatherTypes(set<Type*>* types) const;
-    virtual void Write(FILE* to);
-};
-
-struct Statement
-{
-    virtual ~Statement();
-    virtual void Write(FILE* to) = 0;
-};
-
-struct StatementBlock : public Statement
-{
-    vector<Statement*> statements;
-
-    StatementBlock();
-    virtual ~StatementBlock();
-    virtual void Write(FILE* to);
-
-    void Add(Statement* statement);
-    void Add(Expression* expression);
-};
-
-struct ExpressionStatement : public Statement
-{
-    Expression* expression;
-
-    ExpressionStatement(Expression* expression);
-    virtual ~ExpressionStatement();
-    virtual void Write(FILE* to);
-};
-
-struct Assignment : public Expression
-{
-    Variable* lvalue;
-    Expression* rvalue;
-    Type* cast;
-
-    Assignment(Variable* lvalue, Expression* rvalue);
-    Assignment(Variable* lvalue, Expression* rvalue, Type* cast);
-    virtual ~Assignment();
-    virtual void Write(FILE* to);
-};
-
-struct MethodCall : public Expression
-{
-    Expression* obj;
-    Type* clazz;
-    string name;
-    vector<Expression*> arguments;
-    vector<string> exceptions;
-
-    MethodCall(const string& name);
-    MethodCall(const string& name, int argc, ...);
-    MethodCall(Expression* obj, const string& name);
-    MethodCall(Type* clazz, const string& name);
-    MethodCall(Expression* obj, const string& name, int argc, ...);
-    MethodCall(Type* clazz, const string& name, int argc, ...);
-    virtual ~MethodCall();
-    virtual void Write(FILE* to);
-
-private:
-    void init(int n, va_list args);
-};
-
-struct Comparison : public Expression
-{
-    Expression* lvalue;
-    string op;
-    Expression* rvalue;
-
-    Comparison(Expression* lvalue, const string& op, Expression* rvalue);
-    virtual ~Comparison();
-    virtual void Write(FILE* to);
-};
-
-struct NewExpression : public Expression
-{
-    Type* type;
-    vector<Expression*> arguments;
-
-    NewExpression(Type* type);
-    NewExpression(Type* type, int argc, ...);
-    virtual ~NewExpression();
-    virtual void Write(FILE* to);
-
-private:
-    void init(int n, va_list args);
-};
-
-struct NewArrayExpression : public Expression
-{
-    Type* type;
-    Expression* size;
-
-    NewArrayExpression(Type* type, Expression* size);
-    virtual ~NewArrayExpression();
-    virtual void Write(FILE* to);
-};
-
-struct Ternary : public Expression
-{
-    Expression* condition;
-    Expression* ifpart;
-    Expression* elsepart;
-
-    Ternary();
-    Ternary(Expression* condition, Expression* ifpart, Expression* elsepart);
-    virtual ~Ternary();
-    virtual void Write(FILE* to);
-};
-
-struct Cast : public Expression
-{
-    Type* type;
-    Expression* expression;
-
-    Cast();
-    Cast(Type* type, Expression* expression);
-    virtual ~Cast();
-    virtual void Write(FILE* to);
-};
-
-struct VariableDeclaration : public Statement
-{
-    Variable* lvalue;
-    Type* cast;
-    Expression* rvalue;
-
-    VariableDeclaration(Variable* lvalue);
-    VariableDeclaration(Variable* lvalue, Expression* rvalue, Type* cast = NULL);
-    virtual ~VariableDeclaration();
-    virtual void Write(FILE* to);
-};
-
-struct IfStatement : public Statement
-{
-    Expression* expression;
-    StatementBlock* statements;
-    IfStatement* elseif;
-
-    IfStatement();
-    virtual ~IfStatement();
-    virtual void Write(FILE* to);
-};
-
-struct ReturnStatement : public Statement
-{
-    Expression* expression;
-
-    ReturnStatement(Expression* expression);
-    virtual ~ReturnStatement();
-    virtual void Write(FILE* to);
-};
-
-struct TryStatement : public Statement
-{
-    StatementBlock* statements;
-
-    TryStatement();
-    virtual ~TryStatement();
-    virtual void Write(FILE* to);
-};
-
-struct CatchStatement : public Statement
-{
-    StatementBlock* statements;
-    Variable* exception;
-
-    CatchStatement(Variable* exception);
-    virtual ~CatchStatement();
-    virtual void Write(FILE* to);
-};
-
-struct FinallyStatement : public Statement
-{
-    StatementBlock* statements;
-
-    FinallyStatement();
-    virtual ~FinallyStatement();
-    virtual void Write(FILE* to);
-};
-
-struct Case
-{
-    vector<string> cases;
-    StatementBlock* statements;
-
-    Case();
-    Case(const string& c);
-    virtual ~Case();
-    virtual void Write(FILE* to);
-};
-
-struct SwitchStatement : public Statement
-{
-    Expression* expression;
-    vector<Case*> cases;
-
-    SwitchStatement(Expression* expression);
-    virtual ~SwitchStatement();
-    virtual void Write(FILE* to);
-};
-
-struct Break : public Statement
-{
-    Break();
-    virtual ~Break();
-    virtual void Write(FILE* to);
-};
-
-struct Method : public ClassElement
-{
-    string comment;
-    int modifiers;
-    Type* returnType;
-    size_t returnTypeDimension;
-    string name;
-    vector<Variable*> parameters;
-    vector<Type*> exceptions;
-    StatementBlock* statements;
-
-    Method();
-    virtual ~Method();
-
-    virtual void GatherTypes(set<Type*>* types) const;
-    virtual void Write(FILE* to);
-};
-
-struct Class : public ClassElement
-{
-    enum {
-        CLASS,
-        INTERFACE
-    };
-
-    string comment;
-    int modifiers;
-    int what;               // CLASS or INTERFACE
-    Type* type;
-    Type* extends;
-    vector<Type*> interfaces;
-    vector<ClassElement*> elements;
-
-    Class();
-    virtual ~Class();
-
-    virtual void GatherTypes(set<Type*>* types) const;
-    virtual void Write(FILE* to);
-};
-
-struct Document
-{
-    string comment;
-    string package;
-    string originalSrc;
-    set<Type*> imports;
-    vector<Class*> classes;
-
-    Document();
-    virtual ~Document();
-
-    virtual void Write(FILE* to);
-};
-
-#endif // AIDL_AST_H
diff --git a/tools/aidl/Android.mk b/tools/aidl/Android.mk
deleted file mode 100644
index 77d46ab..0000000
--- a/tools/aidl/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-# Copies files into the directory structure described by a manifest
-
-# This tool is prebuilt if we're doing an app-only build.
-ifeq ($(TARGET_BUILD_APPS),)
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	aidl_language_l.l \
-	aidl_language_y.y \
-	aidl.cpp \
-	aidl_language.cpp \
-	options.cpp \
-	search_path.cpp \
-	AST.cpp \
-	Type.cpp \
-	generate_java.cpp \
-	generate_java_binder.cpp \
-	generate_java_rpc.cpp
-
-LOCAL_CFLAGS := -g
-LOCAL_MODULE := aidl
-
-include $(BUILD_HOST_EXECUTABLE)
-
-endif # TARGET_BUILD_APPS
diff --git a/tools/aidl/NOTICE b/tools/aidl/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/tools/aidl/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-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.
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/tools/aidl/Type.cpp b/tools/aidl/Type.cpp
deleted file mode 100644
index d572af6..0000000
--- a/tools/aidl/Type.cpp
+++ /dev/null
@@ -1,1440 +0,0 @@
-#include "Type.h"
-
-Namespace NAMES;
-
-Type* VOID_TYPE;
-Type* BOOLEAN_TYPE;
-Type* BYTE_TYPE;
-Type* CHAR_TYPE;
-Type* INT_TYPE;
-Type* LONG_TYPE;
-Type* FLOAT_TYPE;
-Type* DOUBLE_TYPE;
-Type* STRING_TYPE;
-Type* OBJECT_TYPE;
-Type* CHAR_SEQUENCE_TYPE;
-Type* TEXT_UTILS_TYPE;
-Type* REMOTE_EXCEPTION_TYPE;
-Type* RUNTIME_EXCEPTION_TYPE;
-Type* IBINDER_TYPE;
-Type* IINTERFACE_TYPE;
-Type* BINDER_NATIVE_TYPE;
-Type* BINDER_PROXY_TYPE;
-Type* PARCEL_TYPE;
-Type* PARCELABLE_INTERFACE_TYPE;
-Type* CONTEXT_TYPE;
-Type* MAP_TYPE;
-Type* LIST_TYPE;
-Type* CLASSLOADER_TYPE;
-Type* RPC_DATA_TYPE;
-Type* RPC_ERROR_TYPE;
-Type* EVENT_FAKE_TYPE;
-
-Expression* NULL_VALUE;
-Expression* THIS_VALUE;
-Expression* SUPER_VALUE;
-Expression* TRUE_VALUE;
-Expression* FALSE_VALUE;
-
-void
-register_base_types()
-{
-    VOID_TYPE = new BasicType("void",
-            "XXX", "XXX", "XXX", "XXX", "XXX",
-            "XXX", "XXX", "XXX", "XXX", "XXX");
-    NAMES.Add(VOID_TYPE);
-
-    BOOLEAN_TYPE = new BooleanType();
-    NAMES.Add(BOOLEAN_TYPE);
-
-    BYTE_TYPE = new BasicType("byte",
-            "writeByte", "readByte", "writeByteArray", "createByteArray", "readByteArray",
-            "putByte", "getByte", "putByteArray", "createByteArray", "getByteArray");
-    NAMES.Add(BYTE_TYPE);
-
-    CHAR_TYPE = new CharType();
-    NAMES.Add(CHAR_TYPE);
-
-    INT_TYPE = new BasicType("int",
-            "writeInt", "readInt", "writeIntArray", "createIntArray", "readIntArray",
-            "putInteger", "getInteger", "putIntegerArray", "createIntegerArray", "getIntegerArray");
-    NAMES.Add(INT_TYPE);
-
-    LONG_TYPE = new BasicType("long",
-            "writeLong", "readLong", "writeLongArray", "createLongArray", "readLongArray",
-            "putLong", "getLong", "putLongArray", "createLongArray", "getLongArray");
-    NAMES.Add(LONG_TYPE);
-
-    FLOAT_TYPE = new BasicType("float",
-            "writeFloat", "readFloat", "writeFloatArray", "createFloatArray", "readFloatArray",
-            "putFloat", "getFloat", "putFloatArray", "createFloatArray", "getFloatArray");
-    NAMES.Add(FLOAT_TYPE);
-
-    DOUBLE_TYPE = new BasicType("double",
-            "writeDouble", "readDouble", "writeDoubleArray", "createDoubleArray", "readDoubleArray",
-            "putDouble", "getDouble", "putDoubleArray", "createDoubleArray", "getDoubleArray");
-    NAMES.Add(DOUBLE_TYPE);
-
-    STRING_TYPE = new StringType();
-    NAMES.Add(STRING_TYPE);
-
-    OBJECT_TYPE = new Type("java.lang", "Object", Type::BUILT_IN, false, false, false);
-    NAMES.Add(OBJECT_TYPE);
-
-    CHAR_SEQUENCE_TYPE = new CharSequenceType();
-    NAMES.Add(CHAR_SEQUENCE_TYPE);
-
-    MAP_TYPE = new MapType();
-    NAMES.Add(MAP_TYPE);
-
-    LIST_TYPE = new ListType();
-    NAMES.Add(LIST_TYPE);
-
-    TEXT_UTILS_TYPE = new Type("android.text", "TextUtils", Type::BUILT_IN, false, false, false);
-    NAMES.Add(TEXT_UTILS_TYPE);
-
-    REMOTE_EXCEPTION_TYPE = new RemoteExceptionType();
-    NAMES.Add(REMOTE_EXCEPTION_TYPE);
-
-    RUNTIME_EXCEPTION_TYPE = new RuntimeExceptionType();
-    NAMES.Add(RUNTIME_EXCEPTION_TYPE);
-
-    IBINDER_TYPE = new IBinderType();
-    NAMES.Add(IBINDER_TYPE);
-
-    IINTERFACE_TYPE = new IInterfaceType();
-    NAMES.Add(IINTERFACE_TYPE);
-
-    BINDER_NATIVE_TYPE = new BinderType();
-    NAMES.Add(BINDER_NATIVE_TYPE);
-
-    BINDER_PROXY_TYPE = new BinderProxyType();
-    NAMES.Add(BINDER_PROXY_TYPE);
-
-    PARCEL_TYPE = new ParcelType();
-    NAMES.Add(PARCEL_TYPE);
-
-    PARCELABLE_INTERFACE_TYPE = new ParcelableInterfaceType();
-    NAMES.Add(PARCELABLE_INTERFACE_TYPE);
-
-    CONTEXT_TYPE = new Type("android.content", "Context", Type::BUILT_IN, false, false, false);
-    NAMES.Add(CONTEXT_TYPE);
-
-    RPC_DATA_TYPE = new RpcDataType();
-    NAMES.Add(RPC_DATA_TYPE);
-
-    RPC_ERROR_TYPE = new UserDataType("android.support.place.rpc", "RpcError",
-                                    true, __FILE__, __LINE__);
-    NAMES.Add(RPC_ERROR_TYPE);
-
-    EVENT_FAKE_TYPE = new Type("event", Type::BUILT_IN, false, false, false);
-    NAMES.Add(EVENT_FAKE_TYPE);
-
-    CLASSLOADER_TYPE = new ClassLoaderType();
-    NAMES.Add(CLASSLOADER_TYPE);
-
-    NULL_VALUE = new LiteralExpression("null");
-    THIS_VALUE = new LiteralExpression("this");
-    SUPER_VALUE = new LiteralExpression("super");
-    TRUE_VALUE = new LiteralExpression("true");
-    FALSE_VALUE = new LiteralExpression("false");
-
-    NAMES.AddGenericType("java.util", "List", 1);
-    NAMES.AddGenericType("java.util", "Map", 2);
-}
-
-static Type*
-make_generic_type(const string& package, const string& name,
-                    const vector<Type*>& args)
-{
-    if (package == "java.util" && name == "List") {
-        return new GenericListType("java.util", "List", args);
-    }
-    return NULL;
-    //return new GenericType(package, name, args);
-}
-
-// ================================================================
-
-Type::Type(const string& name, int kind, bool canWriteToParcel, bool canWriteToRpcData,
-        bool canBeOut)
-    :m_package(),
-     m_name(name),
-     m_declFile(""),
-     m_declLine(-1),
-     m_kind(kind),
-     m_canWriteToParcel(canWriteToParcel),
-     m_canWriteToRpcData(canWriteToRpcData),
-     m_canBeOut(canBeOut)
-{
-    m_qualifiedName = name;
-}
-
-Type::Type(const string& package, const string& name,
-            int kind, bool canWriteToParcel, bool canWriteToRpcData,
-            bool canBeOut, const string& declFile, int declLine)
-    :m_package(package),
-     m_name(name),
-     m_declFile(declFile),
-     m_declLine(declLine),
-     m_kind(kind),
-     m_canWriteToParcel(canWriteToParcel),
-     m_canWriteToRpcData(canWriteToRpcData),
-     m_canBeOut(canBeOut)
-{
-    if (package.length() > 0) {
-        m_qualifiedName = package;
-        m_qualifiedName += '.';
-    }
-    m_qualifiedName += name;
-}
-
-Type::~Type()
-{
-}
-
-bool
-Type::CanBeArray() const
-{
-    return false;
-}
-
-string
-Type::ImportType() const
-{
-    return m_qualifiedName;
-}
-
-string
-Type::CreatorName() const
-{
-    return "";
-}
-
-string
-Type::RpcCreatorName() const
-{
-    return "";
-}
-
-string
-Type::InstantiableName() const
-{
-    return QualifiedName();
-}
-
-
-void
-Type::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%sn",
-            __FILE__, __LINE__, m_qualifiedName.c_str());
-    addTo->Add(new LiteralExpression("/* WriteToParcel error "
-                + m_qualifiedName + " */"));
-}
-
-void
-Type::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
-            __FILE__, __LINE__, m_qualifiedName.c_str());
-    addTo->Add(new LiteralExpression("/* CreateFromParcel error "
-                + m_qualifiedName + " */"));
-}
-
-void
-Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
-            __FILE__, __LINE__, m_qualifiedName.c_str());
-    addTo->Add(new LiteralExpression("/* ReadFromParcel error "
-                + m_qualifiedName + " */"));
-}
-
-void
-Type::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
-            __FILE__, __LINE__, m_qualifiedName.c_str());
-    addTo->Add(new LiteralExpression("/* WriteArrayToParcel error "
-                + m_qualifiedName + " */"));
-}
-
-void
-Type::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel, Variable**)
-{
-    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
-            __FILE__, __LINE__, m_qualifiedName.c_str());
-    addTo->Add(new LiteralExpression("/* CreateArrayFromParcel error "
-                + m_qualifiedName + " */"));
-}
-
-void
-Type::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
-            __FILE__, __LINE__, m_qualifiedName.c_str());
-    addTo->Add(new LiteralExpression("/* ReadArrayFromParcel error "
-                + m_qualifiedName + " */"));
-}
-
-void
-Type::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
-            __FILE__, __LINE__, m_qualifiedName.c_str());
-    addTo->Add(new LiteralExpression("/* WriteToRpcData error "
-                + m_qualifiedName + " */"));
-}
-
-void
-Type::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
-        Variable** cl)
-{
-    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
-            __FILE__, __LINE__, m_qualifiedName.c_str());
-    addTo->Add(new LiteralExpression("/* ReadFromRpcData error "
-                + m_qualifiedName + " */"));
-}
-
-void
-Type::SetQualifiedName(const string& qualified)
-{
-    m_qualifiedName = qualified;
-}
-
-Expression*
-Type::BuildWriteToParcelFlags(int flags)
-{
-    if (flags == 0) {
-        return new LiteralExpression("0");
-    }
-    if ((flags&PARCELABLE_WRITE_RETURN_VALUE) != 0) {
-        return new FieldVariable(PARCELABLE_INTERFACE_TYPE,
-                "PARCELABLE_WRITE_RETURN_VALUE");
-    }
-    return new LiteralExpression("0");
-}
-
-// ================================================================
-
-BasicType::BasicType(const string& name, const string& marshallParcel,
-          const string& unmarshallParcel, const string& writeArrayParcel,
-          const string& createArrayParcel, const string& readArrayParcel,
-          const string& marshallRpc, const string& unmarshallRpc,
-          const string& writeArrayRpc, const string& createArrayRpc, const string& readArrayRpc)
-    :Type(name, BUILT_IN, true, true, false),
-     m_marshallParcel(marshallParcel),
-     m_unmarshallParcel(unmarshallParcel),
-     m_writeArrayParcel(writeArrayParcel),
-     m_createArrayParcel(createArrayParcel),
-     m_readArrayParcel(readArrayParcel),
-     m_marshallRpc(marshallRpc),
-     m_unmarshallRpc(unmarshallRpc),
-     m_writeArrayRpc(writeArrayRpc),
-     m_createArrayRpc(createArrayRpc),
-     m_readArrayRpc(readArrayRpc)
-{
-}
-
-void
-BasicType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, m_marshallParcel, 1, v));
-}
-
-void
-BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallParcel)));
-}
-
-bool
-BasicType::CanBeArray() const
-{
-    return true;
-}
-
-void
-BasicType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, m_writeArrayParcel, 1, v));
-}
-
-void
-BasicType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel, Variable**)
-{
-    addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayParcel)));
-}
-
-void
-BasicType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    addTo->Add(new MethodCall(parcel, m_readArrayParcel, 1, v));
-}
-
-void
-BasicType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    addTo->Add(new MethodCall(data, m_marshallRpc, 2, k, v));
-}
-
-void
-BasicType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
-        Variable** cl)
-{
-    addTo->Add(new Assignment(v, new MethodCall(data, m_unmarshallRpc, 1, k)));
-}
-
-// ================================================================
-
-BooleanType::BooleanType()
-    :Type("boolean", BUILT_IN, true, true, false)
-{
-}
-
-void
-BooleanType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, "writeInt", 1, 
-                new Ternary(v, new LiteralExpression("1"),
-                    new LiteralExpression("0"))));
-}
-
-void
-BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    addTo->Add(new Assignment(v, new Comparison(new LiteralExpression("0"),
-                    "!=", new MethodCall(parcel, "readInt"))));
-}
-
-bool
-BooleanType::CanBeArray() const
-{
-    return true;
-}
-
-void
-BooleanType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, "writeBooleanArray", 1, v));
-}
-
-void
-BooleanType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel, Variable**)
-{
-    addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray")));
-}
-
-void
-BooleanType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v));
-}
-
-void
-BooleanType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    addTo->Add(new MethodCall(data, "putBoolean", 2, k, v));
-}
-
-void
-BooleanType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
-        Variable** cl)
-{
-    addTo->Add(new Assignment(v, new MethodCall(data, "getBoolean", 1, k)));
-}
-
-// ================================================================
-
-CharType::CharType()
-    :Type("char", BUILT_IN, true, true, false)
-{
-}
-
-void
-CharType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, "writeInt", 1, 
-                    new Cast(INT_TYPE, v)));
-}
-
-void
-CharType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this));
-}
-
-bool
-CharType::CanBeArray() const
-{
-    return true;
-}
-
-void
-CharType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, "writeCharArray", 1, v));
-}
-
-void
-CharType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel, Variable**)
-{
-    addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray")));
-}
-
-void
-CharType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    addTo->Add(new MethodCall(parcel, "readCharArray", 1, v));
-}
-
-void
-CharType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    addTo->Add(new MethodCall(data, "putChar", 2, k, v));
-}
-
-void
-CharType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
-        Variable** cl)
-{
-    addTo->Add(new Assignment(v, new MethodCall(data, "getChar", 1, k)));
-}
-
-// ================================================================
-
-StringType::StringType()
-    :Type("java.lang", "String", BUILT_IN, true, true, false)
-{
-}
-
-string
-StringType::CreatorName() const
-{
-    return "android.os.Parcel.STRING_CREATOR";
-}
-
-void
-StringType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, "writeString", 1, v));
-}
-
-void
-StringType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    addTo->Add(new Assignment(v, new MethodCall(parcel, "readString")));
-}
-
-bool
-StringType::CanBeArray() const
-{
-    return true;
-}
-
-void
-StringType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, "writeStringArray", 1, v));
-}
-
-void
-StringType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel, Variable**)
-{
-    addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray")));
-}
-
-void
-StringType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    addTo->Add(new MethodCall(parcel, "readStringArray", 1, v));
-}
-
-void
-StringType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    addTo->Add(new MethodCall(data, "putString", 2, k, v));
-}
-
-void
-StringType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, Variable**)
-{
-    addTo->Add(new Assignment(v, new MethodCall(data, "getString", 1, k)));
-}
-
-// ================================================================
-
-CharSequenceType::CharSequenceType()
-    :Type("java.lang", "CharSequence", BUILT_IN, true, true, false)
-{
-}
-
-string
-CharSequenceType::CreatorName() const
-{
-    return "android.os.Parcel.STRING_CREATOR";
-}
-
-void
-CharSequenceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    // if (v != null) {
-    //     parcel.writeInt(1);
-    //     v.writeToParcel(parcel);
-    // } else {
-    //     parcel.writeInt(0);
-    // }
-    IfStatement* elsepart = new IfStatement();
-    elsepart->statements->Add(new MethodCall(parcel, "writeInt", 1,
-                                new LiteralExpression("0")));
-    IfStatement* ifpart = new IfStatement;
-    ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
-    ifpart->elseif = elsepart;
-    ifpart->statements->Add(new MethodCall(parcel, "writeInt", 1,
-                                new LiteralExpression("1")));
-    ifpart->statements->Add(new MethodCall(TEXT_UTILS_TYPE, "writeToParcel",
-                                3, v, parcel, BuildWriteToParcelFlags(flags)));
-
-    addTo->Add(ifpart);
-}
-
-void
-CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                Variable* parcel, Variable**)
-{
-    // if (0 != parcel.readInt()) {
-    //     v = TextUtils.createFromParcel(parcel)
-    // } else {
-    //     v = null;
-    // }
-    IfStatement* elsepart = new IfStatement();
-    elsepart->statements->Add(new Assignment(v, NULL_VALUE));
-
-    IfStatement* ifpart = new IfStatement();
-    ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
-                new MethodCall(parcel, "readInt"));
-    ifpart->elseif = elsepart;
-    ifpart->statements->Add(new Assignment(v,
-                new MethodCall(TEXT_UTILS_TYPE,
-                                    "CHAR_SEQUENCE_CREATOR.createFromParcel", 1, parcel)));
-
-    addTo->Add(ifpart);
-}
-
-
-// ================================================================
-
-RemoteExceptionType::RemoteExceptionType()
-    :Type("android.os", "RemoteException", BUILT_IN, false, false, false)
-{
-}
-
-void
-RemoteExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-void
-RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-// ================================================================
-
-RuntimeExceptionType::RuntimeExceptionType()
-    :Type("java.lang", "RuntimeException", BUILT_IN, false, false, false)
-{
-}
-
-void
-RuntimeExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-void
-RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-
-// ================================================================
-
-IBinderType::IBinderType()
-    :Type("android.os", "IBinder", BUILT_IN, true, false, false)
-{
-}
-
-void
-IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, v));
-}
-
-void
-IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder")));
-}
-
-void
-IBinderType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, "writeBinderArray", 1, v));
-}
-
-void
-IBinderType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel, Variable**)
-{
-    addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray")));
-}
-
-void
-IBinderType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v));
-}
-
-
-// ================================================================
-
-IInterfaceType::IInterfaceType()
-    :Type("android.os", "IInterface", BUILT_IN, false, false, false)
-{
-}
-
-void
-IInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-void
-IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-
-// ================================================================
-
-BinderType::BinderType()
-    :Type("android.os", "Binder", BUILT_IN, false, false, false)
-{
-}
-
-void
-BinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-void
-BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable**)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-
-// ================================================================
-
-BinderProxyType::BinderProxyType()
-    :Type("android.os", "BinderProxy", BUILT_IN, false, false, false)
-{
-}
-
-void
-BinderProxyType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-void
-BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable**)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-
-// ================================================================
-
-ParcelType::ParcelType()
-    :Type("android.os", "Parcel", BUILT_IN, false, false, false)
-{
-}
-
-void
-ParcelType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-void
-ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-// ================================================================
-
-ParcelableInterfaceType::ParcelableInterfaceType()
-    :Type("android.os", "Parcelable", BUILT_IN, false, false, false)
-{
-}
-
-void
-ParcelableInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-void
-ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
-}
-
-// ================================================================
-
-MapType::MapType()
-    :Type("java.util", "Map", BUILT_IN, true, false, true)
-{
-}
-
-void
-MapType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, "writeMap", 1, v));
-}
-
-static void EnsureClassLoader(StatementBlock* addTo, Variable** cl)
-{
-    // We don't want to look up the class loader once for every
-    // collection argument, so ensure we do it at most once per method.
-    if (*cl == NULL) {
-        *cl = new Variable(CLASSLOADER_TYPE, "cl");
-        addTo->Add(new VariableDeclaration(*cl,
-                new LiteralExpression("this.getClass().getClassLoader()"),
-                CLASSLOADER_TYPE));
-    }
-}
-
-void
-MapType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
-{
-    EnsureClassLoader(addTo, cl);
-    addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, *cl)));
-}
-
-void
-MapType::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
-{
-    EnsureClassLoader(addTo, cl);
-    addTo->Add(new MethodCall(parcel, "readMap", 2, v, *cl));
-}
-
-
-// ================================================================
-
-ListType::ListType()
-    :Type("java.util", "List", BUILT_IN, true, true, true)
-{
-}
-
-string
-ListType::InstantiableName() const
-{
-    return "java.util.ArrayList";
-}
-
-void
-ListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, "writeList", 1, v));
-}
-
-void
-ListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
-{
-    EnsureClassLoader(addTo, cl);
-    addTo->Add(new Assignment(v, new MethodCall(parcel, "readArrayList", 1, *cl)));
-}
-
-void
-ListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
-                    Variable* parcel, Variable** cl)
-{
-    EnsureClassLoader(addTo, cl);
-    addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl));
-}
-
-void
-ListType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    addTo->Add(new MethodCall(data, "putList", 2, k, v));
-}
-
-void
-ListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
-        Variable** cl)
-{
-    addTo->Add(new Assignment(v, new MethodCall(data, "getList", 1, k)));
-}
-
-// ================================================================
-
-UserDataType::UserDataType(const string& package, const string& name,
-                        bool builtIn, bool canWriteToParcel, bool canWriteToRpcData,
-                        const string& declFile, int declLine)
-    :Type(package, name, builtIn ? BUILT_IN : USERDATA, canWriteToParcel, canWriteToRpcData,
-            true, declFile, declLine)
-{
-}
-
-string
-UserDataType::CreatorName() const
-{
-    return QualifiedName() + ".CREATOR";
-}
-
-string
-UserDataType::RpcCreatorName() const
-{
-    return QualifiedName() + ".RPC_CREATOR";
-}
-
-void
-UserDataType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    // if (v != null) {
-    //     parcel.writeInt(1);
-    //     v.writeToParcel(parcel);
-    // } else {
-    //     parcel.writeInt(0);
-    // }
-    IfStatement* elsepart = new IfStatement();
-    elsepart->statements->Add(new MethodCall(parcel, "writeInt", 1,
-                                new LiteralExpression("0")));
-    IfStatement* ifpart = new IfStatement;
-    ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
-    ifpart->elseif = elsepart;
-    ifpart->statements->Add(new MethodCall(parcel, "writeInt", 1,
-                                new LiteralExpression("1")));
-    ifpart->statements->Add(new MethodCall(v, "writeToParcel", 2,
-                                parcel, BuildWriteToParcelFlags(flags)));
-
-    addTo->Add(ifpart);
-}
-
-void
-UserDataType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    // if (0 != parcel.readInt()) {
-    //     v = CLASS.CREATOR.createFromParcel(parcel)
-    // } else {
-    //     v = null;
-    // }
-    IfStatement* elsepart = new IfStatement();
-    elsepart->statements->Add(new Assignment(v, NULL_VALUE));
-
-    IfStatement* ifpart = new IfStatement();
-    ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
-                new MethodCall(parcel, "readInt"));
-    ifpart->elseif = elsepart;
-    ifpart->statements->Add(new Assignment(v,
-                new MethodCall(v->type, "CREATOR.createFromParcel", 1, parcel)));
-
-    addTo->Add(ifpart);
-}
-
-void
-UserDataType::ReadFromParcel(StatementBlock* addTo, Variable* v,
-                    Variable* parcel, Variable**)
-{
-    // TODO: really, we don't need to have this extra check, but we
-    // don't have two separate marshalling code paths
-    // if (0 != parcel.readInt()) {
-    //     v.readFromParcel(parcel)
-    // }
-    IfStatement* ifpart = new IfStatement();
-    ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
-                new MethodCall(parcel, "readInt"));
-    ifpart->statements->Add(new MethodCall(v, "readFromParcel", 1, parcel));
-    addTo->Add(ifpart);
-}
-
-bool
-UserDataType::CanBeArray() const
-{
-    return true;
-}
-
-void
-UserDataType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v,
-                BuildWriteToParcelFlags(flags)));
-}
-
-void
-UserDataType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel, Variable**)
-{
-    string creator = v->type->QualifiedName() + ".CREATOR";
-    addTo->Add(new Assignment(v, new MethodCall(parcel,
-                "createTypedArray", 1, new LiteralExpression(creator))));
-}
-
-void
-UserDataType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    string creator = v->type->QualifiedName() + ".CREATOR";
-    addTo->Add(new MethodCall(parcel, "readTypedArray", 2,
-                    v, new LiteralExpression(creator)));
-}
-
-void
-UserDataType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags)
-{
-    // data.putFlattenable(k, v);
-    addTo->Add(new MethodCall(data, "putFlattenable", 2, k, v));
-}
-
-void
-UserDataType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl)
-{
-    // data.getFlattenable(k, CLASS.RPC_CREATOR);
-    addTo->Add(new Assignment(v, new MethodCall(data, "getFlattenable", 2, k,
-                new FieldVariable(v->type, "RPC_CREATOR"))));
-}
-
-// ================================================================
-
-InterfaceType::InterfaceType(const string& package, const string& name,
-                        bool builtIn, bool oneway,
-                        const string& declFile, int declLine)
-    :Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false, false,
-                        declFile, declLine)
-    ,m_oneway(oneway)
-{
-}
-
-bool
-InterfaceType::OneWay() const
-{
-    return m_oneway;
-}
-
-void
-InterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    // parcel.writeStrongBinder(v != null ? v.asBinder() : null);
-    addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, 
-                new Ternary(
-                    new Comparison(v, "!=", NULL_VALUE),
-                    new MethodCall(v, "asBinder"),
-                    NULL_VALUE)));
-}
-
-void
-InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    // v = Interface.asInterface(parcel.readStrongBinder());
-    string type = v->type->QualifiedName();
-    type += ".Stub";
-    addTo->Add(new Assignment(v,
-                new MethodCall( NAMES.Find(type), "asInterface", 1,
-                    new MethodCall(parcel, "readStrongBinder"))));
-}
-
-
-// ================================================================
-
-GenericType::GenericType(const string& package, const string& name,
-                         const vector<Type*>& args)
-    :Type(package, name, BUILT_IN, true, true, true)
-{
-    m_args = args;
-
-    m_importName = package + '.' + name;
-
-    string gen = "<";
-    int N = args.size();
-    for (int i=0; i<N; i++) {
-        Type* t = args[i];
-        gen += t->QualifiedName();
-        if (i != N-1) {
-            gen += ',';
-        }
-    }
-    gen += '>';
-    m_genericArguments = gen;
-    SetQualifiedName(m_importName + gen);
-}
-
-const vector<Type*>&
-GenericType::GenericArgumentTypes() const
-{
-    return m_args;
-}
-
-string
-GenericType::GenericArguments() const
-{
-    return m_genericArguments;
-}
-
-string
-GenericType::ImportType() const
-{
-    return m_importName;
-}
-
-void
-GenericType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    fprintf(stderr, "implement GenericType::WriteToParcel\n");
-}
-
-void
-GenericType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    fprintf(stderr, "implement GenericType::CreateFromParcel\n");
-}
-
-void
-GenericType::ReadFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel, Variable**)
-{
-    fprintf(stderr, "implement GenericType::ReadFromParcel\n");
-}
-
-
-// ================================================================
-
-GenericListType::GenericListType(const string& package, const string& name,
-                         const vector<Type*>& args)
-    :GenericType(package, name, args),
-     m_creator(args[0]->CreatorName())
-{
-}
-
-string
-GenericListType::CreatorName() const
-{
-    return "android.os.Parcel.arrayListCreator";
-}
-
-string
-GenericListType::InstantiableName() const
-{
-    return "java.util.ArrayList" + GenericArguments();
-}
-
-void
-GenericListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
-{
-    if (m_creator == STRING_TYPE->CreatorName()) {
-        addTo->Add(new MethodCall(parcel, "writeStringList", 1, v));
-    } else if (m_creator == IBINDER_TYPE->CreatorName()) {
-        addTo->Add(new MethodCall(parcel, "writeBinderList", 1, v));
-    } else {
-        // parcel.writeTypedListXX(arg);
-        addTo->Add(new MethodCall(parcel, "writeTypedList", 1, v));
-    }
-}
-
-void
-GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
-{
-    if (m_creator == STRING_TYPE->CreatorName()) {
-        addTo->Add(new Assignment(v,
-                   new MethodCall(parcel, "createStringArrayList", 0)));
-    } else if (m_creator == IBINDER_TYPE->CreatorName()) {
-        addTo->Add(new Assignment(v,
-                   new MethodCall(parcel, "createBinderArrayList", 0)));
-    } else {
-        // v = _data.readTypedArrayList(XXX.creator);
-        addTo->Add(new Assignment(v,
-                   new MethodCall(parcel, "createTypedArrayList", 1,
-                   new LiteralExpression(m_creator))));
-    }
-}
-
-void
-GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel, Variable**)
-{
-    if (m_creator == STRING_TYPE->CreatorName()) {
-        addTo->Add(new MethodCall(parcel, "readStringList", 1, v));
-    } else if (m_creator == IBINDER_TYPE->CreatorName()) {
-        addTo->Add(new MethodCall(parcel, "readBinderList", 1, v));
-    } else {
-        // v = _data.readTypedList(v, XXX.creator);
-        addTo->Add(new MethodCall(parcel, "readTypedList", 2,
-                       v,
-                       new LiteralExpression(m_creator)));
-    }
-}
-
-void
-GenericListType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    Type* generic = GenericArgumentTypes()[0];
-    if (generic == RPC_DATA_TYPE) {
-        addTo->Add(new MethodCall(data, "putRpcDataList", 2, k, v));
-    } else if (generic->RpcCreatorName() != "") {
-        addTo->Add(new MethodCall(data, "putFlattenableList", 2, k, v));
-    } else {
-        addTo->Add(new MethodCall(data, "putList", 2, k, v));
-    }
-}
-
-void
-GenericListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, Variable** cl)
-{
-    Type* generic = GenericArgumentTypes()[0];
-    if (generic == RPC_DATA_TYPE) {
-        addTo->Add(new Assignment(v, new MethodCall(data, "getRpcDataList", 2, k)));
-    } else if (generic->RpcCreatorName() != "") {
-        addTo->Add(new Assignment(v, new MethodCall(data, "getFlattenableList", 2, k, 
-                        new LiteralExpression(generic->RpcCreatorName()))));
-    } else {
-        string classArg = GenericArgumentTypes()[0]->QualifiedName();
-        classArg += ".class";
-        addTo->Add(new Assignment(v, new MethodCall(data, "getList", 2, k,
-                        new LiteralExpression(classArg))));
-    }
-}
-
-
-// ================================================================
-
-RpcDataType::RpcDataType()
-    :UserDataType("android.support.place.rpc", "RpcData", true, true, true)
-{
-}
-
-void
-RpcDataType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    addTo->Add(new MethodCall(data, "putRpcData", 2, k, v));
-}
-
-void
-RpcDataType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
-        Variable** cl)
-{
-    addTo->Add(new Assignment(v, new MethodCall(data, "getRpcData", 1, k)));
-}
-
-
-// ================================================================
-
-ClassLoaderType::ClassLoaderType()
-    :Type("java.lang", "ClassLoader", BUILT_IN, false, false, false)
-{
-}
-
-
-// ================================================================
-
-Namespace::Namespace()
-{
-}
-
-Namespace::~Namespace()
-{
-    int N = m_types.size();
-    for (int i=0; i<N; i++) {
-        delete m_types[i];
-    }
-}
-
-void
-Namespace::Add(Type* type)
-{
-    Type* t = Find(type->QualifiedName());
-    if (t == NULL) {
-        m_types.push_back(type);
-    }
-}
-
-void
-Namespace::AddGenericType(const string& package, const string& name, int args)
-{
-    Generic g;
-        g.package = package;
-        g.name = name;
-        g.qualified = package + '.' + name;
-        g.args = args;
-    m_generics.push_back(g);
-}
-
-Type*
-Namespace::Find(const string& name) const
-{
-    int N = m_types.size();
-    for (int i=0; i<N; i++) {
-        if (m_types[i]->QualifiedName() == name) {
-            return m_types[i];
-        }
-    }
-    return NULL;
-}
-
-Type*
-Namespace::Find(const char* package, const char* name) const
-{
-    string s;
-    if (package != NULL) {
-        s += package;
-        s += '.';
-    }
-    s += name;
-    return Find(s);
-}
-
-static string
-normalize_generic(const string& s)
-{
-    string r;
-    int N = s.size();
-    for (int i=0; i<N; i++) {
-        char c = s[i];
-        if (!isspace(c)) {
-            r += c;
-        }
-    }
-    return r;
-}
-
-Type*
-Namespace::Search(const string& name)
-{
-    // an exact match wins
-    Type* result = Find(name);
-    if (result != NULL) {
-        return result;
-    }
-
-    // try the class names
-    // our language doesn't allow you to not specify outer classes
-    // when referencing an inner class.  that could be changed, and this
-    // would be the place to do it, but I don't think the complexity in
-    // scoping rules is worth it.
-    int N = m_types.size();
-    for (int i=0; i<N; i++) {
-        if (m_types[i]->Name() == name) {
-            return m_types[i];
-        }
-    }
-
-    // we got to here and it's not a generic, give up
-    if (name.find('<') == name.npos) {
-        return NULL;
-    }
-
-    // remove any whitespace
-    string normalized = normalize_generic(name);
-
-    // find the part before the '<', find a generic for it
-    ssize_t baseIndex = normalized.find('<');
-    string base(normalized.c_str(), baseIndex);
-    const Generic* g = search_generic(base);
-    if (g == NULL) {
-        return NULL;
-    }
-
-    // For each of the args, do a recursive search on it.  We don't allow
-    // generics within generics like Java does, because we're really limiting
-    // them to just built-in container classes, at least for now.  Our syntax
-    // ensures this right now as well.
-    vector<Type*> args;
-    size_t start = baseIndex + 1;
-    size_t end = start;
-    while (normalized[start] != '\0') {
-        end = normalized.find(',', start);
-        if (end == normalized.npos) {
-            end = normalized.find('>', start);
-        }
-        string s(normalized.c_str()+start, end-start);
-        Type* t = this->Search(s);
-        if (t == NULL) {
-            // maybe we should print a warning here?
-            return NULL;
-        }
-        args.push_back(t);
-        start = end+1;
-    }
-
-    // construct a GenericType, add it to our name set so they always get
-    // the same object, and return it.
-    result = make_generic_type(g->package, g->name, args);
-    if (result == NULL) {
-        return NULL;
-    }
-
-    this->Add(result);
-    return this->Find(result->QualifiedName());
-}
-
-const Namespace::Generic*
-Namespace::search_generic(const string& name) const
-{
-    int N = m_generics.size();
-
-    // first exact match
-    for (int i=0; i<N; i++) {
-        const Generic& g = m_generics[i];
-        if (g.qualified == name) {
-            return &g;
-        }
-    }
-
-    // then name match
-    for (int i=0; i<N; i++) {
-        const Generic& g = m_generics[i];
-        if (g.name == name) {
-            return &g;
-        }
-    }
-
-    return NULL;
-}
-
-void
-Namespace::Dump() const
-{
-    int n = m_types.size();
-    for (int i=0; i<n; i++) {
-        Type* t = m_types[i];
-        printf("type: package=%s name=%s qualifiedName=%s\n",
-                t->Package().c_str(), t->Name().c_str(),
-                t->QualifiedName().c_str());
-    }
-}
diff --git a/tools/aidl/Type.h b/tools/aidl/Type.h
deleted file mode 100644
index ae12720..0000000
--- a/tools/aidl/Type.h
+++ /dev/null
@@ -1,542 +0,0 @@
-#ifndef AIDL_TYPE_H
-#define AIDL_TYPE_H
-
-#include "AST.h"
-#include <string>
-#include <vector>
-
-using namespace std;
-
-class Type
-{
-public:
-    // kinds
-    enum {
-        BUILT_IN,
-        USERDATA,
-        INTERFACE,
-        GENERATED
-    };
-    
-    // WriteToParcel flags
-    enum {
-        PARCELABLE_WRITE_RETURN_VALUE = 0x0001
-    };
-
-                    Type(const string& name, int kind, bool canWriteToParcel,
-                            bool canWriteToRpcData, bool canBeOut);
-                    Type(const string& package, const string& name,
-                            int kind, bool canWriteToParcel, bool canWriteToRpcData, bool canBeOut,
-                            const string& declFile = "", int declLine = -1);
-    virtual         ~Type();
-
-    inline string   Package() const             { return m_package; }
-    inline string   Name() const                { return m_name; }
-    inline string   QualifiedName() const       { return m_qualifiedName; }
-    inline int      Kind() const                { return m_kind; }
-    inline string   DeclFile() const            { return m_declFile; }
-    inline int      DeclLine() const            { return m_declLine; }
-    inline bool     CanWriteToParcel() const    { return m_canWriteToParcel; }
-    inline bool     CanWriteToRpcData() const   { return m_canWriteToRpcData; }
-    inline bool     CanBeOutParameter() const   { return m_canBeOut; }
-    
-    virtual string  ImportType() const;
-    virtual string  CreatorName() const;
-    virtual string  RpcCreatorName() const;
-    virtual string  InstantiableName() const;
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual bool    CanBeArray() const;
-
-    virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-
-protected:
-    void SetQualifiedName(const string& qualified);
-    Expression* BuildWriteToParcelFlags(int flags);
-
-private:
-    Type();
-    Type(const Type&);
-
-    string m_package;
-    string m_name;
-    string m_qualifiedName;
-    string m_declFile;
-    int m_declLine;
-    int m_kind;
-    bool m_canWriteToParcel;
-    bool m_canWriteToRpcData;
-    bool m_canBeOut;
-};
-
-class BasicType : public Type
-{
-public:
-                    BasicType(const string& name,
-                              const string& marshallParcel,
-                              const string& unmarshallParcel,
-                              const string& writeArrayParcel,
-                              const string& createArrayParcel,
-                              const string& readArrayParcel,
-                              const string& marshallRpc,
-                              const string& unmarshallRpc,
-                              const string& writeArrayRpc,
-                              const string& createArrayRpc,
-                              const string& readArrayRpc);
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual bool    CanBeArray() const;
-
-    virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-
-private:
-    string m_marshallParcel;
-    string m_unmarshallParcel;
-    string m_writeArrayParcel;
-    string m_createArrayParcel;
-    string m_readArrayParcel;
-    string m_marshallRpc;
-    string m_unmarshallRpc;
-    string m_writeArrayRpc;
-    string m_createArrayRpc;
-    string m_readArrayRpc;
-};
-
-class BooleanType : public Type
-{
-public:
-                    BooleanType();
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual bool    CanBeArray() const;
-
-    virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-};
-
-class CharType : public Type
-{
-public:
-                    CharType();
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual bool    CanBeArray() const;
-
-    virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-};
-
-
-class StringType : public Type
-{
-public:
-                    StringType();
-
-    virtual string  CreatorName() const;
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual bool    CanBeArray() const;
-
-    virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-};
-
-class CharSequenceType : public Type
-{
-public:
-                    CharSequenceType();
-
-    virtual string  CreatorName() const;
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-};
-
-class RemoteExceptionType : public Type
-{
-public:
-                    RemoteExceptionType();
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-};
-
-class RuntimeExceptionType : public Type
-{
-public:
-                    RuntimeExceptionType();
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-};
-
-class IBinderType : public Type
-{
-public:
-                    IBinderType();
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-};
-
-class IInterfaceType : public Type
-{
-public:
-                    IInterfaceType();
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-};
-
-class BinderType : public Type
-{
-public:
-                    BinderType();
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-};
-
-class BinderProxyType : public Type
-{
-public:
-                    BinderProxyType();
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-};
-
-class ParcelType : public Type
-{
-public:
-                    ParcelType();
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-};
-
-class ParcelableInterfaceType : public Type
-{
-public:
-                    ParcelableInterfaceType();
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-};
-
-class MapType : public Type
-{
-public:
-                    MapType();
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-};
-
-class ListType : public Type
-{
-public:
-                    ListType();
-
-    virtual string  InstantiableName() const;
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-};
-
-class UserDataType : public Type
-{
-public:
-                    UserDataType(const string& package, const string& name,
-                            bool builtIn, bool canWriteToParcel, bool canWriteToRpcData,
-                            const string& declFile = "", int declLine = -1);
-
-    virtual string  CreatorName() const;
-    virtual string  RpcCreatorName() const;
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual bool    CanBeArray() const;
-
-    virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-};
-
-class InterfaceType : public Type
-{
-public:
-                    InterfaceType(const string& package, const string& name,
-                            bool builtIn, bool oneway,
-                            const string& declFile, int declLine);
-
-    bool            OneWay() const;
-    
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-                                    
-private:
-    bool m_oneway;
-};
-
-
-class GenericType : public Type
-{
-public:
-                    GenericType(const string& package, const string& name,
-                                 const vector<Type*>& args);
-
-    const vector<Type*>& GenericArgumentTypes() const;
-    string          GenericArguments() const;
-
-    virtual string  ImportType() const;
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-private:
-    string m_genericArguments;
-    string m_importName;
-    vector<Type*> m_args;
-};
-
-class RpcDataType : public UserDataType
-{
-public:
-                    RpcDataType();
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-};
-
-class ClassLoaderType : public Type
-{
-public:
-                    ClassLoaderType();
-};
-
-class GenericListType : public GenericType
-{
-public:
-                    GenericListType(const string& package, const string& name,
-                                 const vector<Type*>& args);
-
-    virtual string  CreatorName() const;
-    virtual string  InstantiableName() const;
-
-    virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, int flags);
-    virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-    virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-    
-private:
-    string m_creator;
-};
-
-class Namespace
-{
-public:
-            Namespace();
-            ~Namespace();
-    void    Add(Type* type);
-
-    // args is the number of template types (what is this called?)
-    void    AddGenericType(const string& package, const string& name, int args);
-
-    // lookup a specific class name
-    Type*   Find(const string& name) const;
-    Type*   Find(const char* package, const char* name) const;
-    
-    // try to search by either a full name or a partial name
-    Type*   Search(const string& name);
-
-    void    Dump() const;
-
-private:
-    struct Generic {
-        string package;
-        string name;
-        string qualified;
-        int args;
-    };
-
-    const Generic* search_generic(const string& name) const;
-
-    vector<Type*> m_types;
-    vector<Generic> m_generics;
-};
-
-extern Namespace NAMES;
-
-extern Type* VOID_TYPE;
-extern Type* BOOLEAN_TYPE;
-extern Type* BYTE_TYPE;
-extern Type* CHAR_TYPE;
-extern Type* INT_TYPE;
-extern Type* LONG_TYPE;
-extern Type* FLOAT_TYPE;
-extern Type* DOUBLE_TYPE;
-extern Type* OBJECT_TYPE;
-extern Type* STRING_TYPE;
-extern Type* CHAR_SEQUENCE_TYPE;
-extern Type* TEXT_UTILS_TYPE;
-extern Type* REMOTE_EXCEPTION_TYPE;
-extern Type* RUNTIME_EXCEPTION_TYPE;
-extern Type* IBINDER_TYPE;
-extern Type* IINTERFACE_TYPE;
-extern Type* BINDER_NATIVE_TYPE;
-extern Type* BINDER_PROXY_TYPE;
-extern Type* PARCEL_TYPE;
-extern Type* PARCELABLE_INTERFACE_TYPE;
-
-extern Type* CONTEXT_TYPE;
-
-extern Type* RPC_DATA_TYPE;
-extern Type* RPC_ERROR_TYPE;
-extern Type* RPC_CONTEXT_TYPE;
-extern Type* EVENT_FAKE_TYPE;
-
-extern Expression* NULL_VALUE;
-extern Expression* THIS_VALUE;
-extern Expression* SUPER_VALUE;
-extern Expression* TRUE_VALUE;
-extern Expression* FALSE_VALUE;
-
-void register_base_types();
-
-#endif // AIDL_TYPE_H
diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp
deleted file mode 100644
index b8a4803..0000000
--- a/tools/aidl/aidl.cpp
+++ /dev/null
@@ -1,1155 +0,0 @@
-
-#include "aidl_language.h"
-#include "options.h"
-#include "search_path.h"
-#include "Type.h"
-#include "generate_java.h"
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <map>
-
-#ifdef HAVE_MS_C_RUNTIME
-#include <io.h>
-#include <sys/stat.h>
-#endif
-
-#ifndef O_BINARY
-#  define O_BINARY  0
-#endif
-
-// The following are gotten as the offset from the allowable id's between
-// android.os.IBinder.FIRST_CALL_TRANSACTION=1 and
-// android.os.IBinder.LAST_CALL_TRANSACTION=16777215
-#define MIN_USER_SET_METHOD_ID                0
-#define MAX_USER_SET_METHOD_ID                16777214
-
-using namespace std;
-
-static void
-test_document(document_item_type* d)
-{
-    while (d) {
-        if (d->item_type == INTERFACE_TYPE_BINDER) {
-            interface_type* c = (interface_type*)d;
-            printf("interface %s %s {\n", c->package, c->name.data);
-            interface_item_type *q = (interface_item_type*)c->interface_items;
-            while (q) {
-                if (q->item_type == METHOD_TYPE) {
-                    method_type *m = (method_type*)q;
-                    printf("  %s %s(", m->type.type.data, m->name.data);
-                    arg_type *p = m->args;
-                    while (p) {
-                        printf("%s %s",p->type.type.data,p->name.data);
-                        if (p->next) printf(", ");
-                        p=p->next;
-                    }
-                    printf(")");
-                    printf(";\n");
-                }
-                q=q->next;
-            }
-            printf("}\n");
-        }
-        else if (d->item_type == USER_DATA_TYPE) {
-            user_data_type* b = (user_data_type*)d;
-            if ((b->flattening_methods & PARCELABLE_DATA) != 0) {
-                printf("parcelable %s %s;\n", b->package, b->name.data);
-            }
-            if ((b->flattening_methods & RPC_DATA) != 0) {
-                printf("flattenable %s %s;\n", b->package, b->name.data);
-            }
-        }
-        else {
-            printf("UNKNOWN d=0x%08lx d->item_type=%d\n", (long)d, d->item_type);
-        }
-        d = d->next;
-    }
-}
-
-// ==========================================================
-int
-convert_direction(const char* direction)
-{
-    if (direction == NULL) {
-        return IN_PARAMETER;
-    }
-    if (0 == strcmp(direction, "in")) {
-        return IN_PARAMETER;
-    }
-    if (0 == strcmp(direction, "out")) {
-        return OUT_PARAMETER;
-    }
-    return INOUT_PARAMETER;
-}
-
-// ==========================================================
-struct import_info {
-    const char* from;
-    const char* filename;
-    buffer_type statement;
-    const char* neededClass;
-    document_item_type* doc;
-    struct import_info* next;
-};
-
-document_item_type* g_document = NULL;
-import_info* g_imports = NULL;
-
-static void
-main_document_parsed(document_item_type* d)
-{
-    g_document = d;
-}
-
-static void
-main_import_parsed(buffer_type* statement)
-{
-    import_info* import = (import_info*)malloc(sizeof(import_info));
-    memset(import, 0, sizeof(import_info));
-    import->from = strdup(g_currentFilename);
-    import->statement.lineno = statement->lineno;
-    import->statement.data = strdup(statement->data);
-    import->statement.extra = NULL;
-    import->next = g_imports;
-    import->neededClass = parse_import_statement(statement->data);
-    g_imports = import;
-}
-
-static ParserCallbacks g_mainCallbacks = {
-    &main_document_parsed,
-    &main_import_parsed
-};
-
-char*
-parse_import_statement(const char* text)
-{
-    const char* end;
-    int len;
-
-    while (isspace(*text)) {
-        text++;
-    }
-    while (!isspace(*text)) {
-        text++;
-    }
-    while (isspace(*text)) {
-        text++;
-    }
-    end = text;
-    while (!isspace(*end) && *end != ';') {
-        end++;
-    }
-    len = end-text;
-
-    char* rv = (char*)malloc(len+1);
-    memcpy(rv, text, len);
-    rv[len] = '\0';
-
-    return rv;
-}
-
-// ==========================================================
-static void
-import_import_parsed(buffer_type* statement)
-{
-}
-
-static ParserCallbacks g_importCallbacks = {
-    &main_document_parsed,
-    &import_import_parsed
-};
-
-// ==========================================================
-static int
-check_filename(const char* filename, const char* package, buffer_type* name)
-{
-    const char* p;
-    string expected;
-    string fn;
-    size_t len;
-    char cwd[MAXPATHLEN];
-    bool valid = false;
-
-#ifdef HAVE_WINDOWS_PATHS
-    if (isalpha(filename[0]) && filename[1] == ':'
-        && filename[2] == OS_PATH_SEPARATOR) {
-#else
-    if (filename[0] == OS_PATH_SEPARATOR) {
-#endif
-        fn = filename;
-    } else {
-        fn = getcwd(cwd, sizeof(cwd));
-        len = fn.length();
-        if (fn[len-1] != OS_PATH_SEPARATOR) {
-            fn += OS_PATH_SEPARATOR;
-        }
-        fn += filename;
-    }
-
-    if (package) {
-        expected = package;
-        expected += '.';
-    }
-
-    len = expected.length();
-    for (size_t i=0; i<len; i++) {
-        if (expected[i] == '.') {
-            expected[i] = OS_PATH_SEPARATOR;
-        }
-    }
-
-    p = strchr(name->data, '.');
-    len = p ? p-name->data : strlen(name->data);
-    expected.append(name->data, len);
-    
-    expected += ".aidl";
-
-    len = fn.length();
-    valid = (len >= expected.length());
-
-    if (valid) {
-        p = fn.c_str() + (len - expected.length());
-
-#ifdef HAVE_WINDOWS_PATHS
-        if (OS_PATH_SEPARATOR != '/') {
-            // Input filename under cygwin most likely has / separators
-            // whereas the expected string uses \\ separators. Adjust
-            // them accordingly.
-          for (char *c = const_cast<char *>(p); *c; ++c) {
-                if (*c == '/') *c = OS_PATH_SEPARATOR;
-            }
-        }
-#endif
-
-#ifdef OS_CASE_SENSITIVE
-        valid = (expected == p);
-#else
-        valid = !strcasecmp(expected.c_str(), p);
-#endif
-    }
-
-    if (!valid) {
-        fprintf(stderr, "%s:%d interface %s should be declared in a file"
-                " called %s.\n",
-                filename, name->lineno, name->data, expected.c_str());
-        return 1;
-    }
-
-    return 0;
-}
-
-static int
-check_filenames(const char* filename, document_item_type* items)
-{
-    int err = 0;
-    while (items) {
-        if (items->item_type == USER_DATA_TYPE) {
-            user_data_type* p = (user_data_type*)items;
-            err |= check_filename(filename, p->package, &p->name);
-        }
-        else if (items->item_type == INTERFACE_TYPE_BINDER
-                || items->item_type == INTERFACE_TYPE_RPC) {
-            interface_type* c = (interface_type*)items;
-            err |= check_filename(filename, c->package, &c->name);
-        }
-        else {
-            fprintf(stderr, "aidl: internal error unkown document type %d.\n",
-                        items->item_type);
-            return 1;
-        }
-        items = items->next;
-    }
-    return err;
-}
-
-// ==========================================================
-static const char*
-kind_to_string(int kind)
-{
-    switch (kind)
-    {
-        case Type::INTERFACE:
-            return "an interface";
-        case Type::USERDATA:
-            return "a user data";
-        default:
-            return "ERROR";
-    }
-}
-
-static char*
-rfind(char* str, char c)
-{
-    char* p = str + strlen(str) - 1;
-    while (p >= str) {
-        if (*p == c) {
-            return p;
-        }
-        p--;
-    }
-    return NULL;
-}
-
-static int
-gather_types(const char* filename, document_item_type* items)
-{
-    int err = 0;
-    while (items) {
-        Type* type;
-        if (items->item_type == USER_DATA_TYPE) {
-            user_data_type* p = (user_data_type*)items;
-            type = new UserDataType(p->package ? p->package : "", p->name.data,
-                    false, ((p->flattening_methods & PARCELABLE_DATA) != 0),
-                    ((p->flattening_methods & RPC_DATA) != 0), filename, p->name.lineno);
-        }
-        else if (items->item_type == INTERFACE_TYPE_BINDER
-                || items->item_type == INTERFACE_TYPE_RPC) {
-            interface_type* c = (interface_type*)items;
-            type = new InterfaceType(c->package ? c->package : "",
-                            c->name.data, false, c->oneway,
-                            filename, c->name.lineno);
-        }
-        else {
-            fprintf(stderr, "aidl: internal error %s:%d\n", __FILE__, __LINE__);
-            return 1;
-        }
-
-        Type* old = NAMES.Find(type->QualifiedName());
-        if (old == NULL) {
-            NAMES.Add(type);
-
-            if (items->item_type == INTERFACE_TYPE_BINDER) {
-                // for interfaces, also add the stub and proxy types, we don't
-                // bother checking these for duplicates, because the parser
-                // won't let us do it.
-                interface_type* c = (interface_type*)items;
-
-                string name = c->name.data;
-                name += ".Stub";
-                Type* stub = new Type(c->package ? c->package : "",
-                                        name, Type::GENERATED, false, false, false,
-                                        filename, c->name.lineno);
-                NAMES.Add(stub);
-
-                name = c->name.data;
-                name += ".Stub.Proxy";
-                Type* proxy = new Type(c->package ? c->package : "",
-                                        name, Type::GENERATED, false, false, false,
-                                        filename, c->name.lineno);
-                NAMES.Add(proxy);
-            }
-            else if (items->item_type == INTERFACE_TYPE_RPC) {
-                // for interfaces, also add the service base type, we don't
-                // bother checking these for duplicates, because the parser
-                // won't let us do it.
-                interface_type* c = (interface_type*)items;
-
-                string name = c->name.data;
-                name += ".ServiceBase";
-                Type* base = new Type(c->package ? c->package : "",
-                                        name, Type::GENERATED, false, false, false,
-                                        filename, c->name.lineno);
-                NAMES.Add(base);
-            }
-        } else {
-            if (old->Kind() == Type::BUILT_IN) {
-                fprintf(stderr, "%s:%d attempt to redefine built in class %s\n",
-                            filename, type->DeclLine(),
-                            type->QualifiedName().c_str());
-                err = 1;
-            }
-            else if (type->Kind() != old->Kind()) {
-                const char* oldKind = kind_to_string(old->Kind());
-                const char* newKind = kind_to_string(type->Kind());
-
-                fprintf(stderr, "%s:%d attempt to redefine %s as %s,\n",
-                            filename, type->DeclLine(),
-                            type->QualifiedName().c_str(), newKind);
-                fprintf(stderr, "%s:%d    previously defined here as %s.\n",
-                            old->DeclFile().c_str(), old->DeclLine(), oldKind);
-                err = 1;
-            }
-        }
-
-        items = items->next;
-    }
-    return err;
-}
-
-// ==========================================================
-static bool
-matches_keyword(const char* str)
-{
-    static const char* KEYWORDS[] = { "abstract", "assert", "boolean", "break",
-        "byte", "case", "catch", "char", "class", "const", "continue",
-        "default", "do", "double", "else", "enum", "extends", "final",
-        "finally", "float", "for", "goto", "if", "implements", "import",
-        "instanceof", "int", "interface", "long", "native", "new", "package",
-        "private", "protected", "public", "return", "short", "static",
-        "strictfp", "super", "switch", "synchronized", "this", "throw",
-        "throws", "transient", "try", "void", "volatile", "while",
-        "true", "false", "null",
-        NULL
-    };
-    const char** k = KEYWORDS;
-    while (*k) {
-        if (0 == strcmp(str, *k)) {
-            return true;
-        }
-        k++;
-    }
-    return false;
-}
-
-static int
-check_method(const char* filename, int kind, method_type* m)
-{
-    int err = 0;
-
-    // return type
-    Type* returnType = NAMES.Search(m->type.type.data);
-    if (returnType == NULL) {
-        fprintf(stderr, "%s:%d unknown return type %s\n", filename,
-                    m->type.type.lineno, m->type.type.data);
-        err = 1;
-        return err;
-    }
-
-    if (returnType == EVENT_FAKE_TYPE) {
-        if (kind != INTERFACE_TYPE_RPC) {
-            fprintf(stderr, "%s:%d event methods only supported for rpc interfaces\n",
-                    filename, m->type.type.lineno);
-            err = 1;
-        }
-    } else {
-        if (!(kind == INTERFACE_TYPE_BINDER ? returnType->CanWriteToParcel()
-                    : returnType->CanWriteToRpcData())) {
-            fprintf(stderr, "%s:%d return type %s can't be marshalled.\n", filename,
-                        m->type.type.lineno, m->type.type.data);
-            err = 1;
-        }
-    }
-
-    if (m->type.dimension > 0 && !returnType->CanBeArray()) {
-        fprintf(stderr, "%s:%d return type %s%s can't be an array.\n", filename,
-                m->type.array_token.lineno, m->type.type.data,
-                m->type.array_token.data);
-        err = 1;
-    }
-
-    if (m->type.dimension > 1) {
-        fprintf(stderr, "%s:%d return type %s%s only one"
-                " dimensional arrays are supported\n", filename,
-                m->type.array_token.lineno, m->type.type.data,
-                m->type.array_token.data);
-        err = 1;
-    }
-
-    int index = 1;
-
-    arg_type* arg = m->args;
-    while (arg) {
-        Type* t = NAMES.Search(arg->type.type.data);
-
-        // check the arg type
-        if (t == NULL) {
-            fprintf(stderr, "%s:%d parameter %s (%d) unknown type %s\n",
-                    filename, m->type.type.lineno, arg->name.data, index,
-                    arg->type.type.data);
-            err = 1;
-            goto next;
-        }
-
-        if (t == EVENT_FAKE_TYPE) {
-            fprintf(stderr, "%s:%d parameter %s (%d) event can not be used as a parameter %s\n",
-                    filename, m->type.type.lineno, arg->name.data, index,
-                    arg->type.type.data);
-            err = 1;
-            goto next;
-        }
-        
-        if (!(kind == INTERFACE_TYPE_BINDER ? t->CanWriteToParcel() : t->CanWriteToRpcData())) {
-            fprintf(stderr, "%s:%d parameter %d: '%s %s' can't be marshalled.\n",
-                        filename, m->type.type.lineno, index,
-                        arg->type.type.data, arg->name.data);
-            err = 1;
-        }
-
-        if (returnType == EVENT_FAKE_TYPE
-                && convert_direction(arg->direction.data) != IN_PARAMETER) {
-            fprintf(stderr, "%s:%d parameter %d: '%s %s' All paremeters on events must be 'in'.\n",
-                    filename, m->type.type.lineno, index,
-                    arg->type.type.data, arg->name.data);
-            err = 1;
-            goto next;
-        }
-
-        if (arg->direction.data == NULL
-                && (arg->type.dimension != 0 || t->CanBeOutParameter())) {
-            fprintf(stderr, "%s:%d parameter %d: '%s %s' can be an out"
-                                " parameter, so you must declare it as in,"
-                                " out or inout.\n",
-                        filename, m->type.type.lineno, index,
-                        arg->type.type.data, arg->name.data);
-            err = 1;
-        }
-
-        if (convert_direction(arg->direction.data) != IN_PARAMETER
-                && !t->CanBeOutParameter()
-                && arg->type.dimension == 0) {
-            fprintf(stderr, "%s:%d parameter %d: '%s %s %s' can only be an in"
-                            " parameter.\n",
-                        filename, m->type.type.lineno, index,
-                        arg->direction.data, arg->type.type.data,
-                        arg->name.data);
-            err = 1;
-        }
-
-        if (arg->type.dimension > 0 && !t->CanBeArray()) {
-            fprintf(stderr, "%s:%d parameter %d: '%s %s%s %s' can't be an"
-                    " array.\n", filename,
-                    m->type.array_token.lineno, index, arg->direction.data,
-                    arg->type.type.data, arg->type.array_token.data,
-                    arg->name.data);
-            err = 1;
-        }
-
-        if (arg->type.dimension > 1) {
-            fprintf(stderr, "%s:%d parameter %d: '%s %s%s %s' only one"
-                    " dimensional arrays are supported\n", filename,
-                    m->type.array_token.lineno, index, arg->direction.data,
-                    arg->type.type.data, arg->type.array_token.data,
-                    arg->name.data);
-            err = 1;
-        }
-
-        // check that the name doesn't match a keyword
-        if (matches_keyword(arg->name.data)) {
-            fprintf(stderr, "%s:%d parameter %d %s is named the same as a"
-                    " Java or aidl keyword\n",
-                    filename, m->name.lineno, index, arg->name.data);
-            err = 1;
-        }
-        
-next:
-        index++;
-        arg = arg->next;
-    }
-
-    return err;
-}
-
-static int
-check_types(const char* filename, document_item_type* items)
-{
-    int err = 0;
-    while (items) {
-        // (nothing to check for USER_DATA_TYPE)
-        if (items->item_type == INTERFACE_TYPE_BINDER
-                || items->item_type == INTERFACE_TYPE_RPC) {
-            map<string,method_type*> methodNames;
-            interface_type* c = (interface_type*)items;
-
-            interface_item_type* member = c->interface_items;
-            while (member) {
-                if (member->item_type == METHOD_TYPE) {
-                    method_type* m = (method_type*)member;
-
-                    err |= check_method(filename, items->item_type, m);
-
-                    // prevent duplicate methods
-                    if (methodNames.find(m->name.data) == methodNames.end()) {
-                        methodNames[m->name.data] = m;
-                    } else {
-                        fprintf(stderr,"%s:%d attempt to redefine method %s,\n",
-                                filename, m->name.lineno, m->name.data);
-                        method_type* old = methodNames[m->name.data];
-                        fprintf(stderr, "%s:%d    previously defined here.\n",
-                                filename, old->name.lineno);
-                        err = 1;
-                    }
-                }
-                member = member->next;
-            }
-        }
-
-        items = items->next;
-    }
-    return err;
-}
-
-// ==========================================================
-static int
-exactly_one_interface(const char* filename, const document_item_type* items, const Options& options,
-                      bool* onlyParcelable)
-{
-    if (items == NULL) {
-        fprintf(stderr, "%s: file does not contain any interfaces\n",
-                            filename);
-        return 1;
-    }
-
-    const document_item_type* next = items->next;
-    // Allow parcelables to skip the "one-only" rule.
-    if (items->next != NULL && next->item_type != USER_DATA_TYPE) {
-        int lineno = -1;
-        if (next->item_type == INTERFACE_TYPE_BINDER) {
-            lineno = ((interface_type*)next)->interface_token.lineno;
-        }
-        else if (next->item_type == INTERFACE_TYPE_RPC) {
-            lineno = ((interface_type*)next)->interface_token.lineno;
-        }
-        fprintf(stderr, "%s:%d aidl can only handle one interface per file\n",
-                            filename, lineno);
-        return 1;
-    }
-
-    if (items->item_type == USER_DATA_TYPE) {
-        *onlyParcelable = true;
-        if (options.failOnParcelable) {
-            fprintf(stderr, "%s:%d aidl can only generate code for interfaces, not"
-                            " parcelables or flattenables,\n", filename,
-                            ((user_data_type*)items)->keyword_token.lineno);
-            fprintf(stderr, "%s:%d .aidl files that only declare parcelables or flattenables"
-                            "may not go in the Makefile.\n", filename,
-                            ((user_data_type*)items)->keyword_token.lineno);
-            return 1;
-        }
-    } else {
-        *onlyParcelable = false;
-    }
-
-    return 0;
-}
-
-// ==========================================================
-void
-generate_dep_file(const Options& options, const document_item_type* items)
-{
-    /* we open the file in binary mode to ensure that the same output is
-     * generated on all platforms !!
-     */
-    FILE* to = NULL;
-    if (options.autoDepFile) {
-        string fileName = options.outputFileName + ".d";
-        to = fopen(fileName.c_str(), "wb");
-    } else {
-        to = fopen(options.depFileName.c_str(), "wb");
-    }
-
-    if (to == NULL) {
-        return;
-    }
-
-    const char* slash = "\\";
-    import_info* import = g_imports;
-    if (import == NULL) {
-        slash = "";
-    }
-
-    if (items->item_type == INTERFACE_TYPE_BINDER || items->item_type == INTERFACE_TYPE_RPC) {
-        fprintf(to, "%s: \\\n", options.outputFileName.c_str());
-    } else {
-        // parcelable: there's no output file.
-        fprintf(to, " : \\\n");
-    }
-    fprintf(to, "  %s %s\n", options.inputFileName.c_str(), slash);
-
-    while (import) {
-        if (import->next == NULL) {
-            slash = "";
-        }
-        if (import->filename) {
-            fprintf(to, "  %s %s\n", import->filename, slash);
-        }
-        import = import->next;
-    }
-
-    fprintf(to, "\n");
-
-    // Output "<imported_file>: " so make won't fail if the imported file has
-    // been deleted, moved or renamed in incremental build.
-    import = g_imports;
-    while (import) {
-        if (import->filename) {
-            fprintf(to, "%s :\n", import->filename);
-        }
-        import = import->next;
-    }
-
-    fclose(to);
-}
-
-// ==========================================================
-static string
-generate_outputFileName2(const Options& options, const buffer_type& name, const char* package)
-{
-    string result;
-
-    // create the path to the destination folder based on the
-    // interface package name
-    result = options.outputBaseFolder;
-    result += OS_PATH_SEPARATOR;
-
-    string packageStr = package;
-    size_t len = packageStr.length();
-    for (size_t i=0; i<len; i++) {
-        if (packageStr[i] == '.') {
-            packageStr[i] = OS_PATH_SEPARATOR;
-        }
-    }
-
-    result += packageStr;
-
-    // add the filename by replacing the .aidl extension to .java
-    const char* p = strchr(name.data, '.');
-    len = p ? p-name.data : strlen(name.data);
-
-    result += OS_PATH_SEPARATOR;
-    result.append(name.data, len);
-    result += ".java";
-
-    return result;
-}
-
-// ==========================================================
-static string
-generate_outputFileName(const Options& options, const document_item_type* items)
-{
-    // items has already been checked to have only one interface.
-    if (items->item_type == INTERFACE_TYPE_BINDER || items->item_type == INTERFACE_TYPE_RPC) {
-        interface_type* type = (interface_type*)items;
-
-        return generate_outputFileName2(options, type->name, type->package);
-    } else if (items->item_type == USER_DATA_TYPE) {
-        user_data_type* type = (user_data_type*)items;
-        return generate_outputFileName2(options, type->name, type->package);
-    }
-
-    // I don't think we can come here, but safer than returning NULL.
-    string result;
-    return result;
-}
-
-
-
-// ==========================================================
-static void
-check_outputFilePath(const string& path) {
-    size_t len = path.length();
-    for (size_t i=0; i<len ; i++) {
-        if (path[i] == OS_PATH_SEPARATOR) {
-            string p = path.substr(0, i);
-            if (access(path.data(), F_OK) != 0) {
-#ifdef HAVE_MS_C_RUNTIME
-                _mkdir(p.data());
-#else
-                mkdir(p.data(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
-#endif
-            }
-        }
-    }
-}
-
-
-// ==========================================================
-static int
-parse_preprocessed_file(const string& filename)
-{
-    int err;
-
-    FILE* f = fopen(filename.c_str(), "rb");
-    if (f == NULL) {
-        fprintf(stderr, "aidl: can't open preprocessed file: %s\n",
-                filename.c_str());
-        return 1;
-    }
-
-    int lineno = 1;
-    char line[1024];
-    char type[1024];
-    char fullname[1024];
-    while (fgets(line, sizeof(line), f)) {
-        // skip comments and empty lines
-        if (!line[0] || strncmp(line, "//", 2) == 0) {
-          continue;
-        }
-
-        sscanf(line, "%s %[^; \r\n\t];", type, fullname);
-
-        char* packagename;
-        char* classname = rfind(fullname, '.');
-        if (classname != NULL) {
-            *classname = '\0';
-            classname++;
-            packagename = fullname;
-        } else {
-            classname = fullname;
-            packagename = NULL;
-        }
-
-        //printf("%s:%d:...%s...%s...%s...\n", filename.c_str(), lineno,
-        //        type, packagename, classname);
-        document_item_type* doc;
-        
-        if (0 == strcmp("parcelable", type)) {
-            user_data_type* parcl = (user_data_type*)malloc(
-                    sizeof(user_data_type));
-            memset(parcl, 0, sizeof(user_data_type));
-            parcl->document_item.item_type = USER_DATA_TYPE;
-            parcl->keyword_token.lineno = lineno;
-            parcl->keyword_token.data = strdup(type);
-            parcl->package = packagename ? strdup(packagename) : NULL;
-            parcl->name.lineno = lineno;
-            parcl->name.data = strdup(classname);
-            parcl->semicolon_token.lineno = lineno;
-            parcl->semicolon_token.data = strdup(";");
-            parcl->flattening_methods = PARCELABLE_DATA;
-            doc = (document_item_type*)parcl;
-        }
-        else if (0 == strcmp("flattenable", type)) {
-            user_data_type* parcl = (user_data_type*)malloc(
-                    sizeof(user_data_type));
-            memset(parcl, 0, sizeof(user_data_type));
-            parcl->document_item.item_type = USER_DATA_TYPE;
-            parcl->keyword_token.lineno = lineno;
-            parcl->keyword_token.data = strdup(type);
-            parcl->package = packagename ? strdup(packagename) : NULL;
-            parcl->name.lineno = lineno;
-            parcl->name.data = strdup(classname);
-            parcl->semicolon_token.lineno = lineno;
-            parcl->semicolon_token.data = strdup(";");
-            parcl->flattening_methods = RPC_DATA;
-            doc = (document_item_type*)parcl;
-        }
-        else if (0 == strcmp("interface", type)) {
-            interface_type* iface = (interface_type*)malloc(
-                    sizeof(interface_type));
-            memset(iface, 0, sizeof(interface_type));
-            iface->document_item.item_type = INTERFACE_TYPE_BINDER;
-            iface->interface_token.lineno = lineno;
-            iface->interface_token.data = strdup(type);
-            iface->package = packagename ? strdup(packagename) : NULL;
-            iface->name.lineno = lineno;
-            iface->name.data = strdup(classname);
-            iface->open_brace_token.lineno = lineno;
-            iface->open_brace_token.data = strdup("{");
-            iface->close_brace_token.lineno = lineno;
-            iface->close_brace_token.data = strdup("}");
-            doc = (document_item_type*)iface;
-        }
-        else {
-            fprintf(stderr, "%s:%d: bad type in line: %s\n",
-                    filename.c_str(), lineno, line);
-            return 1;
-        }
-        err = gather_types(filename.c_str(), doc);
-        lineno++;
-    }
-
-    if (!feof(f)) {
-        fprintf(stderr, "%s:%d: error reading file, line to long.\n",
-                filename.c_str(), lineno);
-        return 1;
-    }
-
-    fclose(f);
-    return 0;
-}
-
-static int
-check_and_assign_method_ids(const char * filename, interface_item_type* first_item)
-{
-    // Check whether there are any methods with manually assigned id's and any that are not.
-    // Either all method id's must be manually assigned or all of them must not.
-    // Also, check for duplicates of user set id's and that the id's are within the proper bounds.
-    set<int> usedIds;
-    interface_item_type* item = first_item;
-    bool hasUnassignedIds = false;
-    bool hasAssignedIds = false;
-    while (item != NULL) {
-        if (item->item_type == METHOD_TYPE) {
-            method_type* method_item = (method_type*)item;
-            if (method_item->hasId) {
-                hasAssignedIds = true;
-                method_item->assigned_id = atoi(method_item->id.data);
-                // Ensure that the user set id is not duplicated.
-                if (usedIds.find(method_item->assigned_id) != usedIds.end()) {
-                    // We found a duplicate id, so throw an error.
-                    fprintf(stderr,
-                            "%s:%d Found duplicate method id (%d) for method: %s\n",
-                            filename, method_item->id.lineno,
-                            method_item->assigned_id, method_item->name.data);
-                    return 1;
-                }
-                // Ensure that the user set id is within the appropriate limits
-                if (method_item->assigned_id < MIN_USER_SET_METHOD_ID ||
-                        method_item->assigned_id > MAX_USER_SET_METHOD_ID) {
-                    fprintf(stderr, "%s:%d Found out of bounds id (%d) for method: %s\n",
-                            filename, method_item->id.lineno,
-                            method_item->assigned_id, method_item->name.data);
-                    fprintf(stderr, "    Value for id must be between %d and %d inclusive.\n",
-                            MIN_USER_SET_METHOD_ID, MAX_USER_SET_METHOD_ID);
-                    return 1;
-                }
-                usedIds.insert(method_item->assigned_id);
-            } else {
-                hasUnassignedIds = true;
-            }
-            if (hasAssignedIds && hasUnassignedIds) {
-                fprintf(stderr,
-                        "%s: You must either assign id's to all methods or to none of them.\n",
-                        filename);
-                return 1;
-            }
-        }
-        item = item->next;
-    }
-
-    // In the case that all methods have unassigned id's, set a unique id for them.
-    if (hasUnassignedIds) {
-        int newId = 0;
-        item = first_item;
-        while (item != NULL) {
-            if (item->item_type == METHOD_TYPE) {
-                method_type* method_item = (method_type*)item;
-                method_item->assigned_id = newId++;
-            }
-            item = item->next;
-        }
-    }
-
-    // success
-    return 0;
-}
-
-// ==========================================================
-static int
-compile_aidl(Options& options)
-{
-    int err = 0, N;
-
-    set_import_paths(options.importPaths);
-
-    register_base_types();
-
-    // import the preprocessed file
-    N = options.preprocessedFiles.size();
-    for (int i=0; i<N; i++) {
-        const string& s = options.preprocessedFiles[i];
-        err |= parse_preprocessed_file(s);
-    }
-    if (err != 0) {
-        return err;
-    }
-
-    // parse the main file
-    g_callbacks = &g_mainCallbacks;
-    err = parse_aidl(options.inputFileName.c_str());
-    document_item_type* mainDoc = g_document;
-    g_document = NULL;
-
-    // parse the imports
-    g_callbacks = &g_mainCallbacks;
-    import_info* import = g_imports;
-    while (import) {
-        if (NAMES.Find(import->neededClass) == NULL) {
-            import->filename = find_import_file(import->neededClass);
-            if (!import->filename) {
-                fprintf(stderr, "%s:%d: couldn't find import for class %s\n",
-                        import->from, import->statement.lineno,
-                        import->neededClass);
-                err |= 1;
-            } else {
-                err |= parse_aidl(import->filename);
-                import->doc = g_document;
-                if (import->doc == NULL) {
-                    err |= 1;
-                }
-            }
-        }
-        import = import->next;
-    }
-    // bail out now if parsing wasn't successful
-    if (err != 0 || mainDoc == NULL) {
-        //fprintf(stderr, "aidl: parsing failed, stopping.\n");
-        return 1;
-    }
-
-    // complain about ones that aren't in the right files
-    err |= check_filenames(options.inputFileName.c_str(), mainDoc);
-    import = g_imports;
-    while (import) {
-        err |= check_filenames(import->filename, import->doc);
-        import = import->next;
-    }
-
-    // gather the types that have been declared
-    err |= gather_types(options.inputFileName.c_str(), mainDoc);
-    import = g_imports;
-    while (import) {
-        err |= gather_types(import->filename, import->doc);
-        import = import->next;
-    }
-
-#if 0
-    printf("---- main doc ----\n");
-    test_document(mainDoc);
-
-    import = g_imports;
-    while (import) {
-        printf("---- import doc ----\n");
-        test_document(import->doc);
-        import = import->next;
-    }
-    NAMES.Dump();
-#endif
-
-    // check the referenced types in mainDoc to make sure we've imported them
-    err |= check_types(options.inputFileName.c_str(), mainDoc);
-
-    // finally, there really only needs to be one thing in mainDoc, and it
-    // needs to be an interface.
-    bool onlyParcelable = false;
-    err |= exactly_one_interface(options.inputFileName.c_str(), mainDoc, options, &onlyParcelable);
-
-    // If this includes an interface definition, then assign method ids and validate.
-    if (!onlyParcelable) {
-        err |= check_and_assign_method_ids(options.inputFileName.c_str(),
-                ((interface_type*)mainDoc)->interface_items);
-    }
-
-    // after this, there shouldn't be any more errors because of the
-    // input.
-    if (err != 0 || mainDoc == NULL) {
-        return 1;
-    }
-
-    // if needed, generate the outputFileName from the outputBaseFolder
-    if (options.outputFileName.length() == 0 &&
-            options.outputBaseFolder.length() > 0) {
-        options.outputFileName = generate_outputFileName(options, mainDoc);
-    }
-
-    // if we were asked to, generate a make dependency file
-    // unless it's a parcelable *and* it's supposed to fail on parcelable
-    if ((options.autoDepFile || options.depFileName != "") &&
-            !(onlyParcelable && options.failOnParcelable)) {
-        // make sure the folders of the output file all exists
-        check_outputFilePath(options.outputFileName);
-        generate_dep_file(options, mainDoc);
-    }
-
-    // they didn't ask to fail on parcelables, so just exit quietly.
-    if (onlyParcelable && !options.failOnParcelable) {
-        return 0;
-    }
-
-    // make sure the folders of the output file all exists
-    check_outputFilePath(options.outputFileName);
-
-    err = generate_java(options.outputFileName, options.inputFileName.c_str(),
-                        (interface_type*)mainDoc);
-
-    return err;
-}
-
-static int
-preprocess_aidl(const Options& options)
-{
-    vector<string> lines;
-    int err;
-
-    // read files
-    int N = options.filesToPreprocess.size();
-    for (int i=0; i<N; i++) {
-        g_callbacks = &g_mainCallbacks;
-        err = parse_aidl(options.filesToPreprocess[i].c_str());
-        if (err != 0) {
-            return err;
-        }
-        document_item_type* doc = g_document;
-        string line;
-        if (doc->item_type == USER_DATA_TYPE) {
-            user_data_type* parcelable = (user_data_type*)doc;
-            if ((parcelable->flattening_methods & PARCELABLE_DATA) != 0) {
-                line = "parcelable ";
-            }
-            if ((parcelable->flattening_methods & RPC_DATA) != 0) {
-                line = "flattenable ";
-            }
-            if (parcelable->package) {
-                line += parcelable->package;
-                line += '.';
-            }
-            line += parcelable->name.data;
-        } else {
-            line = "interface ";
-            interface_type* iface = (interface_type*)doc;
-            if (iface->package) {
-                line += iface->package;
-                line += '.';
-            }
-            line += iface->name.data;
-        }
-        line += ";\n";
-        lines.push_back(line);
-    }
-
-    // write preprocessed file
-    int fd = open( options.outputFileName.c_str(), 
-                   O_RDWR|O_CREAT|O_TRUNC|O_BINARY,
-#ifdef HAVE_MS_C_RUNTIME
-                   _S_IREAD|_S_IWRITE);
-#else    
-                   S_IRUSR|S_IWUSR|S_IRGRP);
-#endif            
-    if (fd == -1) {
-        fprintf(stderr, "aidl: could not open file for write: %s\n",
-                options.outputFileName.c_str());
-        return 1;
-    }
-
-    N = lines.size();
-    for (int i=0; i<N; i++) {
-        const string& s = lines[i];
-        int len = s.length();
-        if (len != write(fd, s.c_str(), len)) {
-            fprintf(stderr, "aidl: error writing to file %s\n",
-                options.outputFileName.c_str());
-            close(fd);
-            unlink(options.outputFileName.c_str());
-            return 1;
-        }
-    }
-
-    close(fd);
-    return 0;
-}
-
-// ==========================================================
-int
-main(int argc, const char **argv)
-{
-    Options options;
-    int result = parse_options(argc, argv, &options);
-    if (result) {
-        return result;
-    }
-
-    switch (options.task)
-    {
-        case COMPILE_AIDL:
-            return compile_aidl(options);
-        case PREPROCESS_AIDL:
-            return preprocess_aidl(options);
-    }
-    fprintf(stderr, "aidl: internal error\n");
-    return 1;
-}
diff --git a/tools/aidl/aidl_language.cpp b/tools/aidl/aidl_language.cpp
deleted file mode 100644
index cd6a3bd..0000000
--- a/tools/aidl/aidl_language.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "aidl_language.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#ifdef HAVE_MS_C_RUNTIME
-int isatty(int  fd)
-{
-    return (fd == 0);
-}
-#endif
-
-#if 0
-ParserCallbacks k_parserCallbacks = {
-    NULL
-};
-#endif
-
-ParserCallbacks* g_callbacks = NULL; // &k_parserCallbacks;
-
diff --git a/tools/aidl/aidl_language.h b/tools/aidl/aidl_language.h
deleted file mode 100644
index de1370c..0000000
--- a/tools/aidl/aidl_language.h
+++ /dev/null
@@ -1,172 +0,0 @@
-#ifndef DEVICE_TOOLS_AIDL_AIDL_LANGUAGE_H
-#define DEVICE_TOOLS_AIDL_AIDL_LANGUAGE_H
-
-
-typedef enum {
-    NO_EXTRA_TEXT = 0,
-    SHORT_COMMENT,
-    LONG_COMMENT,
-    COPY_TEXT,
-    WHITESPACE
-} which_extra_text;
-
-typedef struct extra_text_type {
-    unsigned lineno;
-    which_extra_text which;
-    char* data; 
-    unsigned len;
-    struct extra_text_type* next;
-} extra_text_type;
-
-typedef struct buffer_type {
-    unsigned lineno;
-    unsigned token;
-    char *data;
-    extra_text_type* extra;
-} buffer_type;
-
-typedef struct type_type {
-    buffer_type type;
-    buffer_type array_token;
-    int dimension;
-} type_type;
-
-typedef struct arg_type {
-    buffer_type comma_token; // empty in the first one in the list
-    buffer_type direction;
-    type_type type;
-    buffer_type name;
-    struct arg_type *next;
-} arg_type;
-
-enum {
-    METHOD_TYPE
-};
-
-typedef struct interface_item_type {
-    unsigned item_type;
-    struct interface_item_type* next;
-} interface_item_type;
-
-typedef struct method_type {
-    interface_item_type interface_item;
-    type_type type;
-    bool oneway;
-    buffer_type oneway_token;
-    buffer_type name;
-    buffer_type open_paren_token;
-    arg_type* args;
-    buffer_type close_paren_token;
-    bool hasId;
-    buffer_type equals_token;
-    buffer_type id;
-    // XXX missing comments/copy text here
-    buffer_type semicolon_token;
-    buffer_type* comments_token; // points into this structure, DO NOT DELETE
-    int assigned_id;
-} method_type;
-
-enum {
-    USER_DATA_TYPE = 12,
-    INTERFACE_TYPE_BINDER,
-    INTERFACE_TYPE_RPC
-};
-
-typedef struct document_item_type {
-    unsigned item_type;
-    struct document_item_type* next;
-} document_item_type;
-
-
-// for user_data_type.flattening_methods
-enum {
-    PARCELABLE_DATA = 0x1,
-    RPC_DATA = 0x2
-};
-
-typedef struct user_data_type {
-    document_item_type document_item;
-    buffer_type keyword_token; // only the first one
-    char* package;
-    buffer_type name;
-    buffer_type semicolon_token;
-    int flattening_methods;
-} user_data_type;
-
-typedef struct interface_type {
-    document_item_type document_item;
-    buffer_type interface_token;
-    bool oneway;
-    buffer_type oneway_token;
-    char* package;
-    buffer_type name;
-    buffer_type open_brace_token;
-    interface_item_type* interface_items;
-    buffer_type close_brace_token;
-    buffer_type* comments_token; // points into this structure, DO NOT DELETE
-} interface_type;
-
-typedef union lexer_type {
-    buffer_type buffer;
-    type_type type;
-    arg_type *arg;
-    method_type* method;
-    interface_item_type* interface_item;
-    interface_type* interface_obj;
-    user_data_type* user_data;
-    document_item_type* document_item;
-} lexer_type;
-
-
-#define YYSTYPE lexer_type
-
-#if __cplusplus
-extern "C" {
-#endif
-
-int parse_aidl(char const *);
-
-// strips off the leading whitespace, the "import" text
-// also returns whether it's a local or system import
-// we rely on the input matching the import regex from below
-char* parse_import_statement(const char* text);
-
-// in, out or inout
-enum {
-    IN_PARAMETER = 1,
-    OUT_PARAMETER = 2,
-    INOUT_PARAMETER = 3
-};
-int convert_direction(const char* direction);
-
-// callbacks from within the parser
-// these functions all take ownership of the strings
-typedef struct ParserCallbacks {
-    void (*document)(document_item_type* items);
-    void (*import)(buffer_type* statement);
-} ParserCallbacks;
-
-extern ParserCallbacks* g_callbacks;
-
-// true if there was an error parsing, false otherwise
-extern int g_error;
-
-// the name of the file we're currently parsing
-extern char const* g_currentFilename;
-
-// the package name for our current file
-extern char const* g_currentPackage;
-
-typedef enum {
-    STATEMENT_INSIDE_INTERFACE
-} error_type;
-
-void init_buffer_type(buffer_type* buf, int lineno);
-
-
-#if __cplusplus
-}
-#endif
-
-
-#endif // DEVICE_TOOLS_AIDL_AIDL_LANGUAGE_H
diff --git a/tools/aidl/aidl_language_l.l b/tools/aidl/aidl_language_l.l
deleted file mode 100644
index 3d33e7a..0000000
--- a/tools/aidl/aidl_language_l.l
+++ /dev/null
@@ -1,214 +0,0 @@
-%{
-#include "aidl_language.h"
-#include "aidl_language_y.h"
-#include "search_path.h"
-#include <string.h>
-#include <stdlib.h>
-
-extern YYSTYPE yylval;
-
-// comment and whitespace handling
-// these functions save a copy of the buffer
-static void begin_extra_text(unsigned lineno, which_extra_text which);
-static void append_extra_text(char* text);
-static extra_text_type* get_extra_text(void);   // you now own the object
-                                                // this returns
-static void drop_extra_text(void);
-
-// package handling
-static void do_package_statement(const char* importText);
-
-#define SET_BUFFER(t) \
-    do { \
-        yylval.buffer.lineno = yylineno; \
-        yylval.buffer.token = (t); \
-        yylval.buffer.data = strdup(yytext); \
-        yylval.buffer.extra = get_extra_text(); \
-    } while(0)
-
-%}
-
-%option yylineno
-%option noyywrap
-
-%x COPYING LONG_COMMENT
-
-identifier  [_a-zA-Z][_a-zA-Z0-9\.]*
-whitespace  ([ \t\n\r]+)
-brackets    \[{whitespace}?\]
-idvalue     (0|[1-9][0-9]*)
-
-%%
-
-
-\%\%\{              { begin_extra_text(yylineno, COPY_TEXT); BEGIN(COPYING); }
-<COPYING>\}\%\%     { BEGIN(INITIAL); }
-<COPYING>.*\n       { append_extra_text(yytext); }
-<COPYING>.*         { append_extra_text(yytext); }
-<COPYING>\n+        { append_extra_text(yytext); }
-
-
-\/\*                            { begin_extra_text(yylineno, (which_extra_text)LONG_COMMENT);
-                                  BEGIN(LONG_COMMENT); }
-<LONG_COMMENT>[^*]*             { append_extra_text(yytext); }
-<LONG_COMMENT>\*+[^/]           { append_extra_text(yytext); }
-<LONG_COMMENT>\n                { append_extra_text(yytext); }
-<LONG_COMMENT>\**\/             { BEGIN(INITIAL); }
-
-^{whitespace}?import{whitespace}[^ \t\r\n]+{whitespace}?;  {
-                                                SET_BUFFER(IMPORT);
-                                                return IMPORT;
-                                            }
-^{whitespace}?package{whitespace}[^ \t\r\n]+{whitespace}?;  {
-                                                do_package_statement(yytext);
-                                                SET_BUFFER(PACKAGE);
-                                                return PACKAGE;
-                                            }
-<<EOF>>             { yyterminate(); }
-
-\/\/.*\n            { begin_extra_text(yylineno, SHORT_COMMENT);
-                        append_extra_text(yytext); }
-
-{whitespace}    { /* begin_extra_text(yylineno, WHITESPACE);
-                    append_extra_text(yytext); */ }
-
-;               { SET_BUFFER(';'); return ';'; }
-\{              { SET_BUFFER('{'); return '{'; }
-\}              { SET_BUFFER('}'); return '}'; }
-\(              { SET_BUFFER('('); return '('; }
-\)              { SET_BUFFER(')'); return ')'; }
-,               { SET_BUFFER(','); return ','; }
-=               { SET_BUFFER('='); return '='; }
-
-    /* keywords */
-parcelable      { SET_BUFFER(PARCELABLE); return PARCELABLE; }
-interface       { SET_BUFFER(INTERFACE); return INTERFACE; }
-flattenable     { SET_BUFFER(FLATTENABLE); return FLATTENABLE; }
-rpc             { SET_BUFFER(INTERFACE); return RPC; }
-in              { SET_BUFFER(IN); return IN; }
-out             { SET_BUFFER(OUT); return OUT; }
-inout           { SET_BUFFER(INOUT); return INOUT; }
-oneway          { SET_BUFFER(ONEWAY); return ONEWAY; }
-
-{brackets}+     { SET_BUFFER(ARRAY); return ARRAY; }
-{idvalue}       { SET_BUFFER(IDVALUE); return IDVALUE; }
-{identifier}                                        { SET_BUFFER(IDENTIFIER); return IDENTIFIER; }
-{identifier}\<{whitespace}*{identifier}({whitespace}*,{whitespace}*{identifier})*{whitespace}*\>    {
-                                                      SET_BUFFER(GENERIC); return GENERIC; }
-
-    /* syntax error! */
-.               { printf("UNKNOWN(%s)", yytext);
-                  yylval.buffer.lineno = yylineno;
-                  yylval.buffer.token = IDENTIFIER;
-                  yylval.buffer.data = strdup(yytext);
-                  return IDENTIFIER;
-                }
-
-%%
-
-// comment and whitespace handling
-// ================================================
-extra_text_type* g_extraText = NULL;
-extra_text_type* g_nextExtraText = NULL;
-
-void begin_extra_text(unsigned lineno, which_extra_text which)
-{
-    extra_text_type* text = (extra_text_type*)malloc(sizeof(extra_text_type));
-    text->lineno = lineno;
-    text->which = which;
-    text->data = NULL;
-    text->len = 0;
-    text->next = NULL;
-    if (g_nextExtraText == NULL) {
-        g_extraText = text;
-    } else {
-        g_nextExtraText->next = text;
-    }
-    g_nextExtraText = text;
-}
-
-void append_extra_text(char* text)
-{
-    if (g_nextExtraText->data == NULL) {
-        g_nextExtraText->data = strdup(text);
-        g_nextExtraText->len = strlen(text);
-    } else {
-        char* orig = g_nextExtraText->data;
-        unsigned oldLen = g_nextExtraText->len;
-        unsigned len = strlen(text);
-        g_nextExtraText->len += len;
-        g_nextExtraText->data = (char*)malloc(g_nextExtraText->len+1);
-        memcpy(g_nextExtraText->data, orig, oldLen);
-        memcpy(g_nextExtraText->data+oldLen, text, len);
-        g_nextExtraText->data[g_nextExtraText->len] = '\0';
-        free(orig);
-    }
-}
-
-extra_text_type*
-get_extra_text(void)
-{
-    extra_text_type* result = g_extraText;
-    g_extraText = NULL;
-    g_nextExtraText = NULL;
-    return result;
-}
-
-void drop_extra_text(void)
-{
-    extra_text_type* p = g_extraText;
-    while (p) {
-        extra_text_type* next = p->next;
-        free(p->data);
-        free(p);
-        free(next);
-    }
-    g_extraText = NULL;
-    g_nextExtraText = NULL;
-}
-
-
-// package handling
-// ================================================
-void do_package_statement(const char* importText)
-{
-    if (g_currentPackage) free((void*)g_currentPackage);
-    g_currentPackage = parse_import_statement(importText);
-}
-
-
-// main parse function
-// ================================================
-char const* g_currentFilename = NULL;
-char const* g_currentPackage = NULL;
-
-int yyparse(void);
-
-int parse_aidl(char const *filename)
-{
-    yyin = fopen(filename, "r");
-    if (yyin) {
-        char const* oldFilename = g_currentFilename;
-        char const* oldPackage = g_currentPackage;
-        g_currentFilename = strdup(filename);
-
-        g_error = 0;
-        yylineno = 1;
-        int rv = yyparse();
-        if (g_error != 0) {
-            rv = g_error;
-        }
-
-        free((void*)g_currentFilename);
-        g_currentFilename = oldFilename;
-        
-        if (g_currentPackage) free((void*)g_currentPackage);
-        g_currentPackage = oldPackage;
-
-        return rv;
-    } else {
-        fprintf(stderr, "aidl: unable to open file for read: %s\n", filename);
-        return 1;
-    }
-}
-
diff --git a/tools/aidl/aidl_language_y.y b/tools/aidl/aidl_language_y.y
deleted file mode 100644
index 9b40d28..0000000
--- a/tools/aidl/aidl_language_y.y
+++ /dev/null
@@ -1,373 +0,0 @@
-%{
-#include "aidl_language.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-int yyerror(char* errstr);
-int yylex(void);
-extern int yylineno;
-
-static int count_brackets(const char*);
-
-%}
-
-%token IMPORT
-%token PACKAGE
-%token IDENTIFIER
-%token IDVALUE
-%token GENERIC
-%token ARRAY
-%token PARCELABLE
-%token INTERFACE
-%token FLATTENABLE
-%token RPC
-%token IN
-%token OUT
-%token INOUT
-%token ONEWAY
-
-%%
-document:
-        document_items                          { g_callbacks->document($1.document_item); }
-    |   headers document_items                  { g_callbacks->document($2.document_item); }
-    ;
-
-headers:
-        package                                 { }
-    |   imports                                 { }
-    |   package imports                         { }
-    ;
-
-package:
-        PACKAGE                                 { }
-    ;
-
-imports:
-        IMPORT                                  { g_callbacks->import(&($1.buffer)); }
-    |   IMPORT imports                          { g_callbacks->import(&($1.buffer)); }
-    ;
-
-document_items:
-                                                { $$.document_item = NULL; }
-    |   document_items declaration              {
-                                                    if ($2.document_item == NULL) {
-                                                        // error cases only
-                                                        $$ = $1;
-                                                    } else {
-                                                        document_item_type* p = $1.document_item;
-                                                        while (p && p->next) {
-                                                            p=p->next;
-                                                        }
-                                                        if (p) {
-                                                            p->next = (document_item_type*)$2.document_item;
-                                                            $$ = $1;
-                                                        } else {
-                                                            $$.document_item = (document_item_type*)$2.document_item;
-                                                        }
-                                                    }
-                                                }
-    | document_items error                      {
-                                                    fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n", g_currentFilename,
-                                                            $2.buffer.lineno, $2.buffer.data);
-                                                    $$ = $1;
-                                                }
-    ;
-
-declaration:
-        parcelable_decl                            { $$.document_item = (document_item_type*)$1.user_data; }
-    |   interface_decl                             { $$.document_item = (document_item_type*)$1.interface_item; }
-    ;
-
-parcelable_decl:
-        PARCELABLE IDENTIFIER ';'                   {
-                                                        user_data_type* b = (user_data_type*)malloc(sizeof(user_data_type));
-                                                        b->document_item.item_type = USER_DATA_TYPE;
-                                                        b->document_item.next = NULL;
-                                                        b->keyword_token = $1.buffer;
-                                                        b->name = $2.buffer;
-                                                        b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
-                                                        b->semicolon_token = $3.buffer;
-                                                        b->flattening_methods = PARCELABLE_DATA;
-                                                        $$.user_data = b;
-                                                    }
-    |   PARCELABLE ';'                              {
-                                                        fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n",
-                                                                     g_currentFilename, $1.buffer.lineno);
-                                                        $$.user_data = NULL;
-                                                    }
-    |   PARCELABLE error ';'                        {
-                                                        fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n",
-                                                                     g_currentFilename, $2.buffer.lineno, $2.buffer.data);
-                                                        $$.user_data = NULL;
-                                                    }
-    |   FLATTENABLE IDENTIFIER ';'                  {
-                                                        user_data_type* b = (user_data_type*)malloc(sizeof(user_data_type));
-                                                        b->document_item.item_type = USER_DATA_TYPE;
-                                                        b->document_item.next = NULL;
-                                                        b->keyword_token = $1.buffer;
-                                                        b->name = $2.buffer;
-                                                        b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
-                                                        b->semicolon_token = $3.buffer;
-                                                        b->flattening_methods = PARCELABLE_DATA | RPC_DATA;
-                                                        $$.user_data = b;
-                                                    }
-    |   FLATTENABLE ';'                             {
-                                                        fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name.\n",
-                                                                     g_currentFilename, $1.buffer.lineno);
-                                                        $$.user_data = NULL;
-                                                    }
-    |   FLATTENABLE error ';'                       {
-                                                        fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name, saw \"%s\".\n",
-                                                                     g_currentFilename, $2.buffer.lineno, $2.buffer.data);
-                                                        $$.user_data = NULL;
-                                                    }
-
-    ;
-
-interface_header:
-        INTERFACE                                  {
-                                                        interface_type* c = (interface_type*)malloc(sizeof(interface_type));
-                                                        c->document_item.item_type = INTERFACE_TYPE_BINDER;
-                                                        c->document_item.next = NULL;
-                                                        c->interface_token = $1.buffer;
-                                                        c->oneway = false;
-                                                        memset(&c->oneway_token, 0, sizeof(buffer_type));
-                                                        c->comments_token = &c->interface_token;
-                                                        $$.interface_obj = c;
-                                                   }
-    |   ONEWAY INTERFACE                           {
-                                                        interface_type* c = (interface_type*)malloc(sizeof(interface_type));
-                                                        c->document_item.item_type = INTERFACE_TYPE_BINDER;
-                                                        c->document_item.next = NULL;
-                                                        c->interface_token = $2.buffer;
-                                                        c->oneway = true;
-                                                        c->oneway_token = $1.buffer;
-                                                        c->comments_token = &c->oneway_token;
-                                                        $$.interface_obj = c;
-                                                   }
-    |   RPC                                        {
-                                                        interface_type* c = (interface_type*)malloc(sizeof(interface_type));
-                                                        c->document_item.item_type = INTERFACE_TYPE_RPC;
-                                                        c->document_item.next = NULL;
-                                                        c->interface_token = $1.buffer;
-                                                        c->oneway = false;
-                                                        memset(&c->oneway_token, 0, sizeof(buffer_type));
-                                                        c->comments_token = &c->interface_token;
-                                                        $$.interface_obj = c;
-                                                   }
-    ;
-
-interface_keywords:
-        INTERFACE
-    |   RPC
-    ;
-
-interface_decl:
-        interface_header IDENTIFIER '{' interface_items '}' { 
-                                                        interface_type* c = $1.interface_obj;
-                                                        c->name = $2.buffer;
-                                                        c->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
-                                                        c->open_brace_token = $3.buffer;
-                                                        c->interface_items = $4.interface_item;
-                                                        c->close_brace_token = $5.buffer;
-                                                        $$.interface_obj = c;
-                                                    }
-    |   interface_keywords error '{' interface_items '}'     {
-                                                        fprintf(stderr, "%s:%d: syntax error in interface declaration.  Expected type name, saw \"%s\"\n",
-                                                                    g_currentFilename, $2.buffer.lineno, $2.buffer.data);
-                                                        $$.document_item = NULL;
-                                                    }
-    |   interface_keywords error '}'                {
-                                                        fprintf(stderr, "%s:%d: syntax error in interface declaration.  Expected type name, saw \"%s\"\n",
-                                                                    g_currentFilename, $2.buffer.lineno, $2.buffer.data);
-                                                        $$.document_item = NULL;
-                                                    }
-
-    ;
-
-interface_items:
-                                                    { $$.interface_item = NULL; }
-    |   interface_items method_decl                 {
-                                                        interface_item_type* p=$1.interface_item;
-                                                        while (p && p->next) {
-                                                            p=p->next;
-                                                        }
-                                                        if (p) {
-                                                            p->next = (interface_item_type*)$2.method;
-                                                            $$ = $1;
-                                                        } else {
-                                                            $$.interface_item = (interface_item_type*)$2.method;
-                                                        }
-                                                    }
-    |   interface_items error ';'                   {
-                                                        fprintf(stderr, "%s:%d: syntax error before ';' (expected method declaration)\n",
-                                                                    g_currentFilename, $3.buffer.lineno);
-                                                        $$ = $1;
-                                                    }
-    ;
-
-method_decl:
-        type IDENTIFIER '(' arg_list ')' ';'  {
-                                                        method_type *method = (method_type*)malloc(sizeof(method_type));
-                                                        method->interface_item.item_type = METHOD_TYPE;
-                                                        method->interface_item.next = NULL;
-                                                        method->oneway = false;
-                                                        method->type = $1.type;
-                                                        memset(&method->oneway_token, 0, sizeof(buffer_type));
-                                                        method->name = $2.buffer;
-                                                        method->open_paren_token = $3.buffer;
-                                                        method->args = $4.arg;
-                                                        method->close_paren_token = $5.buffer;
-                                                        method->hasId = false;
-                                                        memset(&method->equals_token, 0, sizeof(buffer_type));
-                                                        memset(&method->id, 0, sizeof(buffer_type));
-                                                        method->semicolon_token = $6.buffer;
-                                                        method->comments_token = &method->type.type;
-                                                        $$.method = method;
-                                                    }
-    |   ONEWAY type IDENTIFIER '(' arg_list ')' ';'  {
-                                                        method_type *method = (method_type*)malloc(sizeof(method_type));
-                                                        method->interface_item.item_type = METHOD_TYPE;
-                                                        method->interface_item.next = NULL;
-                                                        method->oneway = true;
-                                                        method->oneway_token = $1.buffer;
-                                                        method->type = $2.type;
-                                                        method->name = $3.buffer;
-                                                        method->open_paren_token = $4.buffer;
-                                                        method->args = $5.arg;
-                                                        method->close_paren_token = $6.buffer;
-                                                        method->hasId = false;
-                                                        memset(&method->equals_token, 0, sizeof(buffer_type));
-                                                        memset(&method->id, 0, sizeof(buffer_type));
-                                                        method->semicolon_token = $7.buffer;
-                                                        method->comments_token = &method->oneway_token;
-                                                        $$.method = method;
-                                                    }
-    |    type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';'  {
-                                                        method_type *method = (method_type*)malloc(sizeof(method_type));
-                                                        method->interface_item.item_type = METHOD_TYPE;
-                                                        method->interface_item.next = NULL;
-                                                        method->oneway = false;
-                                                        memset(&method->oneway_token, 0, sizeof(buffer_type));
-                                                        method->type = $1.type;
-                                                        method->name = $2.buffer;
-                                                        method->open_paren_token = $3.buffer;
-                                                        method->args = $4.arg;
-                                                        method->close_paren_token = $5.buffer;
-                                                        method->hasId = true;
-                                                        method->equals_token = $6.buffer;
-                                                        method->id = $7.buffer;
-                                                        method->semicolon_token = $8.buffer;
-                                                        method->comments_token = &method->type.type;
-                                                        $$.method = method;
-                                                    }
-    |   ONEWAY type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';'  {
-                                                        method_type *method = (method_type*)malloc(sizeof(method_type));
-                                                        method->interface_item.item_type = METHOD_TYPE;
-                                                        method->interface_item.next = NULL;
-                                                        method->oneway = true;
-                                                        method->oneway_token = $1.buffer;
-                                                        method->type = $2.type;
-                                                        method->name = $3.buffer;
-                                                        method->open_paren_token = $4.buffer;
-                                                        method->args = $5.arg;
-                                                        method->close_paren_token = $6.buffer;
-                                                        method->hasId = true;
-                                                        method->equals_token = $7.buffer;
-                                                        method->id = $8.buffer;
-                                                        method->semicolon_token = $9.buffer;
-                                                        method->comments_token = &method->oneway_token;
-                                                        $$.method = method;
-                                                    }
-    ;
-
-arg_list:
-                                { $$.arg = NULL; }
-    |   arg                     { $$ = $1; }
-    |   arg_list ',' arg        {
-                                    if ($$.arg != NULL) {
-                                        // only NULL on error
-                                        $$ = $1;
-                                        arg_type *p = $1.arg;
-                                        while (p && p->next) {
-                                            p=p->next;
-                                        }
-                                        $3.arg->comma_token = $2.buffer;
-                                        p->next = $3.arg;
-                                    }
-                                }
-    |   error                   {
-                                    fprintf(stderr, "%s:%d: syntax error in parameter list\n", g_currentFilename, $1.buffer.lineno);
-                                    $$.arg = NULL;
-                                }
-    ;
-
-arg:
-        direction type IDENTIFIER     {
-                                                arg_type* arg = (arg_type*)malloc(sizeof(arg_type));
-                                                memset(&arg->comma_token, 0, sizeof(buffer_type));
-                                                arg->direction = $1.buffer;
-                                                arg->type = $2.type;
-                                                arg->name = $3.buffer;
-                                                arg->next = NULL;
-                                                $$.arg = arg;
-                                      }
-    ;
-
-type:
-        IDENTIFIER              {
-                                    $$.type.type = $1.buffer;
-                                    init_buffer_type(&$$.type.array_token, yylineno);
-                                    $$.type.dimension = 0;
-                                }
-    |   IDENTIFIER ARRAY        {
-                                    $$.type.type = $1.buffer;
-                                    $$.type.array_token = $2.buffer;
-                                    $$.type.dimension = count_brackets($2.buffer.data);
-                                }
-    |   GENERIC                 {
-                                    $$.type.type = $1.buffer;
-                                    init_buffer_type(&$$.type.array_token, yylineno);
-                                    $$.type.dimension = 0;
-                                }
-    ;
-
-direction:
-                    { init_buffer_type(&$$.buffer, yylineno); }
-    |   IN          { $$.buffer = $1.buffer; }
-    |   OUT         { $$.buffer = $1.buffer; }
-    |   INOUT       { $$.buffer = $1.buffer; }
-    ;
-
-%%
-
-#include <ctype.h>
-#include <stdio.h>
-
-int g_error = 0;
-
-int yyerror(char* errstr)
-{
-    fprintf(stderr, "%s:%d: %s\n", g_currentFilename, yylineno, errstr);
-    g_error = 1;
-    return 1;
-}
-
-void init_buffer_type(buffer_type* buf, int lineno)
-{
-    buf->lineno = lineno;
-    buf->token = 0;
-    buf->data = NULL;
-    buf->extra = NULL;
-}
-
-static int count_brackets(const char* s)
-{
-    int n=0;
-    while (*s) {
-        if (*s == '[') n++;
-        s++;
-    }
-    return n;
-}
diff --git a/tools/aidl/generate_java.cpp b/tools/aidl/generate_java.cpp
deleted file mode 100644
index 9e57407..0000000
--- a/tools/aidl/generate_java.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-#include "generate_java.h"
-#include "Type.h"
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-// =================================================
-VariableFactory::VariableFactory(const string& base)
-    :m_base(base),
-     m_index(0)
-{
-}
-
-Variable*
-VariableFactory::Get(Type* type)
-{
-    char name[100];
-    sprintf(name, "%s%d", m_base.c_str(), m_index);
-    m_index++;
-    Variable* v = new Variable(type, name);
-    m_vars.push_back(v);
-    return v;
-}
-
-Variable*
-VariableFactory::Get(int index)
-{
-    return m_vars[index];
-}
-
-// =================================================
-string
-gather_comments(extra_text_type* extra)
-{
-    string s;
-    while (extra) {
-        if (extra->which == SHORT_COMMENT) {
-            s += extra->data;
-        }
-        else if (extra->which == LONG_COMMENT) {
-            s += "/*";
-            s += extra->data;
-            s += "*/";
-        }
-        extra = extra->next;
-    }
-    return s;
-}
-
-string
-append(const char* a, const char* b)
-{
-    string s = a;
-    s += b;
-    return s;
-}
-
-// =================================================
-int
-generate_java(const string& filename, const string& originalSrc,
-                interface_type* iface)
-{
-    Class* cl;
-
-    if (iface->document_item.item_type == INTERFACE_TYPE_BINDER) {
-        cl = generate_binder_interface_class(iface);
-    }
-    else if (iface->document_item.item_type == INTERFACE_TYPE_RPC) {
-        cl = generate_rpc_interface_class(iface);
-    }
-
-    Document* document = new Document;
-        document->comment = "";
-        if (iface->package) document->package = iface->package;
-        document->originalSrc = originalSrc;
-        document->classes.push_back(cl);
-
-//    printf("outputting... filename=%s\n", filename.c_str());
-    FILE* to;
-    if (filename == "-") {
-        to = stdout;
-    } else {
-       /* open file in binary mode to ensure that the tool produces the
-        * same output on all platforms !!
-        */
-        to = fopen(filename.c_str(), "wb");
-        if (to == NULL) {
-            fprintf(stderr, "unable to open %s for write\n", filename.c_str());
-            return 1;
-        }
-    }
-
-    document->Write(to);
-
-    fclose(to);
-    return 0;
-}
-
diff --git a/tools/aidl/generate_java.h b/tools/aidl/generate_java.h
deleted file mode 100644
index 4bfcfeb..0000000
--- a/tools/aidl/generate_java.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef GENERATE_JAVA_H
-#define GENERATE_JAVA_H
-
-#include "aidl_language.h"
-#include "AST.h"
-
-#include <string>
-
-using namespace std;
-
-int generate_java(const string& filename, const string& originalSrc,
-                interface_type* iface);
-
-Class* generate_binder_interface_class(const interface_type* iface);
-Class* generate_rpc_interface_class(const interface_type* iface);
-
-string gather_comments(extra_text_type* extra);
-string append(const char* a, const char* b);
-
-class VariableFactory
-{
-public:
-    VariableFactory(const string& base); // base must be short
-    Variable* Get(Type* type);
-    Variable* Get(int index);
-private:
-    vector<Variable*> m_vars;
-    string m_base;
-    int m_index;
-};
-
-#endif // GENERATE_JAVA_H
-
diff --git a/tools/aidl/generate_java_binder.cpp b/tools/aidl/generate_java_binder.cpp
deleted file mode 100644
index f291ceb..0000000
--- a/tools/aidl/generate_java_binder.cpp
+++ /dev/null
@@ -1,560 +0,0 @@
-#include "generate_java.h"
-#include "Type.h"
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-// =================================================
-class StubClass : public Class
-{
-public:
-    StubClass(Type* type, Type* interfaceType);
-    virtual ~StubClass();
-
-    Variable* transact_code;
-    Variable* transact_data;
-    Variable* transact_reply;
-    Variable* transact_flags;
-    SwitchStatement* transact_switch;
-private:
-    void make_as_interface(Type* interfaceType);
-};
-
-StubClass::StubClass(Type* type, Type* interfaceType)
-    :Class()
-{
-    this->comment = "/** Local-side IPC implementation stub class. */";
-    this->modifiers = PUBLIC | ABSTRACT | STATIC;
-    this->what = Class::CLASS;
-    this->type = type;
-    this->extends = BINDER_NATIVE_TYPE;
-    this->interfaces.push_back(interfaceType);
-
-    // descriptor
-    Field* descriptor = new Field(STATIC | FINAL | PRIVATE,
-                            new Variable(STRING_TYPE, "DESCRIPTOR"));
-    descriptor->value = "\"" + interfaceType->QualifiedName() + "\"";
-    this->elements.push_back(descriptor);
-
-    // ctor
-    Method* ctor = new Method;
-        ctor->modifiers = PUBLIC;
-        ctor->comment = "/** Construct the stub at attach it to the "
-                        "interface. */";
-        ctor->name = "Stub";
-        ctor->statements = new StatementBlock;
-    MethodCall* attach = new MethodCall(THIS_VALUE, "attachInterface",
-                            2, THIS_VALUE, new LiteralExpression("DESCRIPTOR"));
-    ctor->statements->Add(attach);
-    this->elements.push_back(ctor);
-
-    // asInterface
-    make_as_interface(interfaceType);
-
-    // asBinder
-    Method* asBinder = new Method;
-        asBinder->modifiers = PUBLIC | OVERRIDE;
-        asBinder->returnType = IBINDER_TYPE;
-        asBinder->name = "asBinder";
-        asBinder->statements = new StatementBlock;
-    asBinder->statements->Add(new ReturnStatement(THIS_VALUE));
-    this->elements.push_back(asBinder);
-
-    // onTransact
-    this->transact_code = new Variable(INT_TYPE, "code");
-    this->transact_data = new Variable(PARCEL_TYPE, "data");
-    this->transact_reply = new Variable(PARCEL_TYPE, "reply");
-    this->transact_flags = new Variable(INT_TYPE, "flags");
-    Method* onTransact = new Method;
-        onTransact->modifiers = PUBLIC | OVERRIDE;
-        onTransact->returnType = BOOLEAN_TYPE;
-        onTransact->name = "onTransact";
-        onTransact->parameters.push_back(this->transact_code);
-        onTransact->parameters.push_back(this->transact_data);
-        onTransact->parameters.push_back(this->transact_reply);
-        onTransact->parameters.push_back(this->transact_flags);
-        onTransact->statements = new StatementBlock;
-        onTransact->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
-    this->elements.push_back(onTransact);
-    this->transact_switch = new SwitchStatement(this->transact_code);
-
-    onTransact->statements->Add(this->transact_switch);
-    MethodCall* superCall = new MethodCall(SUPER_VALUE, "onTransact", 4,
-                                    this->transact_code, this->transact_data,
-                                    this->transact_reply, this->transact_flags);
-    onTransact->statements->Add(new ReturnStatement(superCall));
-}
-
-StubClass::~StubClass()
-{
-}
-
-void
-StubClass::make_as_interface(Type *interfaceType)
-{
-    Variable* obj = new Variable(IBINDER_TYPE, "obj");
-
-    Method* m = new Method;
-        m->comment = "/**\n * Cast an IBinder object into an ";
-        m->comment += interfaceType->QualifiedName();
-        m->comment += " interface,\n";
-        m->comment += " * generating a proxy if needed.\n */";
-        m->modifiers = PUBLIC | STATIC;
-        m->returnType = interfaceType;
-        m->name = "asInterface";
-        m->parameters.push_back(obj);
-        m->statements = new StatementBlock;
-
-    IfStatement* ifstatement = new IfStatement();
-        ifstatement->expression = new Comparison(obj, "==", NULL_VALUE);
-        ifstatement->statements = new StatementBlock;
-        ifstatement->statements->Add(new ReturnStatement(NULL_VALUE));
-    m->statements->Add(ifstatement);
-
-    // IInterface iin = obj.queryLocalInterface(DESCRIPTOR)
-    MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface");
-    queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR"));
-    IInterfaceType* iinType = new IInterfaceType();
-    Variable *iin = new Variable(iinType, "iin");
-    VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, NULL);
-    m->statements->Add(iinVd);
-
-    // Ensure the instance type of the local object is as expected.
-    // One scenario where this is needed is if another package (with a
-    // different class loader) runs in the same process as the service.
-
-    // if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>) iin;
-    Comparison* iinNotNull = new Comparison(iin, "!=", NULL_VALUE);
-    Comparison* instOfCheck = new Comparison(iin, " instanceof ",
-            new LiteralExpression(interfaceType->QualifiedName()));
-    IfStatement* instOfStatement = new IfStatement();
-        instOfStatement->expression = new Comparison(iinNotNull, "&&", instOfCheck);
-        instOfStatement->statements = new StatementBlock;
-        instOfStatement->statements->Add(new ReturnStatement(new Cast(interfaceType, iin)));
-    m->statements->Add(instOfStatement);
-
-    string proxyType = interfaceType->QualifiedName();
-    proxyType += ".Stub.Proxy";
-    NewExpression* ne = new NewExpression(NAMES.Find(proxyType));
-    ne->arguments.push_back(obj);
-    m->statements->Add(new ReturnStatement(ne));
-
-    this->elements.push_back(m);
-}
-
-
-
-// =================================================
-class ProxyClass : public Class
-{
-public:
-    ProxyClass(Type* type, InterfaceType* interfaceType);
-    virtual ~ProxyClass();
-
-    Variable* mRemote;
-    bool mOneWay;
-};
-
-ProxyClass::ProxyClass(Type* type, InterfaceType* interfaceType)
-    :Class()
-{
-    this->modifiers = PRIVATE | STATIC;
-    this->what = Class::CLASS;
-    this->type = type;
-    this->interfaces.push_back(interfaceType);
-
-    mOneWay = interfaceType->OneWay();
-
-    // IBinder mRemote
-    mRemote = new Variable(IBINDER_TYPE, "mRemote");
-    this->elements.push_back(new Field(PRIVATE, mRemote));
-
-    // Proxy()
-    Variable* remote = new Variable(IBINDER_TYPE, "remote");
-    Method* ctor = new Method;
-        ctor->name = "Proxy";
-        ctor->statements = new StatementBlock;
-        ctor->parameters.push_back(remote);
-    ctor->statements->Add(new Assignment(mRemote, remote));
-    this->elements.push_back(ctor);
-
-    // IBinder asBinder()
-    Method* asBinder = new Method;
-        asBinder->modifiers = PUBLIC | OVERRIDE;
-        asBinder->returnType = IBINDER_TYPE;
-        asBinder->name = "asBinder";
-        asBinder->statements = new StatementBlock;
-    asBinder->statements->Add(new ReturnStatement(mRemote));
-    this->elements.push_back(asBinder);
-}
-
-ProxyClass::~ProxyClass()
-{
-}
-
-// =================================================
-static void
-generate_new_array(Type* t, StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
-{
-    Variable* len = new Variable(INT_TYPE, v->name + "_length");
-    addTo->Add(new VariableDeclaration(len, new MethodCall(parcel, "readInt")));
-    IfStatement* lencheck = new IfStatement();
-    lencheck->expression = new Comparison(len, "<", new LiteralExpression("0"));
-    lencheck->statements->Add(new Assignment(v, NULL_VALUE));
-    lencheck->elseif = new IfStatement();
-    lencheck->elseif->statements->Add(new Assignment(v,
-                new NewArrayExpression(t, len)));
-    addTo->Add(lencheck);
-}
-
-static void
-generate_write_to_parcel(Type* t, StatementBlock* addTo, Variable* v,
-                            Variable* parcel, int flags)
-{
-    if (v->dimension == 0) {
-        t->WriteToParcel(addTo, v, parcel, flags);
-    }
-    if (v->dimension == 1) {
-        t->WriteArrayToParcel(addTo, v, parcel, flags);
-    }
-}
-
-static void
-generate_create_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
-                            Variable* parcel, Variable** cl)
-{
-    if (v->dimension == 0) {
-        t->CreateFromParcel(addTo, v, parcel, cl);
-    }
-    if (v->dimension == 1) {
-        t->CreateArrayFromParcel(addTo, v, parcel, cl);
-    }
-}
-
-static void
-generate_read_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
-                            Variable* parcel, Variable** cl)
-{
-    if (v->dimension == 0) {
-        t->ReadFromParcel(addTo, v, parcel, cl);
-    }
-    if (v->dimension == 1) {
-        t->ReadArrayFromParcel(addTo, v, parcel, cl);
-    }
-}
-
-
-static void
-generate_method(const method_type* method, Class* interface,
-                    StubClass* stubClass, ProxyClass* proxyClass, int index)
-{
-    arg_type* arg;
-    int i;
-    bool hasOutParams = false;
-
-    const bool oneway = proxyClass->mOneWay || method->oneway;
-
-    // == the TRANSACT_ constant =============================================
-    string transactCodeName = "TRANSACTION_";
-    transactCodeName += method->name.data;
-
-    char transactCodeValue[60];
-    sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index);
-
-    Field* transactCode = new Field(STATIC | FINAL,
-                            new Variable(INT_TYPE, transactCodeName));
-    transactCode->value = transactCodeValue;
-    stubClass->elements.push_back(transactCode);
-
-    // == the declaration in the interface ===================================
-    Method* decl = new Method;
-        decl->comment = gather_comments(method->comments_token->extra);
-        decl->modifiers = PUBLIC;
-        decl->returnType = NAMES.Search(method->type.type.data);
-        decl->returnTypeDimension = method->type.dimension;
-        decl->name = method->name.data;
-
-    arg = method->args;
-    while (arg != NULL) {
-        decl->parameters.push_back(new Variable(
-                            NAMES.Search(arg->type.type.data), arg->name.data,
-                            arg->type.dimension));
-        arg = arg->next;
-    }
-
-    decl->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
-
-    interface->elements.push_back(decl);
-
-    // == the stub method ====================================================
-
-    Case* c = new Case(transactCodeName);
-
-    MethodCall* realCall = new MethodCall(THIS_VALUE, method->name.data);
-
-    // interface token validation is the very first thing we do
-    c->statements->Add(new MethodCall(stubClass->transact_data,
-            "enforceInterface", 1, new LiteralExpression("DESCRIPTOR")));
-
-    // args
-    Variable* cl = NULL;
-    VariableFactory stubArgs("_arg");
-    arg = method->args;
-    while (arg != NULL) {
-        Type* t = NAMES.Search(arg->type.type.data);
-        Variable* v = stubArgs.Get(t);
-        v->dimension = arg->type.dimension;
-
-        c->statements->Add(new VariableDeclaration(v));
-
-        if (convert_direction(arg->direction.data) & IN_PARAMETER) {
-            generate_create_from_parcel(t, c->statements, v,
-                    stubClass->transact_data, &cl);
-        } else {
-            if (arg->type.dimension == 0) {
-                c->statements->Add(new Assignment(v, new NewExpression(v->type)));
-            }
-            else if (arg->type.dimension == 1) {
-                generate_new_array(v->type, c->statements, v,
-                        stubClass->transact_data);
-            }
-            else {
-                fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__,
-                        __LINE__);
-            }
-        }
-
-        realCall->arguments.push_back(v);
-
-        arg = arg->next;
-    }
-
-    // the real call
-    Variable* _result = NULL;
-    if (0 == strcmp(method->type.type.data, "void")) {
-        c->statements->Add(realCall);
-
-        if (!oneway) {
-            // report that there were no exceptions
-            MethodCall* ex = new MethodCall(stubClass->transact_reply,
-                    "writeNoException", 0);
-            c->statements->Add(ex);
-        }
-    } else {
-        _result = new Variable(decl->returnType, "_result",
-                                decl->returnTypeDimension);
-        c->statements->Add(new VariableDeclaration(_result, realCall));
-
-        if (!oneway) {
-            // report that there were no exceptions
-            MethodCall* ex = new MethodCall(stubClass->transact_reply,
-                    "writeNoException", 0);
-            c->statements->Add(ex);
-        }
-
-        // marshall the return value
-        generate_write_to_parcel(decl->returnType, c->statements, _result,
-                                    stubClass->transact_reply,
-                                    Type::PARCELABLE_WRITE_RETURN_VALUE);
-    }
-
-    // out parameters
-    i = 0;
-    arg = method->args;
-    while (arg != NULL) {
-        Type* t = NAMES.Search(arg->type.type.data);
-        Variable* v = stubArgs.Get(i++);
-
-        if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
-            generate_write_to_parcel(t, c->statements, v,
-                                stubClass->transact_reply,
-                                Type::PARCELABLE_WRITE_RETURN_VALUE);
-            hasOutParams = true;
-        }
-
-        arg = arg->next;
-    }
-
-    // return true
-    c->statements->Add(new ReturnStatement(TRUE_VALUE));
-    stubClass->transact_switch->cases.push_back(c);
-
-    // == the proxy method ===================================================
-    Method* proxy = new Method;
-        proxy->comment = gather_comments(method->comments_token->extra);
-        proxy->modifiers = PUBLIC | OVERRIDE;
-        proxy->returnType = NAMES.Search(method->type.type.data);
-        proxy->returnTypeDimension = method->type.dimension;
-        proxy->name = method->name.data;
-        proxy->statements = new StatementBlock;
-        arg = method->args;
-        while (arg != NULL) {
-            proxy->parameters.push_back(new Variable(
-                            NAMES.Search(arg->type.type.data), arg->name.data,
-                            arg->type.dimension));
-            arg = arg->next;
-        }
-        proxy->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
-    proxyClass->elements.push_back(proxy);
-
-    // the parcels
-    Variable* _data = new Variable(PARCEL_TYPE, "_data");
-    proxy->statements->Add(new VariableDeclaration(_data,
-                                new MethodCall(PARCEL_TYPE, "obtain")));
-    Variable* _reply = NULL;
-    if (!oneway) {
-        _reply = new Variable(PARCEL_TYPE, "_reply");
-        proxy->statements->Add(new VariableDeclaration(_reply,
-                                    new MethodCall(PARCEL_TYPE, "obtain")));
-    }
-
-    // the return value
-    _result = NULL;
-    if (0 != strcmp(method->type.type.data, "void")) {
-        _result = new Variable(proxy->returnType, "_result",
-                method->type.dimension);
-        proxy->statements->Add(new VariableDeclaration(_result));
-    }
-
-    // try and finally
-    TryStatement* tryStatement = new TryStatement();
-    proxy->statements->Add(tryStatement);
-    FinallyStatement* finallyStatement = new FinallyStatement();
-    proxy->statements->Add(finallyStatement);
-
-    // the interface identifier token: the DESCRIPTOR constant, marshalled as a string
-    tryStatement->statements->Add(new MethodCall(_data, "writeInterfaceToken",
-            1, new LiteralExpression("DESCRIPTOR")));
-
-    // the parameters
-    arg = method->args;
-    while (arg != NULL) {
-        Type* t = NAMES.Search(arg->type.type.data);
-        Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
-        int dir = convert_direction(arg->direction.data);
-        if (dir == OUT_PARAMETER && arg->type.dimension != 0) {
-            IfStatement* checklen = new IfStatement();
-            checklen->expression = new Comparison(v, "==", NULL_VALUE);
-            checklen->statements->Add(new MethodCall(_data, "writeInt", 1,
-                        new LiteralExpression("-1")));
-            checklen->elseif = new IfStatement();
-            checklen->elseif->statements->Add(new MethodCall(_data, "writeInt",
-                        1, new FieldVariable(v, "length")));
-            tryStatement->statements->Add(checklen);
-        }
-        else if (dir & IN_PARAMETER) {
-            generate_write_to_parcel(t, tryStatement->statements, v, _data, 0);
-        }
-        arg = arg->next;
-    }
-
-    // the transact call
-    MethodCall* call = new MethodCall(proxyClass->mRemote, "transact", 4,
-                            new LiteralExpression("Stub." + transactCodeName),
-                            _data, _reply ? _reply : NULL_VALUE,
-                            new LiteralExpression(
-                                oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0"));
-    tryStatement->statements->Add(call);
-
-    // throw back exceptions.
-    if (_reply) {
-        MethodCall* ex = new MethodCall(_reply, "readException", 0);
-        tryStatement->statements->Add(ex);
-    }
-
-    // returning and cleanup
-    if (_reply != NULL) {
-        if (_result != NULL) {
-            generate_create_from_parcel(proxy->returnType,
-                    tryStatement->statements, _result, _reply, &cl);
-        }
-
-        // the out/inout parameters
-        arg = method->args;
-        while (arg != NULL) {
-            Type* t = NAMES.Search(arg->type.type.data);
-            Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
-            if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
-                generate_read_from_parcel(t, tryStatement->statements,
-                                            v, _reply, &cl);
-            }
-            arg = arg->next;
-        }
-
-        finallyStatement->statements->Add(new MethodCall(_reply, "recycle"));
-    }
-    finallyStatement->statements->Add(new MethodCall(_data, "recycle"));
-
-    if (_result != NULL) {
-        proxy->statements->Add(new ReturnStatement(_result));
-    }
-}
-
-static void
-generate_interface_descriptors(StubClass* stub, ProxyClass* proxy)
-{
-    // the interface descriptor transaction handler
-    Case* c = new Case("INTERFACE_TRANSACTION");
-    c->statements->Add(new MethodCall(stub->transact_reply, "writeString",
-            1, new LiteralExpression("DESCRIPTOR")));
-    c->statements->Add(new ReturnStatement(TRUE_VALUE));
-    stub->transact_switch->cases.push_back(c);
-
-    // and the proxy-side method returning the descriptor directly
-    Method* getDesc = new Method;
-    getDesc->modifiers = PUBLIC;
-    getDesc->returnType = STRING_TYPE;
-    getDesc->returnTypeDimension = 0;
-    getDesc->name = "getInterfaceDescriptor";
-    getDesc->statements = new StatementBlock;
-    getDesc->statements->Add(new ReturnStatement(new LiteralExpression("DESCRIPTOR")));
-    proxy->elements.push_back(getDesc);
-}
-
-Class*
-generate_binder_interface_class(const interface_type* iface)
-{
-    InterfaceType* interfaceType = static_cast<InterfaceType*>(
-        NAMES.Find(iface->package, iface->name.data));
-
-    // the interface class
-    Class* interface = new Class;
-        interface->comment = gather_comments(iface->comments_token->extra);
-        interface->modifiers = PUBLIC;
-        interface->what = Class::INTERFACE;
-        interface->type = interfaceType;
-        interface->interfaces.push_back(IINTERFACE_TYPE);
-
-    // the stub inner class
-    StubClass* stub = new StubClass(
-        NAMES.Find(iface->package, append(iface->name.data, ".Stub").c_str()),
-        interfaceType);
-    interface->elements.push_back(stub);
-
-    // the proxy inner class
-    ProxyClass* proxy = new ProxyClass(
-        NAMES.Find(iface->package,
-                         append(iface->name.data, ".Stub.Proxy").c_str()),
-        interfaceType);
-    stub->elements.push_back(proxy);
-
-    // stub and proxy support for getInterfaceDescriptor()
-    generate_interface_descriptors(stub, proxy);
-
-    // all the declared methods of the interface
-    int index = 0;
-    interface_item_type* item = iface->interface_items;
-    while (item != NULL) {
-        if (item->item_type == METHOD_TYPE) {
-            method_type * method_item = (method_type*) item;
-            generate_method(method_item, interface, stub, proxy, method_item->assigned_id);
-        }
-        item = item->next;
-        index++;
-    }
-
-    return interface;
-}
-
diff --git a/tools/aidl/generate_java_rpc.cpp b/tools/aidl/generate_java_rpc.cpp
deleted file mode 100644
index 5e4dacc..0000000
--- a/tools/aidl/generate_java_rpc.cpp
+++ /dev/null
@@ -1,1001 +0,0 @@
-#include "generate_java.h"
-#include "Type.h"
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-Type* SERVICE_CONTEXT_TYPE = new Type("android.content",
-        "Context", Type::BUILT_IN, false, false, false);
-Type* PRESENTER_BASE_TYPE = new Type("android.support.place.connector",
-        "EventListener", Type::BUILT_IN, false, false, false);
-Type* PRESENTER_LISTENER_BASE_TYPE = new Type("android.support.place.connector",
-        "EventListener.Listener", Type::BUILT_IN, false, false, false);
-Type* RPC_BROKER_TYPE = new Type("android.support.place.connector", "Broker",
-        Type::BUILT_IN, false, false, false);
-Type* RPC_CONTAINER_TYPE = new Type("com.android.athome.connector", "ConnectorContainer",
-        Type::BUILT_IN, false, false, false);
-Type* PLACE_INFO_TYPE = new Type("android.support.place.connector", "PlaceInfo",
-        Type::BUILT_IN, false, false, false);
-// TODO: Just use Endpoint, so this works for all endpoints.
-Type* RPC_CONNECTOR_TYPE = new Type("android.support.place.connector", "Connector",
-        Type::BUILT_IN, false, false, false);
-Type* RPC_ENDPOINT_INFO_TYPE = new UserDataType("android.support.place.rpc",
-        "EndpointInfo", true, __FILE__, __LINE__);
-Type* RPC_RESULT_HANDLER_TYPE = new UserDataType("android.support.place.rpc", "RpcResultHandler",
-        true, __FILE__, __LINE__);
-Type* RPC_ERROR_LISTENER_TYPE = new Type("android.support.place.rpc", "RpcErrorHandler",
-        Type::BUILT_IN, false, false, false);
-Type* RPC_CONTEXT_TYPE = new UserDataType("android.support.place.rpc", "RpcContext", true,
-        __FILE__, __LINE__);
-
-static void generate_create_from_data(Type* t, StatementBlock* addTo, const string& key,
-        Variable* v, Variable* data, Variable** cl);
-static void generate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* from);
-static void generate_write_to_data(Type* t, StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data);
-
-static string
-format_int(int n)
-{
-    char str[20];
-    sprintf(str, "%d", n);
-    return string(str);
-}
-
-static string
-class_name_leaf(const string& str)
-{
-    string::size_type pos = str.rfind('.');
-    if (pos == string::npos) {
-        return str;
-    } else {
-        return string(str, pos+1);
-    }
-}
-
-static string
-results_class_name(const string& n)
-{
-    string str = n;
-    str[0] = toupper(str[0]);
-    str.insert(0, "On");
-    return str;
-}
-
-static string
-results_method_name(const string& n)
-{
-    string str = n;
-    str[0] = toupper(str[0]);
-    str.insert(0, "on");
-    return str;
-}
-
-static string
-push_method_name(const string& n)
-{
-    string str = n;
-    str[0] = toupper(str[0]);
-    str.insert(0, "push");
-    return str;
-}
-
-// =================================================
-class DispatcherClass : public Class
-{
-public:
-    DispatcherClass(const interface_type* iface, Expression* target);
-    virtual ~DispatcherClass();
-
-    void AddMethod(const method_type* method);
-    void DoneWithMethods();
-
-    Method* processMethod;
-    Variable* actionParam;
-    Variable* requestParam;
-    Variable* rpcContextParam;
-    Variable* errorParam;
-    Variable* requestData;
-    Variable* resultData;
-    IfStatement* dispatchIfStatement;
-    Expression* targetExpression;
-
-private:
-    void generate_process();
-};
-
-DispatcherClass::DispatcherClass(const interface_type* iface, Expression* target)
-    :Class(),
-     dispatchIfStatement(NULL),
-     targetExpression(target)
-{
-    generate_process();
-}
-
-DispatcherClass::~DispatcherClass()
-{
-}
-
-void
-DispatcherClass::generate_process()
-{
-    // byte[] process(String action, byte[] params, RpcContext context, RpcError status)
-    this->processMethod = new Method;
-        this->processMethod->modifiers = PUBLIC;
-        this->processMethod->returnType = BYTE_TYPE;
-        this->processMethod->returnTypeDimension = 1;
-        this->processMethod->name = "process";
-        this->processMethod->statements = new StatementBlock;
-
-    this->actionParam = new Variable(STRING_TYPE, "action");
-    this->processMethod->parameters.push_back(this->actionParam);
-
-    this->requestParam = new Variable(BYTE_TYPE, "requestParam", 1);
-    this->processMethod->parameters.push_back(this->requestParam);
-
-    this->rpcContextParam = new Variable(RPC_CONTEXT_TYPE, "context", 0);
-    this->processMethod->parameters.push_back(this->rpcContextParam);    
-
-    this->errorParam = new Variable(RPC_ERROR_TYPE, "errorParam", 0);
-    this->processMethod->parameters.push_back(this->errorParam);
-
-    this->requestData = new Variable(RPC_DATA_TYPE, "request");
-    this->processMethod->statements->Add(new VariableDeclaration(requestData,
-                new NewExpression(RPC_DATA_TYPE, 1, this->requestParam)));
-
-    this->resultData = new Variable(RPC_DATA_TYPE, "resultData");
-    this->processMethod->statements->Add(new VariableDeclaration(this->resultData,
-                NULL_VALUE));
-}
-
-void
-DispatcherClass::AddMethod(const method_type* method)
-{
-    arg_type* arg;
-
-    // The if/switch statement
-    IfStatement* ifs = new IfStatement();
-        ifs->expression = new MethodCall(new StringLiteralExpression(method->name.data), "equals",
-                1, this->actionParam);
-    StatementBlock* block = ifs->statements = new StatementBlock;
-    if (this->dispatchIfStatement == NULL) {
-        this->dispatchIfStatement = ifs;
-        this->processMethod->statements->Add(dispatchIfStatement);
-    } else {
-        this->dispatchIfStatement->elseif = ifs;
-        this->dispatchIfStatement = ifs;
-    }
-    
-    // The call to decl (from above)
-    MethodCall* realCall = new MethodCall(this->targetExpression, method->name.data);
-
-    // args
-    Variable* classLoader = NULL;
-    VariableFactory stubArgs("_arg");
-    arg = method->args;
-    while (arg != NULL) {
-        Type* t = NAMES.Search(arg->type.type.data);
-        Variable* v = stubArgs.Get(t);
-        v->dimension = arg->type.dimension;
-
-        // Unmarshall the parameter
-        block->Add(new VariableDeclaration(v));
-        if (convert_direction(arg->direction.data) & IN_PARAMETER) {
-            generate_create_from_data(t, block, arg->name.data, v,
-                    this->requestData, &classLoader);
-        } else {
-            if (arg->type.dimension == 0) {
-                block->Add(new Assignment(v, new NewExpression(v->type)));
-            }
-            else if (arg->type.dimension == 1) {
-                generate_new_array(v->type, block, v, this->requestData);
-            }
-            else {
-                fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__,
-                        __LINE__);
-            }
-        }
-
-        // Add that parameter to the method call
-        realCall->arguments.push_back(v);
-
-        arg = arg->next;
-    }
-
-    // Add a final parameter: RpcContext. Contains data about
-    // incoming request (e.g., certificate)
-    realCall->arguments.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
-
-    Type* returnType = NAMES.Search(method->type.type.data);
-    if (returnType == EVENT_FAKE_TYPE) {
-        returnType = VOID_TYPE;
-    }
-    
-    // the real call
-    bool first = true;
-    Variable* _result = NULL;
-    if (returnType == VOID_TYPE) {
-        block->Add(realCall);
-    } else {
-        _result = new Variable(returnType, "_result",
-                                method->type.dimension);
-        block->Add(new VariableDeclaration(_result, realCall));
-
-        // need the result RpcData
-        if (first) {
-            block->Add(new Assignment(this->resultData,
-                        new NewExpression(RPC_DATA_TYPE)));
-            first = false;
-        }
-
-        // marshall the return value
-        generate_write_to_data(returnType, block,
-                new StringLiteralExpression("_result"), _result, this->resultData);
-    }
-
-    // out parameters
-    int i = 0;
-    arg = method->args;
-    while (arg != NULL) {
-        Type* t = NAMES.Search(arg->type.type.data);
-        Variable* v = stubArgs.Get(i++);
-
-        if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
-            // need the result RpcData
-            if (first) {
-                block->Add(new Assignment(this->resultData, new NewExpression(RPC_DATA_TYPE)));
-                first = false;
-            }
-
-            generate_write_to_data(t, block, new StringLiteralExpression(arg->name.data),
-                    v, this->resultData);
-        }
-
-        arg = arg->next;
-    }
-}
-
-void
-DispatcherClass::DoneWithMethods()
-{
-    if (this->dispatchIfStatement == NULL) {
-        return;
-    }
-
-    this->elements.push_back(this->processMethod);
-
-    IfStatement* fallthrough = new IfStatement();
-        fallthrough->statements = new StatementBlock;
-        fallthrough->statements->Add(new ReturnStatement(
-                    new MethodCall(SUPER_VALUE, "process", 4, 
-                    this->actionParam, this->requestParam, 
-                    this->rpcContextParam,
-                    this->errorParam)));
-    this->dispatchIfStatement->elseif = fallthrough;
-    IfStatement* s = new IfStatement;
-        s->statements = new StatementBlock;
-    this->processMethod->statements->Add(s);
-    s->expression = new Comparison(this->resultData, "!=", NULL_VALUE);
-    s->statements->Add(new ReturnStatement(new MethodCall(this->resultData, "serialize")));
-    s->elseif = new IfStatement;
-    s = s->elseif;
-    s->statements->Add(new ReturnStatement(NULL_VALUE));
-}
-
-// =================================================
-class RpcProxyClass : public Class
-{
-public:
-    RpcProxyClass(const interface_type* iface, InterfaceType* interfaceType);
-    virtual ~RpcProxyClass();
-
-    Variable* endpoint;
-    Variable* broker;
-
-private:
-    void generate_ctor();
-    void generate_get_endpoint_info();
-};
-
-RpcProxyClass::RpcProxyClass(const interface_type* iface, InterfaceType* interfaceType)
-    :Class()
-{
-    this->comment = gather_comments(iface->comments_token->extra);
-    this->modifiers = PUBLIC;
-    this->what = Class::CLASS;
-    this->type = interfaceType;
-
-    // broker
-    this->broker = new Variable(RPC_BROKER_TYPE, "_broker");
-    this->elements.push_back(new Field(PRIVATE, this->broker));
-    // endpoint
-    this->endpoint = new Variable(RPC_ENDPOINT_INFO_TYPE, "_endpoint");
-    this->elements.push_back(new Field(PRIVATE, this->endpoint));
-
-    // methods
-    generate_ctor();
-    generate_get_endpoint_info();
-}
-
-RpcProxyClass::~RpcProxyClass()
-{
-}
-
-void
-RpcProxyClass::generate_ctor()
-{
-    Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
-    Variable* endpoint = new Variable(RPC_ENDPOINT_INFO_TYPE, "endpoint");
-    Method* ctor = new Method;
-        ctor->modifiers = PUBLIC;
-        ctor->name = class_name_leaf(this->type->Name());
-        ctor->statements = new StatementBlock;
-        ctor->parameters.push_back(broker);
-        ctor->parameters.push_back(endpoint);
-    this->elements.push_back(ctor);
-
-    ctor->statements->Add(new Assignment(this->broker, broker));
-    ctor->statements->Add(new Assignment(this->endpoint, endpoint));
-}
-
-void
-RpcProxyClass::generate_get_endpoint_info()
-{
-    Method* get = new Method;
-    get->modifiers = PUBLIC;
-    get->returnType = RPC_ENDPOINT_INFO_TYPE;
-    get->name = "getEndpointInfo";
-    get->statements = new StatementBlock;
-    this->elements.push_back(get);
-
-    get->statements->Add(new ReturnStatement(this->endpoint));
-}
-
-// =================================================
-class EventListenerClass : public DispatcherClass
-{
-public:
-    EventListenerClass(const interface_type* iface, Type* listenerType);
-    virtual ~EventListenerClass();
-
-    Variable* _listener;
-
-private:
-    void generate_ctor();
-};
-
-Expression*
-generate_get_listener_expression(Type* cast)
-{
-    return new Cast(cast, new MethodCall(THIS_VALUE, "getView"));
-}
-
-EventListenerClass::EventListenerClass(const interface_type* iface, Type* listenerType)
-    :DispatcherClass(iface, new FieldVariable(THIS_VALUE, "_listener"))
-{
-    this->modifiers = PRIVATE;
-    this->what = Class::CLASS;
-    this->type = new Type(iface->package ? iface->package : "",
-                        append(iface->name.data, ".Presenter"),
-                        Type::GENERATED, false, false, false);
-    this->extends = PRESENTER_BASE_TYPE;
-
-    this->_listener = new Variable(listenerType, "_listener");
-    this->elements.push_back(new Field(PRIVATE, this->_listener));
-
-    // methods
-    generate_ctor();
-}
-
-EventListenerClass::~EventListenerClass()
-{
-}
-
-void
-EventListenerClass::generate_ctor()
-{
-    Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
-    Variable* listener = new Variable(this->_listener->type, "listener");
-    Method* ctor = new Method;
-        ctor->modifiers = PUBLIC;
-        ctor->name = class_name_leaf(this->type->Name());
-        ctor->statements = new StatementBlock;
-        ctor->parameters.push_back(broker);
-        ctor->parameters.push_back(listener);
-    this->elements.push_back(ctor);
-
-    ctor->statements->Add(new MethodCall("super", 2, broker, listener));
-    ctor->statements->Add(new Assignment(this->_listener, listener));
-}
-
-// =================================================
-class ListenerClass : public Class
-{
-public:
-    ListenerClass(const interface_type* iface);
-    virtual ~ListenerClass();
-
-    bool needed;
-
-private:
-    void generate_ctor();
-};
-
-ListenerClass::ListenerClass(const interface_type* iface)
-    :Class(),
-     needed(false)
-{
-    this->comment = "/** Extend this to listen to the events from this class. */";
-    this->modifiers = STATIC | PUBLIC ;
-    this->what = Class::CLASS;
-    this->type = new Type(iface->package ? iface->package : "",
-                        append(iface->name.data, ".Listener"),
-                        Type::GENERATED, false, false, false);
-    this->extends = PRESENTER_LISTENER_BASE_TYPE;
-}
-
-ListenerClass::~ListenerClass()
-{
-}
-
-// =================================================
-class EndpointBaseClass : public DispatcherClass
-{
-public:
-    EndpointBaseClass(const interface_type* iface);
-    virtual ~EndpointBaseClass();
-
-    bool needed;
-
-private:
-    void generate_ctor();
-};
-
-EndpointBaseClass::EndpointBaseClass(const interface_type* iface)
-    :DispatcherClass(iface, THIS_VALUE),
-     needed(false)
-{
-    this->comment = "/** Extend this to implement a link service. */";
-    this->modifiers = STATIC | PUBLIC | ABSTRACT;
-    this->what = Class::CLASS;
-    this->type = new Type(iface->package ? iface->package : "",
-                        append(iface->name.data, ".EndpointBase"),
-                        Type::GENERATED, false, false, false);
-    this->extends = RPC_CONNECTOR_TYPE;
-
-    // methods
-    generate_ctor();
-}
-
-EndpointBaseClass::~EndpointBaseClass()
-{
-}
-
-void
-EndpointBaseClass::generate_ctor()
-{
-    Variable* container = new Variable(RPC_CONTAINER_TYPE, "container");
-    Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
-	Variable* place = new Variable(PLACE_INFO_TYPE, "placeInfo");
-    Method* ctor = new Method;
-        ctor->modifiers = PUBLIC;
-        ctor->name = class_name_leaf(this->type->Name());
-        ctor->statements = new StatementBlock;
-        ctor->parameters.push_back(container);
-        ctor->parameters.push_back(broker);
-        ctor->parameters.push_back(place);
-    this->elements.push_back(ctor);
-
-    ctor->statements->Add(new MethodCall("super", 3, container, broker, place));
-}
-
-// =================================================
-class ResultDispatcherClass : public Class
-{
-public:
-    ResultDispatcherClass();
-    virtual ~ResultDispatcherClass();
-
-    void AddMethod(int index, const string& name, Method** method, Variable** param);
-
-    bool needed;
-    Variable* methodId;
-    Variable* callback;
-    Method* onResultMethod;
-    Variable* resultParam;
-    SwitchStatement* methodSwitch;
-
-private:
-    void generate_ctor();
-    void generate_onResult();
-};
-
-ResultDispatcherClass::ResultDispatcherClass()
-    :Class(),
-     needed(false)
-{
-    this->modifiers = PRIVATE | FINAL;
-    this->what = Class::CLASS;
-    this->type = new Type("_ResultDispatcher", Type::GENERATED, false, false, false);
-    this->interfaces.push_back(RPC_RESULT_HANDLER_TYPE);
-
-    // methodId
-    this->methodId = new Variable(INT_TYPE, "methodId");
-    this->elements.push_back(new Field(PRIVATE, this->methodId));
-    this->callback = new Variable(OBJECT_TYPE, "callback");
-    this->elements.push_back(new Field(PRIVATE, this->callback));
-
-    // methods
-    generate_ctor();
-    generate_onResult();
-}
-
-ResultDispatcherClass::~ResultDispatcherClass()
-{
-}
-
-void
-ResultDispatcherClass::generate_ctor()
-{
-    Variable* methodIdParam = new Variable(INT_TYPE, "methId");
-    Variable* callbackParam = new Variable(OBJECT_TYPE, "cbObj");
-    Method* ctor = new Method;
-        ctor->modifiers = PUBLIC;
-        ctor->name = class_name_leaf(this->type->Name());
-        ctor->statements = new StatementBlock;
-        ctor->parameters.push_back(methodIdParam);
-        ctor->parameters.push_back(callbackParam);
-    this->elements.push_back(ctor);
-
-    ctor->statements->Add(new Assignment(this->methodId, methodIdParam));
-    ctor->statements->Add(new Assignment(this->callback, callbackParam));
-}
-
-void
-ResultDispatcherClass::generate_onResult()
-{
-    this->onResultMethod = new Method;
-        this->onResultMethod->modifiers = PUBLIC;
-        this->onResultMethod->returnType = VOID_TYPE;
-        this->onResultMethod->returnTypeDimension = 0;
-        this->onResultMethod->name = "onResult";
-        this->onResultMethod->statements = new StatementBlock;
-    this->elements.push_back(this->onResultMethod);
-
-    this->resultParam = new Variable(BYTE_TYPE, "result", 1);
-    this->onResultMethod->parameters.push_back(this->resultParam);
-
-    this->methodSwitch = new SwitchStatement(this->methodId);
-    this->onResultMethod->statements->Add(this->methodSwitch);
-}
-
-void
-ResultDispatcherClass::AddMethod(int index, const string& name, Method** method, Variable** param)
-{
-    Method* m = new Method;
-        m->modifiers = PUBLIC;
-        m->returnType = VOID_TYPE;
-        m->returnTypeDimension = 0;
-        m->name = name;
-        m->statements = new StatementBlock;
-    *param = new Variable(BYTE_TYPE, "result", 1);
-    m->parameters.push_back(*param);
-    this->elements.push_back(m);
-    *method = m;
-
-    Case* c = new Case(format_int(index));
-    c->statements->Add(new MethodCall(new LiteralExpression("this"), name, 1, this->resultParam));
-    c->statements->Add(new Break());
-
-    this->methodSwitch->cases.push_back(c);
-}
-
-// =================================================
-static void
-generate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* from)
-{
-    fprintf(stderr, "aidl: implement generate_new_array %s:%d\n", __FILE__, __LINE__);
-    exit(1);
-}
-
-static void
-generate_create_from_data(Type* t, StatementBlock* addTo, const string& key, Variable* v,
-                            Variable* data, Variable** cl)
-{
-    Expression* k = new StringLiteralExpression(key);
-    if (v->dimension == 0) {
-        t->CreateFromRpcData(addTo, k, v, data, cl);
-    }
-    if (v->dimension == 1) {
-        //t->ReadArrayFromRpcData(addTo, v, data, cl);
-        fprintf(stderr, "aidl: implement generate_create_from_data for arrays%s:%d\n",
-                __FILE__, __LINE__);
-    }
-}
-
-static void
-generate_write_to_data(Type* t, StatementBlock* addTo, Expression* k, Variable* v, Variable* data)
-{
-    if (v->dimension == 0) {
-        t->WriteToRpcData(addTo, k, v, data, 0);
-    }
-    if (v->dimension == 1) {
-        //t->WriteArrayToParcel(addTo, v, data);
-        fprintf(stderr, "aidl: implement generate_write_to_data for arrays%s:%d\n",
-                __FILE__, __LINE__);
-    }
-}
-
-// =================================================
-static Type*
-generate_results_method(const method_type* method, RpcProxyClass* proxyClass)
-{
-    arg_type* arg;
-
-    string resultsMethodName = results_method_name(method->name.data);
-    Type* resultsInterfaceType = new Type(results_class_name(method->name.data),
-            Type::GENERATED, false, false, false);
-
-    if (!method->oneway) {
-        Class* resultsClass = new Class;
-            resultsClass->modifiers = STATIC | PUBLIC;
-            resultsClass->what = Class::INTERFACE;
-            resultsClass->type = resultsInterfaceType;
-
-        Method* resultMethod = new Method;
-            resultMethod->comment = gather_comments(method->comments_token->extra);
-            resultMethod->modifiers = PUBLIC;
-            resultMethod->returnType = VOID_TYPE;
-            resultMethod->returnTypeDimension = 0;
-            resultMethod->name = resultsMethodName;
-        if (0 != strcmp("void", method->type.type.data)) {
-            resultMethod->parameters.push_back(new Variable(NAMES.Search(method->type.type.data),
-                        "_result", method->type.dimension));
-        }
-        arg = method->args;
-        while (arg != NULL) {
-            if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
-                resultMethod->parameters.push_back(new Variable(
-                                    NAMES.Search(arg->type.type.data), arg->name.data,
-                                    arg->type.dimension));
-            }
-            arg = arg->next;
-        }
-        resultsClass->elements.push_back(resultMethod);
-
-        if (resultMethod->parameters.size() > 0) {
-            proxyClass->elements.push_back(resultsClass);
-            return resultsInterfaceType;
-        } 
-    }
-    //delete resultsInterfaceType;
-    return NULL;
-}
-
-static void
-generate_proxy_method(const method_type* method, RpcProxyClass* proxyClass,
-        ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index)
-{
-    arg_type* arg;
-    Method* proxyMethod = new Method;
-        proxyMethod->comment = gather_comments(method->comments_token->extra);
-        proxyMethod->modifiers = PUBLIC;
-        proxyMethod->returnType = VOID_TYPE;
-        proxyMethod->returnTypeDimension = 0;
-        proxyMethod->name = method->name.data;
-        proxyMethod->statements = new StatementBlock;
-    proxyClass->elements.push_back(proxyMethod);
-
-    // The local variables
-    Variable* _data = new Variable(RPC_DATA_TYPE, "_data");
-    proxyMethod->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE)));
-
-    // Add the arguments
-    arg = method->args;
-    while (arg != NULL) {
-        if (convert_direction(arg->direction.data) & IN_PARAMETER) {
-            // Function signature
-            Type* t = NAMES.Search(arg->type.type.data);
-            Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
-            proxyMethod->parameters.push_back(v);
-
-            // Input parameter marshalling
-            generate_write_to_data(t, proxyMethod->statements,
-                    new StringLiteralExpression(arg->name.data), v, _data);
-        }
-        arg = arg->next;
-    }
-
-    // If there is a results interface for this class
-    Expression* resultParameter;
-    if (resultsInterfaceType != NULL) {
-        // Result interface parameter
-        Variable* resultListener = new Variable(resultsInterfaceType, "_result");
-        proxyMethod->parameters.push_back(resultListener);
-
-        // Add the results dispatcher callback
-        resultsDispatcherClass->needed = true;
-        resultParameter = new NewExpression(resultsDispatcherClass->type, 2,
-                new LiteralExpression(format_int(index)), resultListener);
-    } else {
-        resultParameter = NULL_VALUE;
-    }
-
-    // All proxy methods take an error parameter
-    Variable* errorListener = new Variable(RPC_ERROR_LISTENER_TYPE, "_errors");
-    proxyMethod->parameters.push_back(errorListener);
-
-    // Call the broker
-    proxyMethod->statements->Add(new MethodCall(new FieldVariable(THIS_VALUE, "_broker"),
-                "sendRpc", 5,
-                proxyClass->endpoint,
-                new StringLiteralExpression(method->name.data),
-                new MethodCall(_data, "serialize"),
-                resultParameter,
-                errorListener));
-}
-
-static void
-generate_result_dispatcher_method(const method_type* method,
-        ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index)
-{
-    arg_type* arg;
-    Method* dispatchMethod;
-    Variable* dispatchParam;
-    resultsDispatcherClass->AddMethod(index, method->name.data, &dispatchMethod, &dispatchParam);
-
-    Variable* classLoader = NULL;
-    Variable* resultData = new Variable(RPC_DATA_TYPE, "resultData");
-    dispatchMethod->statements->Add(new VariableDeclaration(resultData,
-                new NewExpression(RPC_DATA_TYPE, 1, dispatchParam)));
-
-    // The callback method itself
-    MethodCall* realCall = new MethodCall(
-            new Cast(resultsInterfaceType, new FieldVariable(THIS_VALUE, "callback")),
-            results_method_name(method->name.data));
-
-    // The return value
-    {
-        Type* t = NAMES.Search(method->type.type.data);
-        if (t != VOID_TYPE) {
-            Variable* rv = new Variable(t, "rv");
-            dispatchMethod->statements->Add(new VariableDeclaration(rv));
-            generate_create_from_data(t, dispatchMethod->statements, "_result", rv,
-                    resultData, &classLoader);
-            realCall->arguments.push_back(rv);
-        }
-    }
-
-    VariableFactory stubArgs("arg");
-    arg = method->args;
-    while (arg != NULL) {
-        if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
-            // Unmarshall the results
-            Type* t = NAMES.Search(arg->type.type.data);
-            Variable* v = stubArgs.Get(t);
-            dispatchMethod->statements->Add(new VariableDeclaration(v));
-
-            generate_create_from_data(t, dispatchMethod->statements, arg->name.data, v,
-                    resultData, &classLoader);
-
-            // Add the argument to the callback
-            realCall->arguments.push_back(v);
-        }
-        arg = arg->next;
-    }
-
-    // Call the callback method
-    IfStatement* ifst = new IfStatement;
-        ifst->expression = new Comparison(new FieldVariable(THIS_VALUE, "callback"), "!=", NULL_VALUE);
-    dispatchMethod->statements->Add(ifst);
-    ifst->statements->Add(realCall);
-}
-
-static void
-generate_regular_method(const method_type* method, RpcProxyClass* proxyClass,
-        EndpointBaseClass* serviceBaseClass, ResultDispatcherClass* resultsDispatcherClass,
-        int index)
-{
-    arg_type* arg;
-
-    // == the callback interface for results ================================
-    // the service base class
-    Type* resultsInterfaceType = generate_results_method(method, proxyClass);
-    
-    // == the method in the proxy class =====================================
-    generate_proxy_method(method, proxyClass, resultsDispatcherClass, resultsInterfaceType, index);
-
-    // == the method in the result dispatcher class =========================
-    if (resultsInterfaceType != NULL) {
-        generate_result_dispatcher_method(method, resultsDispatcherClass, resultsInterfaceType,
-                index);
-    }
-
-    // == The abstract method that the service developers implement ==========
-    Method* decl = new Method;
-        decl->comment = gather_comments(method->comments_token->extra);
-        decl->modifiers = PUBLIC | ABSTRACT;
-        decl->returnType = NAMES.Search(method->type.type.data);
-        decl->returnTypeDimension = method->type.dimension;
-        decl->name = method->name.data;
-    arg = method->args;
-    while (arg != NULL) {
-        decl->parameters.push_back(new Variable(
-                            NAMES.Search(arg->type.type.data), arg->name.data,
-                            arg->type.dimension));
-        arg = arg->next;
-    }
-
-    // Add the default RpcContext param to all methods
-    decl->parameters.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
-	
-    serviceBaseClass->elements.push_back(decl);
-    
-
-    // == the dispatch method in the service base class ======================
-    serviceBaseClass->AddMethod(method);
-}
-
-static void
-generate_event_method(const method_type* method, RpcProxyClass* proxyClass,
-        EndpointBaseClass* serviceBaseClass, ListenerClass* listenerClass,
-        EventListenerClass* presenterClass, int index)
-{
-    arg_type* arg;
-    listenerClass->needed = true;
-
-    // == the push method in the service base class =========================
-    Method* push = new Method;
-        push->modifiers = PUBLIC;
-        push->name = push_method_name(method->name.data);
-        push->statements = new StatementBlock;
-        push->returnType = VOID_TYPE;
-    serviceBaseClass->elements.push_back(push);
-
-    // The local variables
-    Variable* _data = new Variable(RPC_DATA_TYPE, "_data");
-    push->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE)));
-
-    // Add the arguments
-    arg = method->args;
-    while (arg != NULL) {
-        // Function signature
-        Type* t = NAMES.Search(arg->type.type.data);
-        Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
-        push->parameters.push_back(v);
-
-        // Input parameter marshalling
-        generate_write_to_data(t, push->statements,
-                new StringLiteralExpression(arg->name.data), v, _data);
-
-        arg = arg->next;
-    }
-
-    // Send the notifications
-    push->statements->Add(new MethodCall("pushEvent", 2,
-                new StringLiteralExpression(method->name.data),
-                new MethodCall(_data, "serialize")));
-
-    // == the event callback dispatcher method  ====================================
-    presenterClass->AddMethod(method);
-
-    // == the event method in the listener base class =====================
-    Method* event = new Method;
-        event->modifiers = PUBLIC;
-        event->name = method->name.data;
-        event->statements = new StatementBlock;
-        event->returnType = VOID_TYPE;
-    listenerClass->elements.push_back(event);
-    arg = method->args;
-    while (arg != NULL) {
-        event->parameters.push_back(new Variable(
-                            NAMES.Search(arg->type.type.data), arg->name.data,
-                            arg->type.dimension));
-        arg = arg->next;
-    }
-
-    // Add a final parameter: RpcContext. Contains data about
-    // incoming request (e.g., certificate)
-    event->parameters.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
-}
-
-static void
-generate_listener_methods(RpcProxyClass* proxyClass, Type* presenterType, Type* listenerType)
-{
-    // AndroidAtHomePresenter _presenter;
-    // void startListening(Listener listener) {
-    //     stopListening();
-    //     _presenter = new Presenter(_broker, listener);
-    //     _presenter.startListening(_endpoint);
-    // }
-    // void stopListening() {
-    //     if (_presenter != null) {
-    //         _presenter.stopListening();
-    //     }
-    // }
-
-    Variable* _presenter = new Variable(presenterType, "_presenter");
-    proxyClass->elements.push_back(new Field(PRIVATE, _presenter));
-
-    Variable* listener = new Variable(listenerType, "listener");
-
-    Method* startListeningMethod = new Method;
-        startListeningMethod->modifiers = PUBLIC;
-        startListeningMethod->returnType = VOID_TYPE;
-        startListeningMethod->name = "startListening";
-        startListeningMethod->statements = new StatementBlock;
-        startListeningMethod->parameters.push_back(listener);
-    proxyClass->elements.push_back(startListeningMethod);
-
-    startListeningMethod->statements->Add(new MethodCall(THIS_VALUE, "stopListening"));
-    startListeningMethod->statements->Add(new Assignment(_presenter,
-                new NewExpression(presenterType, 2, proxyClass->broker, listener)));
-    startListeningMethod->statements->Add(new MethodCall(_presenter,
-                "startListening", 1, proxyClass->endpoint));
-
-    Method* stopListeningMethod = new Method;
-        stopListeningMethod->modifiers = PUBLIC;
-        stopListeningMethod->returnType = VOID_TYPE;
-        stopListeningMethod->name = "stopListening";
-        stopListeningMethod->statements = new StatementBlock;
-    proxyClass->elements.push_back(stopListeningMethod);
-
-    IfStatement* ifst = new IfStatement;
-        ifst->expression = new Comparison(_presenter, "!=", NULL_VALUE);
-    stopListeningMethod->statements->Add(ifst);
-
-    ifst->statements->Add(new MethodCall(_presenter, "stopListening"));
-    ifst->statements->Add(new Assignment(_presenter, NULL_VALUE));
-}
-
-Class*
-generate_rpc_interface_class(const interface_type* iface)
-{
-    // the proxy class
-    InterfaceType* interfaceType = static_cast<InterfaceType*>(
-        NAMES.Find(iface->package, iface->name.data));
-    RpcProxyClass* proxy = new RpcProxyClass(iface, interfaceType);
-
-    // the listener class
-    ListenerClass* listener = new ListenerClass(iface);
-
-    // the presenter class
-    EventListenerClass* presenter = new EventListenerClass(iface, listener->type);
-
-    // the service base class
-    EndpointBaseClass* base = new EndpointBaseClass(iface);
-    proxy->elements.push_back(base);
-
-    // the result dispatcher
-    ResultDispatcherClass* results = new ResultDispatcherClass();
-
-    // all the declared methods of the proxy
-    int index = 0;
-    interface_item_type* item = iface->interface_items;
-    while (item != NULL) {
-        if (item->item_type == METHOD_TYPE) {
-            if (NAMES.Search(((method_type*)item)->type.type.data) == EVENT_FAKE_TYPE) {
-                generate_event_method((method_type*)item, proxy, base, listener, presenter, index);
-            } else {
-                generate_regular_method((method_type*)item, proxy, base, results, index);
-            }
-        }
-        item = item->next;
-        index++;
-    }
-    presenter->DoneWithMethods();
-    base->DoneWithMethods();
-
-    // only add this if there are methods with results / out parameters
-    if (results->needed) {
-        proxy->elements.push_back(results);
-    }
-    if (listener->needed) {
-        proxy->elements.push_back(listener);
-        proxy->elements.push_back(presenter);
-        generate_listener_methods(proxy, presenter->type, listener->type);
-    }
-
-    return proxy;
-}
diff --git a/tools/aidl/options.cpp b/tools/aidl/options.cpp
deleted file mode 100644
index 7b2daeb..0000000
--- a/tools/aidl/options.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-
-#include "options.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-static int
-usage()
-{
-    fprintf(stderr,
-            "usage: aidl OPTIONS INPUT [OUTPUT]\n"
-            "       aidl --preprocess OUTPUT INPUT...\n"
-            "\n"
-            "OPTIONS:\n"
-            "   -I<DIR>    search path for import statements.\n"
-            "   -d<FILE>   generate dependency file.\n"
-            "   -a         generate dependency file next to the output file with the name based on the input file.\n"
-            "   -p<FILE>   file created by --preprocess to import.\n"
-            "   -o<FOLDER> base output folder for generated files.\n"
-            "   -b         fail when trying to compile a parcelable.\n"
-            "\n"
-            "INPUT:\n"
-            "   An aidl interface file.\n"
-            "\n"
-            "OUTPUT:\n"
-            "   The generated interface files.\n"
-            "   If omitted and the -o option is not used, the input filename is used, with the .aidl extension changed to a .java extension.\n"
-            "   If the -o option is used, the generated files will be placed in the base output folder, under their package folder\n"
-           );
-    return 1;
-}
-
-int
-parse_options(int argc, const char* const* argv, Options *options)
-{
-    int i = 1;
-
-    if (argc >= 2 && 0 == strcmp(argv[1], "--preprocess")) {
-        if (argc < 4) {
-            return usage();
-        }
-        options->outputFileName = argv[2];
-        for (int i=3; i<argc; i++) {
-            options->filesToPreprocess.push_back(argv[i]);
-        }
-        options->task = PREPROCESS_AIDL;
-        return 0;
-    }
-
-    options->task = COMPILE_AIDL;
-    options->failOnParcelable = false;
-    options->autoDepFile = false;
-
-    // OPTIONS
-    while (i < argc) {
-        const char* s = argv[i];
-        int len = strlen(s);
-        if (s[0] == '-') {
-            if (len > 1) {
-                // -I<system-import-path>
-                if (s[1] == 'I') {
-                    if (len > 2) {
-                        options->importPaths.push_back(s+2);
-                    } else {
-                        fprintf(stderr, "-I option (%d) requires a path.\n", i);
-                        return usage();
-                    }
-                }
-                else if (s[1] == 'd') {
-                    if (len > 2) {
-                        options->depFileName = s+2;
-                    } else {
-                        fprintf(stderr, "-d option (%d) requires a file.\n", i);
-                        return usage();
-                    }
-                }
-                else if (s[1] == 'a') {
-                    options->autoDepFile = true;
-                }
-                else if (s[1] == 'p') {
-                    if (len > 2) {
-                        options->preprocessedFiles.push_back(s+2);
-                    } else {
-                        fprintf(stderr, "-p option (%d) requires a file.\n", i);
-                        return usage();
-                    }
-                }
-                else if (s[1] == 'o') {
-                    if (len > 2) {
-                        options->outputBaseFolder = s+2;
-                    } else {
-                        fprintf(stderr, "-o option (%d) requires a path.\n", i);
-                        return usage();
-                    }
-                }
-                else if (len == 2 && s[1] == 'b') {
-                    options->failOnParcelable = true;
-                }
-                else {
-                    // s[1] is not known
-                    fprintf(stderr, "unknown option (%d): %s\n", i, s);
-                    return usage();
-                }
-            } else {
-                // len <= 1
-                fprintf(stderr, "unknown option (%d): %s\n", i, s);
-                return usage();
-            }
-        } else {
-            // s[0] != '-'
-            break;
-        }
-        i++;
-    }
-
-    // INPUT
-    if (i < argc) {
-        options->inputFileName = argv[i];
-        i++;
-    } else {
-        fprintf(stderr, "INPUT required\n");
-        return usage();
-    }
-
-    // OUTPUT
-    if (i < argc) {
-        options->outputFileName = argv[i];
-        i++;
-    } else if (options->outputBaseFolder.length() == 0) {
-        // copy input into output and change the extension from .aidl to .java
-        options->outputFileName = options->inputFileName;
-        string::size_type pos = options->outputFileName.size()-5;
-        if (options->outputFileName.compare(pos, 5, ".aidl") == 0) {  // 5 = strlen(".aidl")
-            options->outputFileName.replace(pos, 5, ".java"); // 5 = strlen(".aidl")
-        } else {
-            fprintf(stderr, "INPUT is not an .aidl file.\n");
-            return usage();
-        }
-     }
-
-    // anything remaining?
-    if (i != argc) {
-        fprintf(stderr, "unknown option%s:", (i==argc-1?(const char*)"":(const char*)"s"));
-        for (; i<argc-1; i++) {
-            fprintf(stderr, " %s", argv[i]);
-        }
-        fprintf(stderr, "\n");
-        return usage();
-    }
-
-    return 0;
-}
-
diff --git a/tools/aidl/options.h b/tools/aidl/options.h
deleted file mode 100644
index 387e37d..0000000
--- a/tools/aidl/options.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef DEVICE_TOOLS_AIDL_H
-#define DEVICE_TOOLS_AIDL_H
-
-#include <string.h>
-#include <string>
-#include <vector>
-
-using namespace std;
-
-enum {
-    COMPILE_AIDL,
-    PREPROCESS_AIDL
-};
-
-// This struct is the parsed version of the command line options
-struct Options
-{
-    int task;
-    bool failOnParcelable;
-    vector<string> importPaths;
-    vector<string> preprocessedFiles;
-    string inputFileName;
-    string outputFileName;
-    string outputBaseFolder;
-    string depFileName;
-    bool autoDepFile;
-
-    vector<string> filesToPreprocess;
-};
-
-// takes the inputs from the command line and fills in the Options struct
-// Returns 0 on success, and nonzero on failure.
-// It also prints the usage statement on failure.
-int parse_options(int argc, const char* const* argv, Options *options);
-
-#endif // DEVICE_TOOLS_AIDL_H
diff --git a/tools/aidl/options_test.cpp b/tools/aidl/options_test.cpp
deleted file mode 100644
index bd106ce..0000000
--- a/tools/aidl/options_test.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-#include <iostream>
-#include "options.h"
-
-const bool VERBOSE = false;
-
-using namespace std;
-
-struct Answer {
-    const char* argv[8];
-    int result;
-    const char* systemSearchPath[8];
-    const char* localSearchPath[8];
-    const char* inputFileName;
-    language_t nativeLanguage;
-    const char* outputH;
-    const char* outputCPP;
-    const char* outputJava;
-};
-
-bool
-match_arrays(const char* const*expected, const vector<string> &got)
-{
-    int count = 0;
-    while (expected[count] != NULL) {
-        count++;
-    }
-    if (got.size() != count) {
-        return false;
-    }
-    for (int i=0; i<count; i++) {
-        if (got[i] != expected[i]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-void
-print_array(const char* prefix, const char* const*expected)
-{
-    while (*expected) {
-        cout << prefix << *expected << endl;
-        expected++;
-    }
-}
-
-void
-print_array(const char* prefix, const vector<string> &got)
-{
-    size_t count = got.size();
-    for (size_t i=0; i<count; i++) {
-        cout << prefix << got[i] << endl;
-    }
-}
-
-static int
-test(const Answer& answer)
-{
-    int argc = 0;
-    while (answer.argv[argc]) {
-        argc++;
-    }
-
-    int err = 0;
-
-    Options options;
-    int result = parse_options(argc, answer.argv, &options);
-
-    // result
-    if (((bool)result) != ((bool)answer.result)) {
-        cout << "mismatch: result: got " << result << " expected " <<
-            answer.result << endl;
-        err = 1;
-    }
-
-    if (result != 0) {
-        // if it failed, everything is invalid
-        return err;
-    }
-
-    // systemSearchPath
-    if (!match_arrays(answer.systemSearchPath, options.systemSearchPath)) {
-        cout << "mismatch: systemSearchPath: got" << endl;
-        print_array("        ", options.systemSearchPath);
-        cout << "    expected" << endl;
-        print_array("        ", answer.systemSearchPath);
-        err = 1;
-    }
-
-    // localSearchPath
-    if (!match_arrays(answer.localSearchPath, options.localSearchPath)) {
-        cout << "mismatch: localSearchPath: got" << endl;
-        print_array("        ", options.localSearchPath);
-        cout << "    expected" << endl;
-        print_array("        ", answer.localSearchPath);
-        err = 1;
-    }
-
-    // inputFileName
-    if (answer.inputFileName != options.inputFileName) {
-        cout << "mismatch: inputFileName: got " << options.inputFileName
-            << " expected " << answer.inputFileName << endl;
-        err = 1;
-    }
-
-    // nativeLanguage
-    if (answer.nativeLanguage != options.nativeLanguage) {
-        cout << "mismatch: nativeLanguage: got " << options.nativeLanguage
-            << " expected " << answer.nativeLanguage << endl;
-        err = 1;
-    }
-
-    // outputH
-    if (answer.outputH != options.outputH) {
-        cout << "mismatch: outputH: got " << options.outputH
-            << " expected " << answer.outputH << endl;
-        err = 1;
-    }
-
-    // outputCPP
-    if (answer.outputCPP != options.outputCPP) {
-        cout << "mismatch: outputCPP: got " << options.outputCPP
-            << " expected " << answer.outputCPP << endl;
-        err = 1;
-    }
-
-    // outputJava
-    if (answer.outputJava != options.outputJava) {
-        cout << "mismatch: outputJava: got " << options.outputJava
-            << " expected " << answer.outputJava << endl;
-        err = 1;
-    }
-
-    return err;
-}
-
-const Answer g_tests[] = {
-
-    {
-        /* argv */              { "test", "-i/moof", "-I/blah", "-Ibleh", "-imoo", "inputFileName.aidl_cpp", NULL, NULL },
-        /* result */            0,
-        /* systemSearchPath */  { "/blah", "bleh", NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { "/moof", "moo", NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "inputFileName.aidl_cpp",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "",
-        /* outputCPP */         "",
-        /* outputJava */        ""
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-oh", "outputH", NULL, NULL, NULL, NULL },
-        /* result */            0,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "inputFileName.aidl_cpp",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "outputH",
-        /* outputCPP */         "",
-        /* outputJava */        ""
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-ocpp", "outputCPP", NULL, NULL, NULL, NULL },
-        /* result */            0,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "inputFileName.aidl_cpp",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "",
-        /* outputCPP */         "outputCPP",
-        /* outputJava */        ""
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-ojava", "outputJava", NULL, NULL, NULL, NULL },
-        /* result */            0,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "inputFileName.aidl_cpp",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "",
-        /* outputCPP */         "",
-        /* outputJava */        "outputJava"
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-oh", "outputH", "-ocpp", "outputCPP", "-ojava", "outputJava" },
-        /* result */            0,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "inputFileName.aidl_cpp",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "outputH",
-        /* outputCPP */         "outputCPP",
-        /* outputJava */        "outputJava"
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-oh", "outputH", "-oh", "outputH1", NULL, NULL },
-        /* result */            1,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "",
-        /* outputCPP */         "",
-        /* outputJava */        ""
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-ocpp", "outputCPP", "-ocpp", "outputCPP1", NULL, NULL },
-        /* result */            1,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "",
-        /* outputCPP */         "",
-        /* outputJava */        ""
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-ojava", "outputJava", "-ojava", "outputJava1", NULL, NULL },
-        /* result */            1,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "",
-        /* outputCPP */         "",
-        /* outputJava */        ""
-    },
-
-};
-
-int
-main(int argc, const char** argv)
-{
-    const int count = sizeof(g_tests)/sizeof(g_tests[0]);
-    int matches[count];
-
-    int result = 0;
-    for (int i=0; i<count; i++) {
-        if (VERBOSE) {
-            cout << endl;
-            cout << "---------------------------------------------" << endl;
-            const char* const* p = g_tests[i].argv;
-            while (*p) {
-                cout << " " << *p;
-                p++;
-            }
-            cout << endl;
-            cout << "---------------------------------------------" << endl;
-        }
-        matches[i] = test(g_tests[i]);
-        if (VERBOSE) {
-            if (0 == matches[i]) {
-                cout << "passed" << endl;
-            } else {
-                cout << "failed" << endl;
-            }
-            result |= matches[i];
-        }
-    }
-
-    cout << endl;
-    cout << "=============================================" << endl;
-    cout << "options_test summary" << endl;
-    cout << "=============================================" << endl;
-
-    if (!result) {
-        cout << "passed" << endl;
-    } else {
-        cout << "failed the following tests:" << endl;
-        for (int i=0; i<count; i++) {
-            if (matches[i]) {
-                cout << "   ";
-                const char* const* p = g_tests[i].argv;
-                while (*p) {
-                    cout << " " << *p;
-                    p++;
-                }
-                cout << endl;
-            }
-        }
-    }
-
-    return result;
-}
-
diff --git a/tools/aidl/search_path.cpp b/tools/aidl/search_path.cpp
deleted file mode 100644
index ffb6cb2..0000000
--- a/tools/aidl/search_path.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <unistd.h>
-#include "search_path.h"
-#include "options.h"
-#include <string.h>
-
-#ifdef HAVE_MS_C_RUNTIME
-#include <io.h>
-#endif
-
-static vector<string> g_importPaths;
-
-void
-set_import_paths(const vector<string>& importPaths)
-{
-    g_importPaths = importPaths;
-}
-
-char*
-find_import_file(const char* given)
-{
-    string expected = given;
-
-    int N = expected.length();
-    for (int i=0; i<N; i++) {
-        char c = expected[i];
-        if (c == '.') {
-            expected[i] = OS_PATH_SEPARATOR;
-        }
-    }
-    expected += ".aidl";
-
-    vector<string>& paths = g_importPaths;
-    for (vector<string>::iterator it=paths.begin(); it!=paths.end(); it++) {
-        string f = *it;
-        if (f.size() == 0) {
-            f = ".";
-            f += OS_PATH_SEPARATOR;
-        }
-        else if (f[f.size()-1] != OS_PATH_SEPARATOR) {
-            f += OS_PATH_SEPARATOR;
-        }
-        f.append(expected);
-
-#ifdef HAVE_MS_C_RUNTIME
-        /* check that the file exists and is not write-only */
-        if (0 == _access(f.c_str(), 0) &&  /* mode 0=exist */
-            0 == _access(f.c_str(), 4) ) { /* mode 4=readable */
-#else
-        if (0 == access(f.c_str(), R_OK)) {
-#endif        
-            return strdup(f.c_str());
-        }
-    }
-
-    return NULL;
-}
-
diff --git a/tools/aidl/search_path.h b/tools/aidl/search_path.h
deleted file mode 100644
index 2bf94b1..0000000
--- a/tools/aidl/search_path.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef DEVICE_TOOLS_AIDL_SEARCH_PATH_H
-#define DEVICE_TOOLS_AIDL_SEARCH_PATH_H
-
-#include <stdio.h>
-
-#if __cplusplus
-#include <vector>
-#include <string>
-using namespace std;
-extern "C" {
-#endif
-
-// returns a FILE* and the char* for the file that it found
-// given is the class name we're looking for
-char* find_import_file(const char* given);
-
-#if __cplusplus
-}; // extern "C"
-void set_import_paths(const vector<string>& importPaths);
-#endif
-
-#endif // DEVICE_TOOLS_AIDL_SEARCH_PATH_H
-
diff --git a/tools/layoutlib/.gitignore b/tools/layoutlib/.gitignore
deleted file mode 100644
index c5e82d7..0000000
--- a/tools/layoutlib/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-bin
\ No newline at end of file
diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk
deleted file mode 100644
index ed497a5..0000000
--- a/tools/layoutlib/Android.mk
+++ /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.
-#
-LOCAL_PATH := $(my-dir)
-include $(CLEAR_VARS)
-
-#
-# Define rules to build temp_layoutlib.jar, which contains a subset of
-# the classes in framework.jar.  The layoutlib_create tool is used to
-# transform the framework jar into the temp_layoutlib jar.
-#
-
-# We need to process the framework classes.jar file, but we can't
-# depend directly on it (private vars won't be inherited correctly).
-# So, we depend on framework's BUILT file.
-built_framework_dep := $(call java-lib-deps,framework-base)
-built_framework_classes := $(call java-lib-files,framework-base)
-
-built_core_dep := $(call java-lib-deps,core)
-built_core_classes := $(call java-lib-files,core)
-
-built_ext_dep := $(call java-lib-deps,ext)
-built_ext_classes := $(call java-lib-files,ext)
-
-built_layoutlib_create_jar := $(call intermediates-dir-for, \
-			JAVA_LIBRARIES,layoutlib_create,HOST)/javalib.jar
-
-# This is mostly a copy of config/host_java_library.mk
-LOCAL_MODULE := temp_layoutlib
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
-LOCAL_IS_HOST_MODULE := true
-LOCAL_BUILT_MODULE_STEM := javalib.jar
-
-#######################################
-include $(BUILD_SYSTEM)/base_rules.mk
-#######################################
-
-$(LOCAL_BUILT_MODULE): $(built_core_dep) \
-                       $(built_framework_dep) \
-                       $(built_ext_dep) \
-                       $(built_layoutlib_create_jar)
-	$(hide) echo "host layoutlib_create: $@"
-	$(hide) mkdir -p $(dir $@)
-	$(hide) rm -f $@
-	$(hide) ls -l $(built_framework_classes)
-	$(hide) java -jar $(built_layoutlib_create_jar) \
-	             $@ \
-	             $(built_core_classes) \
-	             $(built_framework_classes) \
-	             $(built_ext_classes)
-	$(hide) ls -l $(built_framework_classes)
-
-
-#
-# Include the subdir makefiles.
-#
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/layoutlib/README b/tools/layoutlib/README
deleted file mode 100644
index 0fea9bd..0000000
--- a/tools/layoutlib/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Layoutlib is a custom version of the android View framework designed to run inside Eclipse.
-The goal of the library is to provide layout rendering in Eclipse that are very very close to their rendering on devices.
-
-None of the com.android.* or android.* classes in layoutlib run on devices.
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
deleted file mode 100644
index 2e4274d..0000000
--- a/tools/layoutlib/bridge/.classpath
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/tools-common/tools-common-prebuilt.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/icu4j/icu4j.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib/bridge/.project b/tools/layoutlib/bridge/.project
deleted file mode 100644
index e36e71b..0000000
--- a/tools/layoutlib/bridge/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_bridge</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib/bridge/.settings/README.txt b/tools/layoutlib/bridge/.settings/README.txt
deleted file mode 100644
index 9120b20..0000000
--- a/tools/layoutlib/bridge/.settings/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Copy this in eclipse project as a .settings folder at the root.
-This ensure proper compilation compliance and warning/error levels.
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/.settings/org.eclipse.jdt.core.prefs b/tools/layoutlib/bridge/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 5381a0e..0000000
--- a/tools/layoutlib/bridge/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,93 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.nonnull=com.android.annotations.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=com.android.annotations.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled
-org.eclipse.jdt.core.compiler.annotation.nullable=com.android.annotations.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=error
-org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk
deleted file mode 100644
index e3d48fc..0000000
--- a/tools/layoutlib/bridge/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-
-LOCAL_JAVA_LIBRARIES := \
-	kxml2-2.3.0 \
-	icu4j \
-	layoutlib_api-prebuilt \
-	tools-common-prebuilt
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	temp_layoutlib \
-	ninepatch-prebuilt
-
-LOCAL_MODULE := layoutlib
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/tools/layoutlib/bridge/resources/bars/action_bar.xml b/tools/layoutlib/bridge/resources/bars/action_bar.xml
deleted file mode 100644
index 7adc5af..0000000
--- a/tools/layoutlib/bridge/resources/bars/action_bar.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <include layout="@android:layout/action_bar_home" />
-    <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png
deleted file mode 100644
index 84e6bc8..0000000
--- a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png
deleted file mode 100644
index 38e4f45..0000000
--- a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png
deleted file mode 100644
index bf9f300..0000000
--- a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_battery_charge_anim100.png b/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_battery_charge_anim100.png
deleted file mode 100644
index 829378e..0000000
--- a/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_battery_charge_anim100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 931daed..0000000
--- a/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/status_bar_background.9.png b/tools/layoutlib/bridge/resources/bars/hdpi/status_bar_background.9.png
deleted file mode 100644
index a4be298..0000000
--- a/tools/layoutlib/bridge/resources/bars/hdpi/status_bar_background.9.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_back.png
deleted file mode 100644
index 782ebfe..0000000
--- a/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index 677b471..0000000
--- a/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_back.png
deleted file mode 100644
index a1b8062..0000000
--- a/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index fcdbefe..0000000
--- a/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 633d864..0000000
--- a/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 4665e2a..0000000
--- a/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png
deleted file mode 100644
index a00bc5b..0000000
--- a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png
deleted file mode 100644
index dc3183b..0000000
--- a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png
deleted file mode 100644
index b07f611..0000000
--- a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_battery_charge_anim100.png b/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_battery_charge_anim100.png
deleted file mode 100644
index 2773a70..0000000
--- a/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_battery_charge_anim100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 6e1ac91..0000000
--- a/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/status_bar_background.9.png b/tools/layoutlib/bridge/resources/bars/mdpi/status_bar_background.9.png
deleted file mode 100644
index eb7c1a4..0000000
--- a/tools/layoutlib/bridge/resources/bars/mdpi/status_bar_background.9.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/navigation_bar.xml b/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
deleted file mode 100644
index 599ca08..0000000
--- a/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<TextView
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_weight="1"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"/>
-	<TextView
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_weight="1"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/status_bar.xml b/tools/layoutlib/bridge/resources/bars/status_bar.xml
deleted file mode 100644
index 51b474d..0000000
--- a/tools/layoutlib/bridge/resources/bars/status_bar.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<TextView
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_weight="1"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_marginTop="1dp"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_marginLeft="3dp"
-			android:layout_marginRight="5dp"
-			android:layout_marginTop="1dp"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/title_bar.xml b/tools/layoutlib/bridge/resources/bars/title_bar.xml
deleted file mode 100644
index 76d78d9..0000000
--- a/tools/layoutlib/bridge/resources/bars/title_bar.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<TextView
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png
deleted file mode 100644
index bd60cd6..0000000
--- a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png
deleted file mode 100644
index c5bc5c9..0000000
--- a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index f621d9c..0000000
--- a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_battery_charge_anim100.png b/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_battery_charge_anim100.png
deleted file mode 100644
index c7fd719..0000000
--- a/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_battery_charge_anim100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 625c61d..0000000
--- a/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/src/android/animation/AnimationThread.java b/tools/layoutlib/bridge/src/android/animation/AnimationThread.java
deleted file mode 100644
index b10ec9f..0000000
--- a/tools/layoutlib/bridge/src/android/animation/AnimationThread.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.animation;
-
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-
-import android.os.Handler;
-import android.os.Handler_Delegate;
-import android.os.Handler_Delegate.IHandlerCallback;
-import android.os.Message;
-
-import java.util.PriorityQueue;
-import java.util.Queue;
-
-/**
- * Abstract animation thread.
- * <p/>
- * This does not actually start an animation, instead it fakes a looper that will play whatever
- * animation is sending messages to its own {@link Handler}.
- * <p/>
- * Classes should implement {@link #preAnimation()} and {@link #postAnimation()}.
- * <p/>
- * If {@link #preAnimation()} does not start an animation somehow then the thread doesn't do
- * anything.
- *
- */
-public abstract class AnimationThread extends Thread {
-
-    private static class MessageBundle implements Comparable<MessageBundle> {
-        final Handler mTarget;
-        final Message mMessage;
-        final long mUptimeMillis;
-
-        MessageBundle(Handler target, Message message, long uptimeMillis) {
-            mTarget = target;
-            mMessage = message;
-            mUptimeMillis = uptimeMillis;
-        }
-
-        @Override
-        public int compareTo(MessageBundle bundle) {
-            if (mUptimeMillis < bundle.mUptimeMillis) {
-                return -1;
-            }
-            return 1;
-        }
-    }
-
-    private final RenderSessionImpl mSession;
-
-    private Queue<MessageBundle> mQueue = new PriorityQueue<MessageBundle>();
-    private final IAnimationListener mListener;
-
-    public AnimationThread(RenderSessionImpl scene, String threadName,
-            IAnimationListener listener) {
-        super(threadName);
-        mSession = scene;
-        mListener = listener;
-    }
-
-    public abstract Result preAnimation();
-    public abstract void postAnimation();
-
-    @Override
-    public void run() {
-        Bridge.prepareThread();
-        try {
-            /* FIXME: The ANIMATION_FRAME message no longer exists.  Instead, the
-             * animation timing loop is completely based on a Choreographer objects
-             * that schedules animation and drawing frames.  The animation handler is
-             * no longer even a handler; it is just a Runnable enqueued on the Choreographer.
-            Handler_Delegate.setCallback(new IHandlerCallback() {
-                @Override
-                public void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) {
-                    if (msg.what == ValueAnimator.ANIMATION_START ||
-                            msg.what == ValueAnimator.ANIMATION_FRAME) {
-                        mQueue.add(new MessageBundle(handler, msg, uptimeMillis));
-                    } else {
-                        // just ignore.
-                    }
-                }
-            });
-            */
-
-            // call out to the pre-animation work, which should start an animation or more.
-            Result result = preAnimation();
-            if (result.isSuccess() == false) {
-                mListener.done(result);
-            }
-
-            // loop the animation
-            RenderSession session = mSession.getSession();
-            do {
-                // check early.
-                if (mListener.isCanceled()) {
-                    break;
-                }
-
-                // get the next message.
-                MessageBundle bundle = mQueue.poll();
-                if (bundle == null) {
-                    break;
-                }
-
-                // sleep enough for this bundle to be on time
-                long currentTime = System.currentTimeMillis();
-                if (currentTime < bundle.mUptimeMillis) {
-                    try {
-                        sleep(bundle.mUptimeMillis - currentTime);
-                    } catch (InterruptedException e) {
-                        // FIXME log/do something/sleep again?
-                        e.printStackTrace();
-                    }
-                }
-
-                // check after sleeping.
-                if (mListener.isCanceled()) {
-                    break;
-                }
-
-                // ready to do the work, acquire the scene.
-                result = mSession.acquire(250);
-                if (result.isSuccess() == false) {
-                    mListener.done(result);
-                    return;
-                }
-
-                // process the bundle. If the animation is not finished, this will enqueue
-                // the next message, so mQueue will have another one.
-                try {
-                    // check after acquiring in case it took a while.
-                    if (mListener.isCanceled()) {
-                        break;
-                    }
-
-                    bundle.mTarget.handleMessage(bundle.mMessage);
-                    if (mSession.render(false /*freshRender*/).isSuccess()) {
-                        mListener.onNewFrame(session);
-                    }
-                } finally {
-                    mSession.release();
-                }
-            } while (mListener.isCanceled() == false && mQueue.size() > 0);
-
-            mListener.done(Status.SUCCESS.createResult());
-
-        } catch (Throwable throwable) {
-            // can't use Bridge.getLog() as the exception might be thrown outside
-            // of an acquire/release block.
-            mListener.done(Status.ERROR_UNKNOWN.createResult("Error playing animation", throwable));
-
-        } finally {
-            postAnimation();
-            Handler_Delegate.setCallback(null);
-            Bridge.cleanupThread();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
deleted file mode 100644
index 7b444aa..0000000
--- a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.animation;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.animation.PropertyValuesHolder
- *
- * Through the layoutlib_create tool, the original native methods of PropertyValuesHolder have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- * The main goal of this class' methods are to provide a native way to access setters and getters
- * on some object. In this case we want to default to using Java reflection instead so the native
- * methods do nothing.
- *
- */
-/*package*/ class PropertyValuesHolder_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetIntMethod(Class<?> targetClass, String methodName) {
-        // return 0 to force PropertyValuesHolder to use Java reflection.
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetFloatMethod(Class<?> targetClass, String methodName) {
-        // return 0 to force PropertyValuesHolder to use Java reflection.
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallIntMethod(Object target, int methodID, int arg) {
-        // do nothing
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallFloatMethod(Object target, int methodID, float arg) {
-        // do nothing
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java b/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
deleted file mode 100644
index aabd3f1..0000000
--- a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-import com.android.ide.common.rendering.api.IProjectCallback;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.os.Bundle;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Fragment}
- *
- * Through the layoutlib_create tool, the original  methods of Fragment have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * The methods being re-implemented are the ones responsible for instantiating Fragment objects.
- * Because the classes of these objects are found in the project, these methods need access to
- * {@link IProjectCallback} object. They are however static methods, so the callback is set
- * before the inflation through {@link #setProjectCallback(IProjectCallback)}.
- */
-public class Fragment_Delegate {
-
-    private static IProjectCallback sProjectCallback;
-
-    /**
-     * Sets the current {@link IProjectCallback} to be used to instantiate classes coming
-     * from the project being rendered.
-     */
-    public static void setProjectCallback(IProjectCallback projectCallback) {
-        sProjectCallback = projectCallback;
-    }
-
-    /**
-     * Like {@link #instantiate(Context, String, Bundle)} but with a null
-     * argument Bundle.
-     */
-    @LayoutlibDelegate
-    /*package*/ static Fragment instantiate(Context context, String fname) {
-        return instantiate(context, fname, null);
-    }
-
-    /**
-     * Create a new instance of a Fragment with the given class name.  This is
-     * the same as calling its empty constructor.
-     *
-     * @param context The calling context being used to instantiate the fragment.
-     * This is currently just used to get its ClassLoader.
-     * @param fname The class name of the fragment to instantiate.
-     * @param args Bundle of arguments to supply to the fragment, which it
-     * can retrieve with {@link #getArguments()}.  May be null.
-     * @return Returns a new fragment instance.
-     * @throws InstantiationException If there is a failure in instantiating
-     * the given fragment class.  This is a runtime exception; it is not
-     * normally expected to happen.
-     */
-    @LayoutlibDelegate
-    /*package*/ static Fragment instantiate(Context context, String fname, Bundle args) {
-        try {
-            if (sProjectCallback != null) {
-                Fragment f = (Fragment) sProjectCallback.loadView(fname,
-                        new Class[0], new Object[0]);
-
-                if (args != null) {
-                    args.setClassLoader(f.getClass().getClassLoader());
-                    f.mArguments = args;
-                }
-                return f;
-            }
-
-            return null;
-        } catch (ClassNotFoundException e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        } catch (java.lang.InstantiationException e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        } catch (IllegalAccessException e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        } catch (Exception e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeAssetManager.java b/tools/layoutlib/bridge/src/android/content/res/BridgeAssetManager.java
deleted file mode 100644
index a953918..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeAssetManager.java
+++ /dev/null
@@ -1,53 +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.content.res;
-
-import com.android.layoutlib.bridge.Bridge;
-
-import android.content.res.AssetManager;
-
-public class BridgeAssetManager extends AssetManager {
-
-    /**
-     * This initializes the static field {@link AssetManager#mSystem} which is used
-     * by methods who get a global asset manager using {@link AssetManager#getSystem()}.
-     * <p/>
-     * They will end up using our bridge asset manager.
-     * <p/>
-     * {@link Bridge} calls this method after setting up a new bridge.
-     */
-    public static AssetManager initSystem() {
-        if (!(AssetManager.sSystem instanceof BridgeAssetManager)) {
-            // Note that AssetManager() creates a system AssetManager and we override it
-            // with our BridgeAssetManager.
-            AssetManager.sSystem = new BridgeAssetManager();
-            AssetManager.sSystem.makeStringBlocks(false);
-        }
-        return AssetManager.sSystem;
-    }
-
-    /**
-     * Clears the static {@link AssetManager#sSystem} to make sure we don't leave objects
-     * around that would prevent us from unloading the library.
-     */
-    public static void clearSystem() {
-        AssetManager.sSystem = null;
-    }
-
-    private BridgeAssetManager() {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
deleted file mode 100644
index 8794452..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
+++ /dev/null
@@ -1,695 +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.content.res;
-
-import com.android.ide.common.rendering.api.IProjectCallback;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.ninepatch.NinePatch;
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.ViewGroup.LayoutParams;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-
-/**
- *
- */
-public final class BridgeResources extends Resources {
-
-    private BridgeContext mContext;
-    private IProjectCallback mProjectCallback;
-    private boolean[] mPlatformResourceFlag = new boolean[1];
-
-    /**
-     * Simpler wrapper around FileInputStream. This is used when the input stream represent
-     * not a normal bitmap but a nine patch.
-     * This is useful when the InputStream is created in a method but used in another that needs
-     * to know whether this is 9-patch or not, such as BitmapFactory.
-     */
-    public class NinePatchInputStream extends FileInputStream {
-        private boolean mFakeMarkSupport = true;
-        public NinePatchInputStream(File file) throws FileNotFoundException {
-            super(file);
-        }
-
-        @Override
-        public boolean markSupported() {
-            if (mFakeMarkSupport) {
-                // this is needed so that BitmapFactory doesn't wrap this in a BufferedInputStream.
-                return true;
-            }
-
-            return super.markSupported();
-        }
-
-        public void disableFakeMarkSupport() {
-            // disable fake mark support so that in case codec actually try to use them
-            // we don't lie to them.
-            mFakeMarkSupport = false;
-        }
-    }
-
-    /**
-     * This initializes the static field {@link Resources#mSystem} which is used
-     * by methods who get global resources using {@link Resources#getSystem()}.
-     * <p/>
-     * They will end up using our bridge resources.
-     * <p/>
-     * {@link Bridge} calls this method after setting up a new bridge.
-     */
-    public static Resources initSystem(BridgeContext context,
-            AssetManager assets,
-            DisplayMetrics metrics,
-            Configuration config,
-            IProjectCallback projectCallback) {
-        return Resources.mSystem = new BridgeResources(context,
-                assets,
-                metrics,
-                config,
-                projectCallback);
-    }
-
-    /**
-     * Disposes the static {@link Resources#mSystem} to make sure we don't leave objects
-     * around that would prevent us from unloading the library.
-     */
-    public static void disposeSystem() {
-        if (Resources.mSystem instanceof BridgeResources) {
-            ((BridgeResources)(Resources.mSystem)).mContext = null;
-            ((BridgeResources)(Resources.mSystem)).mProjectCallback = null;
-        }
-        Resources.mSystem = null;
-    }
-
-    private BridgeResources(BridgeContext context, AssetManager assets, DisplayMetrics metrics,
-            Configuration config, IProjectCallback projectCallback) {
-        super(assets, metrics, config);
-        mContext = context;
-        mProjectCallback = projectCallback;
-    }
-
-    public BridgeTypedArray newTypeArray(int numEntries, boolean platformFile) {
-        return new BridgeTypedArray(this, mContext, numEntries, platformFile);
-    }
-
-    private Pair<String, ResourceValue> getResourceValue(int id, boolean[] platformResFlag_out) {
-        // first get the String related to this id in the framework
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
-
-        if (resourceInfo != null) {
-            platformResFlag_out[0] = true;
-            String attributeName = resourceInfo.getSecond();
-
-            return Pair.of(attributeName, mContext.getRenderResources().getFrameworkResource(
-                    resourceInfo.getFirst(), attributeName));
-        }
-
-        // didn't find a match in the framework? look in the project.
-        if (mProjectCallback != null) {
-            resourceInfo = mProjectCallback.resolveResourceId(id);
-
-            if (resourceInfo != null) {
-                platformResFlag_out[0] = false;
-                String attributeName = resourceInfo.getSecond();
-
-                return Pair.of(attributeName, mContext.getRenderResources().getProjectResource(
-                        resourceInfo.getFirst(), attributeName));
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public Drawable getDrawable(int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
-
-        if (value != null) {
-            return ResourceHelper.getDrawable(value.getSecond(), mContext);
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @Override
-    public int getColor(int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
-
-        if (value != null) {
-            try {
-                return ResourceHelper.getColor(value.getSecond().getValue());
-            } catch (NumberFormatException e) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, e.getMessage(), e,
-                        null /*data*/);
-                return 0;
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @Override
-    public ColorStateList getColorStateList(int id) throws NotFoundException {
-        Pair<String, ResourceValue> resValue = getResourceValue(id, mPlatformResourceFlag);
-
-        if (resValue != null) {
-            ColorStateList stateList = ResourceHelper.getColorStateList(resValue.getSecond(),
-                    mContext);
-            if (stateList != null) {
-                return stateList;
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @Override
-    public CharSequence getText(int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    return v;
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @Override
-    public XmlResourceParser getLayout(int id) throws NotFoundException {
-        Pair<String, ResourceValue> v = getResourceValue(id, mPlatformResourceFlag);
-
-        if (v != null) {
-            ResourceValue value = v.getSecond();
-            XmlPullParser parser = null;
-
-            try {
-                // check if the current parser can provide us with a custom parser.
-                if (mPlatformResourceFlag[0] == false) {
-                    parser = mProjectCallback.getParser(value);
-                }
-
-                // create a new one manually if needed.
-                if (parser == null) {
-                    File xml = new File(value.getValue());
-                    if (xml.isFile()) {
-                        // we need to create a pull parser around the layout XML file, and then
-                        // give that to our XmlBlockParser
-                        parser = ParserFactory.create(xml);
-                    }
-                }
-
-                if (parser != null) {
-                    return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
-                }
-            } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
-                // we'll return null below.
-            } catch (FileNotFoundException e) {
-                // this shouldn't happen since we check above.
-            }
-
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @Override
-    public XmlResourceParser getAnimation(int id) throws NotFoundException {
-        Pair<String, ResourceValue> v = getResourceValue(id, mPlatformResourceFlag);
-
-        if (v != null) {
-            ResourceValue value = v.getSecond();
-            XmlPullParser parser = null;
-
-            try {
-                File xml = new File(value.getValue());
-                if (xml.isFile()) {
-                    // we need to create a pull parser around the layout XML file, and then
-                    // give that to our XmlBlockParser
-                    parser = ParserFactory.create(xml);
-
-                    return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
-                }
-            } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
-                // we'll return null below.
-            } catch (FileNotFoundException e) {
-                // this shouldn't happen since we check above.
-            }
-
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @Override
-    public TypedArray obtainAttributes(AttributeSet set, int[] attrs) {
-        return mContext.obtainStyledAttributes(set, attrs);
-    }
-
-    @Override
-    public TypedArray obtainTypedArray(int id) throws NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-
-    @Override
-    public float getDimension(int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    if (v.equals(BridgeConstants.MATCH_PARENT) ||
-                            v.equals(BridgeConstants.FILL_PARENT)) {
-                        return LayoutParams.MATCH_PARENT;
-                    } else if (v.equals(BridgeConstants.WRAP_CONTENT)) {
-                        return LayoutParams.WRAP_CONTENT;
-                    }
-
-                    if (ResourceHelper.parseFloatAttribute(
-                            value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
-                            mTmpValue.type == TypedValue.TYPE_DIMENSION) {
-                        return mTmpValue.getDimension(getDisplayMetrics());
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @Override
-    public int getDimensionPixelOffset(int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    if (ResourceHelper.parseFloatAttribute(
-                            value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
-                            mTmpValue.type == TypedValue.TYPE_DIMENSION) {
-                        return TypedValue.complexToDimensionPixelOffset(mTmpValue.data,
-                                getDisplayMetrics());
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @Override
-    public int getDimensionPixelSize(int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    if (ResourceHelper.parseFloatAttribute(
-                            value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
-                            mTmpValue.type == TypedValue.TYPE_DIMENSION) {
-                        return TypedValue.complexToDimensionPixelSize(mTmpValue.data,
-                                getDisplayMetrics());
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @Override
-    public int getInteger(int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    int radix = 10;
-                    if (v.startsWith("0x")) {
-                        v = v.substring(2);
-                        radix = 16;
-                    }
-                    try {
-                        return Integer.parseInt(v, radix);
-                    } catch (NumberFormatException e) {
-                        // return exception below
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @Override
-    public boolean getBoolean(int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    return Boolean.parseBoolean(v);
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return false;
-    }
-
-    @Override
-    public String getResourceEntryName(int resid) throws NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getResourceName(int resid) throws NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getResourceTypeName(int resid) throws NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getString(int id, Object... formatArgs) throws NotFoundException {
-        String s = getString(id);
-        if (s != null) {
-            return String.format(s, formatArgs);
-
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @Override
-    public String getString(int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
-
-        if (value != null && value.getSecond().getValue() != null) {
-            return value.getSecond().getValue();
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @Override
-    public void getValue(int id, TypedValue outValue, boolean resolveRefs)
-            throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
-
-        if (value != null) {
-            String v = value.getSecond().getValue();
-
-            if (v != null) {
-                if (ResourceHelper.parseFloatAttribute(value.getFirst(), v, outValue,
-                        false /*requireUnit*/)) {
-                    return;
-                }
-
-                // else it's a string
-                outValue.type = TypedValue.TYPE_STRING;
-                outValue.string = v;
-                return;
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-    }
-
-    @Override
-    public void getValue(String name, TypedValue outValue, boolean resolveRefs)
-            throws NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public XmlResourceParser getXml(int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
-
-        if (value != null) {
-            String v = value.getSecond().getValue();
-
-            if (v != null) {
-                // check this is a file
-                File f = new File(v);
-                if (f.isFile()) {
-                    try {
-                        XmlPullParser parser = ParserFactory.create(f);
-
-                        return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
-                    } catch (XmlPullParserException e) {
-                        NotFoundException newE = new NotFoundException();
-                        newE.initCause(e);
-                        throw newE;
-                    } catch (FileNotFoundException e) {
-                        NotFoundException newE = new NotFoundException();
-                        newE.initCause(e);
-                        throw newE;
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @Override
-    public XmlResourceParser loadXmlResourceParser(String file, int id,
-            int assetCookie, String type) throws NotFoundException {
-        // even though we know the XML file to load directly, we still need to resolve the
-        // id so that we can know if it's a platform or project resource.
-        // (mPlatformResouceFlag will get the result and will be used later).
-        getResourceValue(id, mPlatformResourceFlag);
-
-        File f = new File(file);
-        try {
-            XmlPullParser parser = ParserFactory.create(f);
-
-            return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
-        } catch (XmlPullParserException e) {
-            NotFoundException newE = new NotFoundException();
-            newE.initCause(e);
-            throw newE;
-        } catch (FileNotFoundException e) {
-            NotFoundException newE = new NotFoundException();
-            newE.initCause(e);
-            throw newE;
-        }
-    }
-
-
-    @Override
-    public InputStream openRawResource(int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
-
-        if (value != null) {
-            String path = value.getSecond().getValue();
-
-            if (path != null) {
-                // check this is a file
-                File f = new File(path);
-                if (f.isFile()) {
-                    try {
-                        // if it's a nine-patch return a custom input stream so that
-                        // other methods (mainly bitmap factory) can detect it's a 9-patch
-                        // and actually load it as a 9-patch instead of a normal bitmap
-                        if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
-                            return new NinePatchInputStream(f);
-                        }
-                        return new FileInputStream(f);
-                    } catch (FileNotFoundException e) {
-                        NotFoundException newE = new NotFoundException();
-                        newE.initCause(e);
-                        throw newE;
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @Override
-    public InputStream openRawResource(int id, TypedValue value) throws NotFoundException {
-        getValue(id, value, true);
-
-        String path = value.string.toString();
-
-        File f = new File(path);
-        if (f.isFile()) {
-            try {
-                // if it's a nine-patch return a custom input stream so that
-                // other methods (mainly bitmap factory) can detect it's a 9-patch
-                // and actually load it as a 9-patch instead of a normal bitmap
-                if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
-                    return new NinePatchInputStream(f);
-                }
-                return new FileInputStream(f);
-            } catch (FileNotFoundException e) {
-                NotFoundException exception = new NotFoundException();
-                exception.initCause(e);
-                throw exception;
-            }
-        }
-
-        throw new NotFoundException();
-    }
-
-    @Override
-    public AssetFileDescriptor openRawResourceFd(int id) throws NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Builds and throws a {@link Resources.NotFoundException} based on a resource id and a resource type.
-     * @param id the id of the resource
-     * @throws NotFoundException
-     */
-    private void throwException(int id) throws NotFoundException {
-        // first get the String related to this id in the framework
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
-
-        // if the name is unknown in the framework, get it from the custom view loader.
-        if (resourceInfo == null && mProjectCallback != null) {
-            resourceInfo = mProjectCallback.resolveResourceId(id);
-        }
-
-        String message = null;
-        if (resourceInfo != null) {
-            message = String.format(
-                    "Could not find %1$s resource matching value 0x%2$X (resolved name: %3$s) in current configuration.",
-                    resourceInfo.getFirst(), id, resourceInfo.getSecond());
-        } else {
-            message = String.format(
-                    "Could not resolve resource value: 0x%1$X.", id);
-        }
-
-        throw new NotFoundException(message);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
deleted file mode 100644
index 446d139..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ /dev/null
@@ -1,908 +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.content.res;
-
-import com.android.ide.common.rendering.api.AttrResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.ResourceType;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.graphics.drawable.Drawable;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.LayoutInflater_Delegate;
-import android.view.ViewGroup.LayoutParams;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Map;
-
-/**
- * Custom implementation of TypedArray to handle non compiled resources.
- */
-public final class BridgeTypedArray extends TypedArray {
-
-    private final BridgeResources mBridgeResources;
-    private final BridgeContext mContext;
-    private final boolean mPlatformFile;
-
-    private ResourceValue[] mResourceData;
-    private String[] mNames;
-    private boolean[] mIsFramework;
-
-    public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len,
-            boolean platformFile) {
-        super(null, null, null, 0);
-        mBridgeResources = resources;
-        mContext = context;
-        mPlatformFile = platformFile;
-        mResourceData = new ResourceValue[len];
-        mNames = new String[len];
-        mIsFramework = new boolean[len];
-    }
-
-    /**
-     * A bridge-specific method that sets a value in the type array
-     * @param index the index of the value in the TypedArray
-     * @param name the name of the attribute
-     * @param isFramework whether the attribute is in the android namespace.
-     * @param value the value of the attribute
-     */
-    public void bridgeSetValue(int index, String name, boolean isFramework, ResourceValue value) {
-        mResourceData[index] = value;
-        mNames[index] = name;
-        mIsFramework[index] = isFramework;
-    }
-
-    /**
-     * Seals the array after all calls to {@link #bridgeSetValue(int, String, ResourceValue)} have
-     * been done.
-     * <p/>This allows to compute the list of non default values, permitting
-     * {@link #getIndexCount()} to return the proper value.
-     */
-    public void sealArray() {
-        // fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt
-        // first count the array size
-        int count = 0;
-        for (ResourceValue data : mResourceData) {
-            if (data != null) {
-                count++;
-            }
-        }
-
-        // allocate the table with an extra to store the size
-        mIndices = new int[count+1];
-        mIndices[0] = count;
-
-        // fill the array with the indices.
-        int index = 1;
-        for (int i = 0 ; i < mResourceData.length ; i++) {
-            if (mResourceData[i] != null) {
-                mIndices[index++] = i;
-            }
-        }
-    }
-
-    /**
-     * Return the number of values in this array.
-     */
-    @Override
-    public int length() {
-        return mResourceData.length;
-    }
-
-    /**
-     * Return the Resources object this array was loaded from.
-     */
-    @Override
-    public Resources getResources() {
-        return mBridgeResources;
-    }
-
-    /**
-     * Retrieve the styled string value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return CharSequence holding string data.  May be styled.  Returns
-     *         null if the attribute is not defined.
-     */
-    @Override
-    public CharSequence getText(int index) {
-        if (index < 0 || index >= mResourceData.length) {
-            return null;
-        }
-
-        if (mResourceData[index] != null) {
-            // FIXME: handle styled strings!
-            return mResourceData[index].getValue();
-        }
-
-        return null;
-    }
-
-    /**
-     * Retrieve the string value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return String holding string data.  Any styling information is
-     * removed.  Returns null if the attribute is not defined.
-     */
-    @Override
-    public String getString(int index) {
-        if (index < 0 || index >= mResourceData.length) {
-            return null;
-        }
-
-        if (mResourceData[index] != null) {
-            return mResourceData[index].getValue();
-        }
-
-        return null;
-    }
-
-    /**
-     * Retrieve the boolean value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined.
-     *
-     * @return Attribute boolean value, or defValue if not defined.
-     */
-    @Override
-    public boolean getBoolean(int index, boolean defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        if (mResourceData[index] == null) {
-            return defValue;
-        }
-
-        String s = mResourceData[index].getValue();
-        if (s != null) {
-            return XmlUtils.convertValueToBoolean(s, defValue);
-        }
-
-        return defValue;
-    }
-
-    /**
-     * Retrieve the integer value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined.
-     *
-     * @return Attribute int value, or defValue if not defined.
-     */
-    @Override
-    public int getInt(int index, int defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        if (mResourceData[index] == null) {
-            return defValue;
-        }
-
-        String s = mResourceData[index].getValue();
-
-        if (RenderResources.REFERENCE_NULL.equals(s)) {
-            return defValue;
-        }
-
-        if (s == null || s.length() == 0) {
-            return defValue;
-        }
-
-        try {
-            return XmlUtils.convertValueToInt(s, defValue);
-        } catch (NumberFormatException e) {
-            // pass
-        }
-
-        // Field is not null and is not an integer.
-        // Check for possible constants and try to find them.
-        // Get the map of attribute-constant -> IntegerValue
-        Map<String, Integer> map = null;
-        if (mIsFramework[index]) {
-            map = Bridge.getEnumValues(mNames[index]);
-        } else {
-            // get the styleable matching the resolved name
-            RenderResources res = mContext.getRenderResources();
-            ResourceValue attr = res.getProjectResource(ResourceType.ATTR, mNames[index]);
-            if (attr instanceof AttrResourceValue) {
-                map = ((AttrResourceValue) attr).getAttributeValues();
-            }
-        }
-
-        if (map != null) {
-            // accumulator to store the value of the 1+ constants.
-            int result = 0;
-
-            // split the value in case this is a mix of several flags.
-            String[] keywords = s.split("\\|");
-            for (String keyword : keywords) {
-                Integer i = map.get(keyword.trim());
-                if (i != null) {
-                    result |= i.intValue();
-                } else {
-                    Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                            String.format(
-                                "\"%s\" in attribute \"%2$s\" is not a valid value",
-                                keyword, mNames[index]), null /*data*/);
-                }
-            }
-            return result;
-        }
-
-        return defValue;
-    }
-
-    /**
-     * Retrieve the float value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Attribute float value, or defValue if not defined..
-     */
-    @Override
-    public float getFloat(int index, float defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        if (mResourceData[index] == null) {
-            return defValue;
-        }
-
-        String s = mResourceData[index].getValue();
-
-        if (s != null) {
-            try {
-                return Float.parseFloat(s);
-            } catch (NumberFormatException e) {
-                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                        String.format(
-                            "\"%s\" in attribute \"%2$s\" cannot be converted to float.",
-                            s, mNames[index]), null /*data*/);
-
-                // we'll return the default value below.
-            }
-        }
-        return defValue;
-    }
-
-    /**
-     * Retrieve the color value for the attribute at <var>index</var>.  If
-     * the attribute references a color resource holding a complex
-     * {@link android.content.res.ColorStateList}, then the default color from
-     * the set is returned.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute color value, or defValue if not defined.
-     */
-    @Override
-    public int getColor(int index, int defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        if (mResourceData[index] == null) {
-            return defValue;
-        }
-
-        ColorStateList colorStateList = ResourceHelper.getColorStateList(
-                mResourceData[index], mContext);
-        if (colorStateList != null) {
-            return colorStateList.getDefaultColor();
-        }
-
-        return defValue;
-    }
-
-    /**
-     * Retrieve the ColorStateList for the attribute at <var>index</var>.
-     * The value may be either a single solid color or a reference to
-     * a color or complex {@link android.content.res.ColorStateList} description.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return ColorStateList for the attribute, or null if not defined.
-     */
-    @Override
-    public ColorStateList getColorStateList(int index) {
-        if (index < 0 || index >= mResourceData.length) {
-            return null;
-        }
-
-        if (mResourceData[index] == null) {
-            return null;
-        }
-
-        ResourceValue resValue = mResourceData[index];
-        String value = resValue.getValue();
-
-        if (value == null) {
-            return null;
-        }
-
-        if (RenderResources.REFERENCE_NULL.equals(value)) {
-            return null;
-        }
-
-        // let the framework inflate the ColorStateList from the XML file.
-        File f = new File(value);
-        if (f.isFile()) {
-            try {
-                XmlPullParser parser = ParserFactory.create(f);
-
-                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                        parser, mContext, resValue.isFramework());
-                try {
-                    return ColorStateList.createFromXml(mContext.getResources(), blockParser);
-                } finally {
-                    blockParser.ensurePopped();
-                }
-            } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to configure parser for " + value, e, null /*data*/);
-                return null;
-            } catch (Exception e) {
-                // this is an error and not warning since the file existence is checked before
-                // attempting to parse it.
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                        "Failed to parse file " + value, e, null /*data*/);
-
-                return null;
-            }
-        }
-
-        try {
-            int color = ResourceHelper.getColor(value);
-            return ColorStateList.valueOf(color);
-        } catch (NumberFormatException e) {
-            Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, e.getMessage(), e, null /*data*/);
-        }
-
-        return null;
-    }
-
-    /**
-     * Retrieve the integer value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute integer value, or defValue if not defined.
-     */
-    @Override
-    public int getInteger(int index, int defValue) {
-        return getInt(index, defValue);
-    }
-
-    /**
-     * Retrieve a dimensional unit attribute at <var>index</var>.  Unit
-     * conversions are based on the current {@link DisplayMetrics}
-     * associated with the resources this {@link TypedArray} object
-     * came from.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric, or defValue if not defined.
-     *
-     * @see #getDimensionPixelOffset
-     * @see #getDimensionPixelSize
-     */
-    @Override
-    public float getDimension(int index, float defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        if (mResourceData[index] == null) {
-            return defValue;
-        }
-
-        String s = mResourceData[index].getValue();
-
-        if (s == null) {
-            return defValue;
-        } else if (s.equals(BridgeConstants.MATCH_PARENT) ||
-                s.equals(BridgeConstants.FILL_PARENT)) {
-            return LayoutParams.MATCH_PARENT;
-        } else if (s.equals(BridgeConstants.WRAP_CONTENT)) {
-            return LayoutParams.WRAP_CONTENT;
-        } else if (RenderResources.REFERENCE_NULL.equals(s)) {
-            return defValue;
-        }
-
-        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true /*requireUnit*/)) {
-            return mValue.getDimension(mBridgeResources.getDisplayMetrics());
-        }
-
-        // looks like we were unable to resolve the dimension value
-        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                String.format(
-                    "\"%1$s\" in attribute \"%2$s\" is not a valid format.",
-                    s, mNames[index]), null /*data*/);
-
-        return defValue;
-    }
-
-    /**
-     * Retrieve a dimensional unit attribute at <var>index</var> for use
-     * as an offset in raw pixels.  This is the same as
-     * {@link #getDimension}, except the returned value is converted to
-     * integer pixels for you.  An offset conversion involves simply
-     * truncating the base value to an integer.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric and truncated to integer pixels, or defValue if not defined.
-     *
-     * @see #getDimension
-     * @see #getDimensionPixelSize
-     */
-    @Override
-    public int getDimensionPixelOffset(int index, int defValue) {
-        return (int) getDimension(index, defValue);
-    }
-
-    /**
-     * Retrieve a dimensional unit attribute at <var>index</var> for use
-     * as a size in raw pixels.  This is the same as
-     * {@link #getDimension}, except the returned value is converted to
-     * integer pixels for use as a size.  A size conversion involves
-     * rounding the base value, and ensuring that a non-zero base value
-     * is at least one pixel in size.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric and truncated to integer pixels, or defValue if not defined.
-     *
-     * @see #getDimension
-     * @see #getDimensionPixelOffset
-     */
-    @Override
-    public int getDimensionPixelSize(int index, int defValue) {
-        try {
-            return getDimension(index);
-        } catch (RuntimeException e) {
-            if (mResourceData[index] != null) {
-                String s = mResourceData[index].getValue();
-
-                if (s != null) {
-                    // looks like we were unable to resolve the dimension value
-                    Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                            String.format(
-                                "\"%1$s\" in attribute \"%2$s\" is not a valid format.",
-                                s, mNames[index]), null /*data*/);
-                }
-            }
-
-            return defValue;
-        }
-    }
-
-    /**
-     * Special version of {@link #getDimensionPixelSize} for retrieving
-     * {@link android.view.ViewGroup}'s layout_width and layout_height
-     * attributes.  This is only here for performance reasons; applications
-     * should use {@link #getDimensionPixelSize}.
-     *
-     * @param index Index of the attribute to retrieve.
-     * @param name Textual name of attribute for error reporting.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric and truncated to integer pixels.
-     */
-    @Override
-    public int getLayoutDimension(int index, String name) {
-        try {
-            // this will throw an exception
-            return getDimension(index);
-        } catch (RuntimeException e) {
-
-            if (LayoutInflater_Delegate.sIsInInclude) {
-                throw new RuntimeException();
-            }
-
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                    "You must supply a " + name + " attribute.", null);
-
-            return 0;
-        }
-    }
-
-    @Override
-    public int getLayoutDimension(int index, int defValue) {
-        return getDimensionPixelSize(index, defValue);
-    }
-
-    private int getDimension(int index) {
-        if (mResourceData[index] == null) {
-            throw new RuntimeException();
-        }
-
-        String s = mResourceData[index].getValue();
-
-        if (s == null) {
-            throw new RuntimeException();
-        } else if (s.equals(BridgeConstants.MATCH_PARENT) ||
-                s.equals(BridgeConstants.FILL_PARENT)) {
-            return LayoutParams.MATCH_PARENT;
-        } else if (s.equals(BridgeConstants.WRAP_CONTENT)) {
-            return LayoutParams.WRAP_CONTENT;
-        } else if (RenderResources.REFERENCE_NULL.equals(s)) {
-            throw new RuntimeException();
-        }
-
-        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true /*requireUnit*/)) {
-            float f = mValue.getDimension(mBridgeResources.getDisplayMetrics());
-
-            final int res = (int)(f+0.5f);
-            if (res != 0) return res;
-            if (f == 0) return 0;
-            if (f > 0) return 1;
-        }
-
-        throw new RuntimeException();
-    }
-
-    /**
-     * Retrieve a fractional unit attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param base The base value of this fraction.  In other words, a
-     *             standard fraction is multiplied by this value.
-     * @param pbase The parent base value of this fraction.  In other
-     *             words, a parent fraction (nn%p) is multiplied by this
-     *             value.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute fractional value multiplied by the appropriate
-     * base value, or defValue if not defined.
-     */
-    @Override
-    public float getFraction(int index, int base, int pbase, float defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        if (mResourceData[index] == null) {
-            return defValue;
-        }
-
-        String value = mResourceData[index].getValue();
-        if (value == null) {
-            return defValue;
-        }
-
-        if (ResourceHelper.parseFloatAttribute(mNames[index], value, mValue,
-                false /*requireUnit*/)) {
-            return mValue.getFraction(base, pbase);
-        }
-
-        // looks like we were unable to resolve the fraction value
-        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                String.format(
-                    "\"%1$s\" in attribute \"%2$s\" cannot be converted to a fraction.",
-                    value, mNames[index]), null /*data*/);
-
-        return defValue;
-    }
-
-    /**
-     * Retrieve the resource identifier for the attribute at
-     * <var>index</var>.  Note that attribute resource as resolved when
-     * the overall {@link TypedArray} object is retrieved.  As a
-     * result, this function will return the resource identifier of the
-     * final resource value that was found, <em>not</em> necessarily the
-     * original resource that was specified by the attribute.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute resource identifier, or defValue if not defined.
-     */
-    @Override
-    public int getResourceId(int index, int defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        // get the Resource for this index
-        ResourceValue resValue = mResourceData[index];
-
-        // no data, return the default value.
-        if (resValue == null) {
-            return defValue;
-        }
-
-        // check if this is a style resource
-        if (resValue instanceof StyleResourceValue) {
-            // get the id that will represent this style.
-            return mContext.getDynamicIdByStyle((StyleResourceValue)resValue);
-        }
-
-        if (RenderResources.REFERENCE_NULL.equals(resValue.getValue())) {
-            return defValue;
-        }
-
-        // if the attribute was a reference to a resource, and not a declaration of an id (@+id),
-        // then the xml attribute value was "resolved" which leads us to a ResourceValue with a
-        // valid getType() and getName() returning a resource name.
-        // (and getValue() returning null!). We need to handle this!
-        if (resValue.getResourceType() != null) {
-            // if this is a framework id
-            if (mPlatformFile || resValue.isFramework()) {
-                // look for idName in the android R classes
-                return mContext.getFrameworkResourceValue(
-                        resValue.getResourceType(), resValue.getName(), defValue);
-            }
-
-            // look for idName in the project R class.
-            return mContext.getProjectResourceValue(
-                    resValue.getResourceType(), resValue.getName(), defValue);
-        }
-
-        // else, try to get the value, and resolve it somehow.
-        String value = resValue.getValue();
-        if (value == null) {
-            return defValue;
-        }
-
-        // if the value is just an integer, return it.
-        try {
-            int i = Integer.parseInt(value);
-            if (Integer.toString(i).equals(value)) {
-                return i;
-            }
-        } catch (NumberFormatException e) {
-            // pass
-        }
-
-        // Handle the @id/<name>, @+id/<name> and @android:id/<name>
-        // We need to return the exact value that was compiled (from the various R classes),
-        // as these values can be reused internally with calls to findViewById().
-        // There's a trick with platform layouts that not use "android:" but their IDs are in
-        // fact in the android.R and com.android.internal.R classes.
-        // The field mPlatformFile will indicate that all IDs are to be looked up in the android R
-        // classes exclusively.
-
-        // if this is a reference to an id, find it.
-        if (value.startsWith("@id/") || value.startsWith("@+") ||
-                value.startsWith("@android:id/")) {
-
-            int pos = value.indexOf('/');
-            String idName = value.substring(pos + 1);
-
-            // if this is a framework id
-            if (mPlatformFile || value.startsWith("@android") || value.startsWith("@+android")) {
-                // look for idName in the android R classes
-                return mContext.getFrameworkResourceValue(ResourceType.ID, idName, defValue);
-            }
-
-            // look for idName in the project R class.
-            return mContext.getProjectResourceValue(ResourceType.ID, idName, defValue);
-        }
-
-        // not a direct id valid reference? resolve it
-        Integer idValue = null;
-
-        if (resValue.isFramework()) {
-            idValue = Bridge.getResourceId(resValue.getResourceType(),
-                    resValue.getName());
-        } else {
-            idValue = mContext.getProjectCallback().getResourceId(
-                    resValue.getResourceType(), resValue.getName());
-        }
-
-        if (idValue != null) {
-            return idValue.intValue();
-        }
-
-        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE,
-                String.format(
-                    "Unable to resolve id \"%1$s\" for attribute \"%2$s\"", value, mNames[index]),
-                    resValue);
-
-        return defValue;
-    }
-
-    /**
-     * Retrieve the Drawable for the attribute at <var>index</var>.  This
-     * gets the resource ID of the selected attribute, and uses
-     * {@link Resources#getDrawable Resources.getDrawable} of the owning
-     * Resources object to retrieve its Drawable.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Drawable for the attribute, or null if not defined.
-     */
-    @Override
-    public Drawable getDrawable(int index) {
-        if (index < 0 || index >= mResourceData.length) {
-            return null;
-        }
-
-        if (mResourceData[index] == null) {
-            return null;
-        }
-
-        ResourceValue value = mResourceData[index];
-        String stringValue = value.getValue();
-        if (stringValue == null || RenderResources.REFERENCE_NULL.equals(stringValue)) {
-            return null;
-        }
-
-        return ResourceHelper.getDrawable(value, mContext);
-    }
-
-
-    /**
-     * Retrieve the CharSequence[] for the attribute at <var>index</var>.
-     * This gets the resource ID of the selected attribute, and uses
-     * {@link Resources#getTextArray Resources.getTextArray} of the owning
-     * Resources object to retrieve its String[].
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return CharSequence[] for the attribute, or null if not defined.
-     */
-    @Override
-    public CharSequence[] getTextArray(int index) {
-        if (index < 0 || index >= mResourceData.length) {
-            return null;
-        }
-
-        if (mResourceData[index] == null) {
-            return null;
-        }
-
-        String value = mResourceData[index].getValue();
-        if (value != null) {
-            if (RenderResources.REFERENCE_NULL.equals(value)) {
-                return null;
-            }
-
-            return new CharSequence[] { value };
-        }
-
-        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                String.format(
-                    String.format("Unknown value for getTextArray(%d) => %s", //DEBUG
-                    index, mResourceData[index].getName())), null /*data*/);
-
-        return null;
-    }
-
-    /**
-     * Retrieve the raw TypedValue for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param outValue TypedValue object in which to place the attribute's
-     *                 data.
-     *
-     * @return Returns true if the value was retrieved, else false.
-     */
-    @Override
-    public boolean getValue(int index, TypedValue outValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return false;
-        }
-
-        if (mResourceData[index] == null) {
-            return false;
-        }
-
-        String s = mResourceData[index].getValue();
-
-        return ResourceHelper.parseFloatAttribute(mNames[index], s, outValue,
-                false /*requireUnit*/);
-    }
-
-    /**
-     * Determines whether there is an attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return True if the attribute has a value, false otherwise.
-     */
-    @Override
-    public boolean hasValue(int index) {
-        if (index < 0 || index >= mResourceData.length) {
-            return false;
-        }
-
-        return mResourceData[index] != null;
-    }
-
-    /**
-     * Retrieve the raw TypedValue for the attribute at <var>index</var>
-     * and return a temporary object holding its data.  This object is only
-     * valid until the next call on to {@link TypedArray}.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Returns a TypedValue object if the attribute is defined,
-     *         containing its data; otherwise returns null.  (You will not
-     *         receive a TypedValue whose type is TYPE_NULL.)
-     */
-    @Override
-    public TypedValue peekValue(int index) {
-        if (index < 0 || index >= mResourceData.length) {
-            return null;
-        }
-
-        if (getValue(index, mValue)) {
-            return mValue;
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a message about the parser state suitable for printing error messages.
-     */
-    @Override
-    public String getPositionDescription() {
-        return "<internal -- stub if needed>";
-    }
-
-    /**
-     * Give back a previously retrieved TypedArray, for later re-use.
-     */
-    @Override
-    public void recycle() {
-        // pass
-    }
-
-    @Override
-    public String toString() {
-        return Arrays.toString(mResourceData);
-    }
- }
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
deleted file mode 100644
index c9d615c..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.res.Resources.NotFoundException;
-import android.content.res.Resources.Theme;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Resources$Theme}
- *
- * Through the layoutlib_create tool, the original  methods of Theme have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class Resources_Theme_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtainStyledAttributes(
-            Resources thisResources, Theme thisTheme,
-            int[] attrs) {
-        return RenderSessionImpl.getCurrentContext().obtainStyledAttributes(attrs);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtainStyledAttributes(
-            Resources thisResources, Theme thisTheme,
-            int resid, int[] attrs)
-            throws NotFoundException {
-        return RenderSessionImpl.getCurrentContext().obtainStyledAttributes(resid, attrs);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtainStyledAttributes(
-            Resources thisResources, Theme thisTheme,
-            AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
-        return RenderSessionImpl.getCurrentContext().obtainStyledAttributes(
-                set, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean resolveAttribute(
-            Resources thisResources, Theme thisTheme,
-            int resid, TypedValue outValue,
-            boolean resolveRefs) {
-        return RenderSessionImpl.getCurrentContext().resolveThemeAttribute(
-                resid, outValue, resolveRefs);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java
deleted file mode 100644
index 0a7899a..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.TypedValue;
-
-public class TypedArray_Delegate {
-
-    @LayoutlibDelegate
-    public static boolean getValueAt(TypedArray theTypedArray, int index, TypedValue outValue) {
-        // pass
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java
deleted file mode 100644
index a50a2bd..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Composite;
-
-/**
- * Delegate implementing the native methods of android.graphics.AvoidXfermode
- *
- * Through the layoutlib_create tool, the original native methods of AvoidXfermode have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original AvoidXfermode class.
- *
- * Because this extends {@link Xfermode_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
- * {@link Xfermode_Delegate}.
- *
- */
-public class AvoidXfermode_Delegate extends Xfermode_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Composite getComposite(int alpha) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Avoid Xfermodes are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate(int opColor, int tolerance, int nativeMode) {
-        AvoidXfermode_Delegate newDelegate = new AvoidXfermode_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
deleted file mode 100644
index 62d0a0d..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
+++ /dev/null
@@ -1,215 +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.graphics;
-
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphVector;
-import java.util.LinkedList;
-import java.util.List;
-
-import com.ibm.icu.lang.UScript;
-import com.ibm.icu.lang.UScriptRun;
-
-import android.graphics.Paint_Delegate.FontInfo;
-
-/**
- * Render the text by breaking it into various scripts and using the right font for each script.
- * Can be used to measure the text without actually drawing it.
- */
-@SuppressWarnings("deprecation")
-public class BidiRenderer {
-
-    /* package */ static class ScriptRun {
-        int start;
-        int limit;
-        boolean isRtl;
-        int scriptCode;
-        FontInfo font;
-
-        public ScriptRun(int start, int limit, boolean isRtl) {
-            this.start = start;
-            this.limit = limit;
-            this.isRtl = isRtl;
-            this.scriptCode = UScript.INVALID_CODE;
-        }
-    }
-
-    /* package */ Graphics2D graphics;
-    /* package */ Paint_Delegate paint;
-    /* package */ char[] text;
-
-    /**
-     * @param graphics May be null.
-     * @param paint The Paint to use to get the fonts. Should not be null.
-     * @param text Unidirectional text. Should not be null.
-     */
-    /* package */ BidiRenderer(Graphics2D graphics, Paint_Delegate paint, char[] text) {
-        assert (paint != null);
-        this.graphics = graphics;
-        this.paint = paint;
-        this.text = text;
-    }
-
-    /**
-     * Render unidirectional text.
-     *
-     * This method can also be used to measure the width of the text without actually drawing it.
-     *
-     * @param start index of the first character
-     * @param limit index of the first character that should not be rendered.
-     * @param isRtl is the text right-to-left
-     * @param advances If not null, then advances for each character to be rendered are returned
-     *            here.
-     * @param advancesIndex index into advances from where the advances need to be filled.
-     * @param draw If true and {@link graphics} is not null, draw the rendered text on the graphics
-     *            at the given co-ordinates
-     * @param x The x-coordinate of the left edge of where the text should be drawn on the given
-     *            graphics.
-     * @param y The y-coordinate at which to draw the text on the given graphics.
-     * @return The x-coordinate of the right edge of the drawn text. In other words,
-     *            x + the width of the text.
-     */
-    /* package */ float renderText(int start, int limit, boolean isRtl, float advances[],
-            int advancesIndex, boolean draw, float x, float y) {
-        // We break the text into scripts and then select font based on it and then render each of
-        // the script runs.
-        for (ScriptRun run : getScriptRuns(text, start, limit, isRtl, paint.getFonts())) {
-            int flag = Font.LAYOUT_NO_LIMIT_CONTEXT | Font.LAYOUT_NO_START_CONTEXT;
-            flag |= isRtl ? Font.LAYOUT_RIGHT_TO_LEFT : Font.LAYOUT_LEFT_TO_RIGHT;
-            x = renderScript(run.start, run.limit, run.font, flag, advances, advancesIndex, draw,
-                    x, y);
-            advancesIndex += run.limit - run.start;
-        }
-        return x;
-    }
-
-    /**
-     * Render a script run. Use the preferred font to render as much as possible. This also
-     * implements a fallback mechanism to render characters that cannot be drawn using the
-     * preferred font.
-     *
-     * @return x + width of the text drawn.
-     */
-    private float renderScript(int start, int limit, FontInfo preferredFont, int flag,
-            float advances[], int advancesIndex, boolean draw, float x, float y) {
-        List<FontInfo> fonts = paint.getFonts();
-        if (fonts == null || preferredFont == null) {
-            return x;
-        }
-
-        while (start < limit) {
-            boolean foundFont = false;
-            int canDisplayUpTo = preferredFont.mFont.canDisplayUpTo(text, start, limit);
-            if (canDisplayUpTo == -1) {
-                return render(start, limit, preferredFont, flag, advances, advancesIndex, draw,
-                        x, y);
-            } else if (canDisplayUpTo > start) { // can draw something
-                x = render(start, canDisplayUpTo, preferredFont, flag, advances, advancesIndex,
-                        draw, x, y);
-                advancesIndex += canDisplayUpTo - start;
-                start = canDisplayUpTo;
-            }
-
-            int charCount = Character.isHighSurrogate(text[start]) ? 2 : 1;
-            for (FontInfo font : fonts) {
-                canDisplayUpTo = font.mFont.canDisplayUpTo(text, start, start + charCount);
-                if (canDisplayUpTo == -1) {
-                    x = render(start, start+charCount, font, flag, advances, advancesIndex, draw,
-                            x, y);
-                    start += charCount;
-                    advancesIndex += charCount;
-                    foundFont = true;
-                    break;
-                }
-            }
-            if (!foundFont) {
-                // No font can display this char. Use the preferred font. The char will most
-                // probably appear as a box or a blank space. We could, probably, use some
-                // heuristics and break the character into the base character and diacritics and
-                // then draw it, but it's probably not worth the effort.
-                x = render(start, start + charCount, preferredFont, flag, advances, advancesIndex,
-                        draw, x, y);
-                start += charCount;
-                advancesIndex += charCount;
-            }
-        }
-        return x;
-    }
-
-    /**
-     * Render the text with the given font.
-     */
-    private float render(int start, int limit, FontInfo font, int flag, float advances[],
-            int advancesIndex, boolean draw, float x, float y) {
-
-        float totalAdvance = 0;
-        // Since the metrics don't have anti-aliasing set, we create a new FontRenderContext with
-        // the anti-aliasing set.
-        FontRenderContext f = font.mMetrics.getFontRenderContext();
-        FontRenderContext frc = new FontRenderContext(f.getTransform(), paint.isAntiAliased(),
-                f.usesFractionalMetrics());
-        GlyphVector gv = font.mFont.layoutGlyphVector(frc, text, start, limit, flag);
-        int ng = gv.getNumGlyphs();
-        int[] ci = gv.getGlyphCharIndices(0, ng, null);
-        for (int i = 0; i < ng; i++) {
-            float adv = gv.getGlyphMetrics(i).getAdvanceX();
-            if (advances != null) {
-                int adv_idx = advancesIndex + ci[i];
-                advances[adv_idx] += adv;
-            }
-            totalAdvance += adv;
-        }
-        if (draw && graphics != null) {
-            graphics.drawGlyphVector(gv, x, y);
-        }
-        return x + totalAdvance;
-    }
-
-    // --- Static helper methods ---
-
-    /* package */  static List<ScriptRun> getScriptRuns(char[] text, int start, int limit,
-            boolean isRtl, List<FontInfo> fonts) {
-        LinkedList<ScriptRun> scriptRuns = new LinkedList<ScriptRun>();
-
-        int count = limit - start;
-        UScriptRun uScriptRun = new UScriptRun(text, start, count);
-        while (uScriptRun.next()) {
-            int scriptStart = uScriptRun.getScriptStart();
-            int scriptLimit = uScriptRun.getScriptLimit();
-            ScriptRun run = new ScriptRun(scriptStart, scriptLimit, isRtl);
-            run.scriptCode = uScriptRun.getScriptCode();
-            setScriptFont(text, run, fonts);
-            scriptRuns.add(run);
-        }
-
-        return scriptRuns;
-    }
-
-    // TODO: Replace this method with one which returns the font based on the scriptCode.
-    private static void setScriptFont(char[] text, ScriptRun run,
-            List<FontInfo> fonts) {
-        for (FontInfo fontInfo : fonts) {
-            if (fontInfo.mFont.canDisplayUpTo(text, run.start, run.limit) == -1) {
-                run.font = fontInfo;
-                return;
-            }
-        }
-        run.font = fonts.get(0);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
deleted file mode 100644
index 04ce9d0..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
+++ /dev/null
@@ -1,184 +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.graphics;
-
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.resources.Density;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.res.BridgeResources.NinePatchInputStream;
-import android.graphics.BitmapFactory.Options;
-import android.graphics.Bitmap_Delegate.BitmapCreateFlags;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.EnumSet;
-import java.util.Set;
-
-/**
- * Delegate implementing the native methods of android.graphics.BitmapFactory
- *
- * Through the layoutlib_create tool, the original native methods of BitmapFactory have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-/*package*/ class BitmapFactory_Delegate {
-
-    // ------ Java delegates ------
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap finishDecode(Bitmap bm, Rect outPadding, Options opts) {
-        if (bm == null || opts == null) {
-            return bm;
-        }
-
-        final int density = opts.inDensity;
-        if (density == 0) {
-            return bm;
-        }
-
-        bm.setDensity(density);
-        final int targetDensity = opts.inTargetDensity;
-        if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
-            return bm;
-        }
-
-        byte[] np = bm.getNinePatchChunk();
-        final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
-        // DELEGATE CHANGE: never scale 9-patch
-        if (opts.inScaled && isNinePatch == false) {
-            float scale = targetDensity / (float)density;
-            // TODO: This is very inefficient and should be done in native by Skia
-            final Bitmap oldBitmap = bm;
-            bm = Bitmap.createScaledBitmap(oldBitmap, (int) (bm.getWidth() * scale + 0.5f),
-                    (int) (bm.getHeight() * scale + 0.5f), true);
-            oldBitmap.recycle();
-
-            if (isNinePatch) {
-                np = nativeScaleNinePatch(np, scale, outPadding);
-                bm.setNinePatchChunk(np);
-            }
-            bm.setDensity(targetDensity);
-        }
-
-        return bm;
-    }
-
-
-    // ------ Native Delegates ------
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
-            Rect padding, Options opts) {
-        return nativeDecodeStream(is, storage, padding, opts, false, 1.f);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static  Bitmap nativeDecodeStream(InputStream is, byte[] storage,
-            Rect padding, Options opts, boolean applyScale, float scale) {
-        Bitmap bm = null;
-
-        //TODO support rescaling
-
-        Density density = Density.MEDIUM;
-        Set<BitmapCreateFlags> bitmapCreateFlags = EnumSet.of(BitmapCreateFlags.MUTABLE);
-        if (opts != null) {
-            density = Density.getEnum(opts.inDensity);
-            if (opts.inPremultiplied) {
-                bitmapCreateFlags.add(BitmapCreateFlags.PREMULTIPLIED);
-            }
-        }
-
-        try {
-            if (is instanceof NinePatchInputStream) {
-                NinePatchInputStream npis = (NinePatchInputStream) is;
-                npis.disableFakeMarkSupport();
-
-                // load the bitmap as a nine patch
-                com.android.ninepatch.NinePatch ninePatch = com.android.ninepatch.NinePatch.load(
-                        npis, true /*is9Patch*/, false /*convert*/);
-
-                // get the bitmap and chunk objects.
-                bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), bitmapCreateFlags,
-                        density);
-                NinePatchChunk chunk = ninePatch.getChunk();
-
-                // put the chunk in the bitmap
-                bm.setNinePatchChunk(NinePatch_Delegate.serialize(chunk));
-
-                // read the padding
-                int[] paddingarray = chunk.getPadding();
-                padding.left = paddingarray[0];
-                padding.top = paddingarray[1];
-                padding.right = paddingarray[2];
-                padding.bottom = paddingarray[3];
-            } else {
-                // load the bitmap directly.
-                bm = Bitmap_Delegate.createBitmap(is, bitmapCreateFlags, density);
-            }
-        } catch (IOException e) {
-            Bridge.getLog().error(null,"Failed to load image" , e, null);
-        }
-
-        return bm;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
-            Rect padding, Options opts) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts,
-            boolean applyScale, float scale) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeByteArray(byte[] data, int offset,
-            int length, Options opts) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad) {
-        // don't scale for now. This should not be called anyway since we re-implement
-        // BitmapFactory.finishDecode();
-        return chunk;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeIsSeekable(FileDescriptor fd) {
-        return true;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
deleted file mode 100644
index 65a75b0..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-/**
- * Delegate implementing the native methods of android.graphics.BitmapShader
- *
- * Through the layoutlib_create tool, the original native methods of BitmapShader have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original BitmapShader class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class BitmapShader_Delegate extends Shader_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // no message since isSupported returns true;
-        return null;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate(int native_bitmap, int shaderTileModeX,
-            int shaderTileModeY) {
-        Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(native_bitmap);
-        if (bitmap == null) {
-            return 0;
-        }
-
-        BitmapShader_Delegate newDelegate = new BitmapShader_Delegate(
-                bitmap.getImage(),
-                Shader_Delegate.getTileMode(shaderTileModeX),
-                Shader_Delegate.getTileMode(shaderTileModeY));
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativePostCreate(int native_shader, int native_bitmap,
-            int shaderTileModeX, int shaderTileModeY) {
-        // pass, not needed.
-        return 0;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private BitmapShader_Delegate(java.awt.image.BufferedImage image,
-            TileMode tileModeX, TileMode tileModeY) {
-        mJavaPaint = new BitmapShaderPaint(image, tileModeX, tileModeY);
-    }
-
-    private class BitmapShaderPaint implements java.awt.Paint {
-        private final java.awt.image.BufferedImage mImage;
-        private final TileMode mTileModeX;
-        private final TileMode mTileModeY;
-
-        BitmapShaderPaint(java.awt.image.BufferedImage image,
-                TileMode tileModeX, TileMode tileModeY) {
-            mImage = image;
-            mTileModeX = tileModeX;
-            mTileModeY = tileModeY;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel      colorModel,
-                java.awt.Rectangle             deviceBounds,
-                java.awt.geom.Rectangle2D      userBounds,
-                java.awt.geom.AffineTransform  xform,
-                java.awt.RenderingHints        hints) {
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in BitmapShader", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in BitmapShader", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new BitmapShaderContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class BitmapShaderContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            public BitmapShaderContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel;
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
-                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
-
-                int[] data = new int[w*h];
-
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix.
-                        pt1[0] = pt2[0];
-                        pt1[1] = pt2[1];
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        data[index++] = getColor(pt2[0], pt2[1]);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-        }
-
-        /**
-         * Returns a color for an arbitrary point.
-         */
-        private int getColor(float fx, float fy) {
-            int x = getCoordinate(Math.round(fx), mImage.getWidth(), mTileModeX);
-            int y = getCoordinate(Math.round(fy), mImage.getHeight(), mTileModeY);
-
-            return mImage.getRGB(x, y);
-        }
-
-        private int getCoordinate(int i, int size, TileMode mode) {
-            if (i < 0) {
-                switch (mode) {
-                    case CLAMP:
-                        i = 0;
-                        break;
-                    case REPEAT:
-                        i = size - 1 - (-i % size);
-                        break;
-                    case MIRROR:
-                        // this is the same as the positive side, just make the value positive
-                        // first.
-                        i = -i;
-                        int count = i / size;
-                        i = i % size;
-
-                        if ((count % 2) == 1) {
-                            i = size - 1 - i;
-                        }
-                        break;
-                }
-            } else if (i >= size) {
-                switch (mode) {
-                    case CLAMP:
-                        i = size - 1;
-                        break;
-                    case REPEAT:
-                        i = i % size;
-                        break;
-                    case MIRROR:
-                        int count = i / size;
-                        i = i % size;
-
-                        if ((count % 2) == 1) {
-                            i = size - 1 - i;
-                        }
-                        break;
-                }
-            }
-
-            return i;
-        }
-
-
-        @Override
-        public int getTransparency() {
-            return java.awt.Paint.TRANSLUCENT;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
deleted file mode 100644
index 93284db..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.resources.Density;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Bitmap.Config;
-import android.os.Parcel;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.Buffer;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.Set;
-
-import javax.imageio.ImageIO;
-
-/**
- * Delegate implementing the native methods of android.graphics.Bitmap
- *
- * Through the layoutlib_create tool, the original native methods of Bitmap have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Bitmap class.
- *
- * @see DelegateManager
- *
- */
-public final class Bitmap_Delegate {
-
-    public enum BitmapCreateFlags {
-        PREMULTIPLIED, MUTABLE
-    }
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Bitmap_Delegate> sManager =
-            new DelegateManager<Bitmap_Delegate>(Bitmap_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-    private final Config mConfig;
-    private BufferedImage mImage;
-    private boolean mHasAlpha = true;
-    private boolean mHasMipMap = false;      // TODO: check the default.
-    private int mGenerationId = 0;
-
-
-    // ---- Public Helper methods ----
-
-    /**
-     * Returns the native delegate associated to a given {@link Bitmap_Delegate} object.
-     */
-    public static Bitmap_Delegate getDelegate(Bitmap bitmap) {
-        return sManager.getDelegate(bitmap.mNativeBitmap);
-    }
-
-    /**
-     * Returns the native delegate associated to a given an int referencing a {@link Bitmap} object.
-     */
-    public static Bitmap_Delegate getDelegate(int native_bitmap) {
-        return sManager.getDelegate(native_bitmap);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given file content.
-     *
-     * @param input the file from which to read the bitmap content
-     * @param isMutable whether the bitmap is mutable
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(File input, boolean isMutable, Density density)
-            throws IOException {
-        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given file content.
-     *
-     * @param input the file from which to read the bitmap content
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isPremultiplied()
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(File input, Set<BitmapCreateFlags> createFlags,
-            Density density) throws IOException {
-        // create a delegate with the content of the file.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
-
-        return createBitmap(delegate, createFlags, density.getDpiValue());
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given stream content.
-     *
-     * @param input the stream from which to read the bitmap content
-     * @param isMutable whether the bitmap is mutable
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density)
-            throws IOException {
-        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given stream content.
-     *
-     * @param input the stream from which to read the bitmap content
-     * @param createFlags
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isPremultiplied()
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(InputStream input, Set<BitmapCreateFlags> createFlags,
-            Density density) throws IOException {
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
-
-        return createBitmap(delegate, createFlags, density.getDpiValue());
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
-     *
-     * @param image the bitmap content
-     * @param isMutable whether the bitmap is mutable
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(BufferedImage image, boolean isMutable,
-            Density density) throws IOException {
-        return createBitmap(image, getPremultipliedBitmapCreateFlags(isMutable), density);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
-     *
-     * @param image the bitmap content
-     * @param createFlags
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isPremultiplied()
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags,
-            Density density) throws IOException {
-        // create a delegate with the given image.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
-
-        return createBitmap(delegate, createFlags, density.getDpiValue());
-    }
-
-    /**
-     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
-     */
-    public static BufferedImage getImage(Bitmap bitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(bitmap.mNativeBitmap);
-        if (delegate == null) {
-            return null;
-        }
-
-        return delegate.mImage;
-    }
-
-    public static int getBufferedImageType(int nativeBitmapConfig) {
-        switch (Config.nativeToConfig(nativeBitmapConfig)) {
-            case ALPHA_8:
-                return BufferedImage.TYPE_INT_ARGB;
-            case RGB_565:
-                return BufferedImage.TYPE_INT_ARGB;
-            case ARGB_4444:
-                return BufferedImage.TYPE_INT_ARGB;
-            case ARGB_8888:
-                return BufferedImage.TYPE_INT_ARGB;
-        }
-
-        return BufferedImage.TYPE_INT_ARGB;
-    }
-
-    /**
-     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
-     */
-    public BufferedImage getImage() {
-        return mImage;
-    }
-
-    /**
-     * Returns the Android bitmap config. Note that this not the config of the underlying
-     * Java2D bitmap.
-     */
-    public Config getConfig() {
-        return mConfig;
-    }
-
-    /**
-     * Returns the hasAlpha rendering hint
-     * @return true if the bitmap alpha should be used at render time
-     */
-    public boolean hasAlpha() {
-        return mHasAlpha && mConfig != Config.RGB_565;
-    }
-
-    public boolean hasMipMap() {
-        // TODO: check if more checks are required as in hasAlpha.
-        return mHasMipMap;
-    }
-    /**
-     * Update the generationId.
-     *
-     * @see Bitmap#getGenerationId()
-     */
-    public void change() {
-        mGenerationId++;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
-            int height, int nativeConfig, boolean isMutable) {
-        int imageType = getBufferedImageType(nativeConfig);
-
-        // create the image
-        BufferedImage image = new BufferedImage(width, height, imageType);
-
-        if (colors != null) {
-            image.setRGB(0, 0, width, height, colors, offset, stride);
-        }
-
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
-
-        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
-                            Bitmap.getDefaultDensity());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopy(int srcBitmap, int nativeConfig, boolean isMutable) {
-        Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(srcBitmap);
-        if (srcBmpDelegate == null) {
-            return null;
-        }
-
-        BufferedImage srcImage = srcBmpDelegate.getImage();
-
-        int width = srcImage.getWidth();
-        int height = srcImage.getHeight();
-
-        int imageType = getBufferedImageType(nativeConfig);
-
-        // create the image
-        BufferedImage image = new BufferedImage(width, height, imageType);
-
-        // copy the source image into the image.
-        int[] argb = new int[width * height];
-        srcImage.getRGB(0, 0, width, height, argb, 0, width);
-        image.setRGB(0, 0, width, height, argb, 0, width);
-
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
-
-        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
-                Bitmap.getDefaultDensity());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(int nativeBitmap) {
-        sManager.removeJavaReferenceFor(nativeBitmap);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeRecycle(int nativeBitmap) {
-        sManager.removeJavaReferenceFor(nativeBitmap);
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeCompress(int nativeBitmap, int format, int quality,
-            OutputStream stream, byte[] tempStorage) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.compress() is not supported", null /*data*/);
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeErase(int nativeBitmap, int color) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        BufferedImage image = delegate.mImage;
-
-        Graphics2D g = image.createGraphics();
-        try {
-            g.setColor(new java.awt.Color(color, true));
-
-            g.fillRect(0, 0, image.getWidth(), image.getHeight());
-        } finally {
-            g.dispose();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeWidth(int nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mImage.getWidth();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeHeight(int nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mImage.getHeight();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeRowBytes(int nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mImage.getWidth();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeConfig(int nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mConfig.nativeInt;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeHasAlpha(int nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return true;
-        }
-
-        return delegate.mHasAlpha;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeHasMipMap(int nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return true;
-        }
-
-        return delegate.mHasMipMap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetPixel(int nativeBitmap, int x, int y) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mImage.getRGB(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeGetPixels(int nativeBitmap, int[] pixels, int offset,
-            int stride, int x, int y, int width, int height) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.getImage().getRGB(x, y, width, height, pixels, offset, stride);
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetPixel(int nativeBitmap, int x, int y, int color) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.getImage().setRGB(x, y, color);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetPixels(int nativeBitmap, int[] colors, int offset,
-            int stride, int x, int y, int width, int height) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.getImage().setRGB(x, y, width, height, colors, offset, stride);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeCopyPixelsToBuffer(int nativeBitmap, Buffer dst) {
-        // FIXME implement native delegate
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.copyPixelsToBuffer is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeCopyPixelsFromBuffer(int nb, Buffer src) {
-        // FIXME implement native delegate
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.copyPixelsFromBuffer is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGenerationId(int nativeBitmap) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mGenerationId;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) {
-        // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only
-        // used during aidl call so really this should not be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.",
-                null /*data*/);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeWriteToParcel(int nativeBitmap, boolean isMutable,
-            int density, Parcel p) {
-        // This is only called when sending a bitmap through aidl, so really this should not
-        // be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.",
-                null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeExtractAlpha(int nativeBitmap, int nativePaint,
-            int[] offsetXY) {
-        Bitmap_Delegate bitmap = sManager.getDelegate(nativeBitmap);
-        if (bitmap == null) {
-            return null;
-        }
-
-        // get the paint which can be null if nativePaint is 0.
-        Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
-
-        if (paint != null && paint.getMaskFilter() != null) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
-                    "MaskFilter not supported in Bitmap.extractAlpha",
-                    null, null /*data*/);
-        }
-
-        int alpha = paint != null ? paint.getAlpha() : 0xFF;
-        BufferedImage image = createCopy(bitmap.getImage(), BufferedImage.TYPE_INT_ARGB, alpha);
-
-        // create the delegate. The actual Bitmap config is only an alpha channel
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ALPHA_8);
-
-        // the density doesn't matter, it's set by the Java method.
-        return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE),
-                Density.DEFAULT_DENSITY /*density*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativePrepareToDraw(int nativeBitmap) {
-        // nothing to be done here.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetHasAlpha(int nativeBitmap, boolean hasAlpha) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mHasAlpha = hasAlpha;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetHasMipMap(int nativeBitmap, boolean hasMipMap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mHasMipMap = hasMipMap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSameAs(int nb0, int nb1) {
-        Bitmap_Delegate delegate1 = sManager.getDelegate(nb0);
-        if (delegate1 == null) {
-            return false;
-        }
-
-        Bitmap_Delegate delegate2 = sManager.getDelegate(nb1);
-        if (delegate2 == null) {
-            return false;
-        }
-
-        BufferedImage image1 = delegate1.getImage();
-        BufferedImage image2 = delegate2.getImage();
-        if (delegate1.mConfig != delegate2.mConfig ||
-                image1.getWidth() != image2.getWidth() ||
-                image1.getHeight() != image2.getHeight()) {
-            return false;
-        }
-
-        // get the internal data
-        int w = image1.getWidth();
-        int h = image2.getHeight();
-        int[] argb1 = new int[w*h];
-        int[] argb2 = new int[w*h];
-
-        image1.getRGB(0, 0, w, h, argb1, 0, w);
-        image2.getRGB(0, 0, w, h, argb2, 0, w);
-
-        // compares
-        if (delegate1.mConfig == Config.ALPHA_8) {
-            // in this case we have to manually compare the alpha channel as the rest is garbage.
-            final int length = w*h;
-            for (int i = 0 ; i < length ; i++) {
-                if ((argb1[i] & 0xFF000000) != (argb2[i] & 0xFF000000)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        return Arrays.equals(argb1, argb2);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private Bitmap_Delegate(BufferedImage image, Config config) {
-        mImage = image;
-        mConfig = config;
-    }
-
-    private static Bitmap createBitmap(Bitmap_Delegate delegate,
-            Set<BitmapCreateFlags> createFlags, int density) {
-        // get its native_int
-        int nativeInt = sManager.addNewDelegate(delegate);
-
-        int width = delegate.mImage.getWidth();
-        int height = delegate.mImage.getHeight();
-        boolean isMutable = createFlags.contains(BitmapCreateFlags.MUTABLE);
-        boolean isPremultiplied = createFlags.contains(BitmapCreateFlags.PREMULTIPLIED);
-
-        // and create/return a new Bitmap with it
-        return new Bitmap(nativeInt, null /* buffer */, width, height, density, isMutable,
-                          isPremultiplied, null /*ninePatchChunk*/, null /* layoutBounds */);
-    }
-
-    private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) {
-        Set<BitmapCreateFlags> createFlags = EnumSet.of(BitmapCreateFlags.PREMULTIPLIED);
-        if (isMutable) {
-            createFlags.add(BitmapCreateFlags.MUTABLE);
-        }
-        return createFlags;
-    }
-
-    /**
-     * Creates and returns a copy of a given BufferedImage.
-     * <p/>
-     * if alpha is different than 255, then it is applied to the alpha channel of each pixel.
-     *
-     * @param image the image to copy
-     * @param imageType the type of the new image
-     * @param alpha an optional alpha modifier
-     * @return a new BufferedImage
-     */
-    /*package*/ static BufferedImage createCopy(BufferedImage image, int imageType, int alpha) {
-        int w = image.getWidth();
-        int h = image.getHeight();
-
-        BufferedImage result = new BufferedImage(w, h, imageType);
-
-        int[] argb = new int[w * h];
-        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
-
-        if (alpha != 255) {
-            final int length = argb.length;
-            for (int i = 0 ; i < length; i++) {
-                int a = (argb[i] >>> 24 * alpha) / 255;
-                argb[i] = (a << 24) | (argb[i] & 0x00FFFFFF);
-            }
-        }
-
-        result.setRGB(0, 0, w, h, argb, 0, w);
-
-        return result;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java
deleted file mode 100644
index 4becba1..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.BlurMaskFilter
- *
- * Through the layoutlib_create tool, the original native methods of BlurMaskFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original BlurMaskFilter class.
- *
- * Because this extends {@link MaskFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link MaskFilter_Delegate}.
- *
- * @see MaskFilter_Delegate
- *
- */
-public class BlurMaskFilter_Delegate extends MaskFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Blur Mask Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeConstructor(float radius, int style) {
-        BlurMaskFilter_Delegate newDelegate = new BlurMaskFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
deleted file mode 100644
index 62b47bd..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ /dev/null
@@ -1,1289 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.GcSnapshot;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Bitmap.Config;
-import android.text.TextUtils;
-
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Arc2D;
-import java.awt.image.BufferedImage;
-
-
-/**
- * Delegate implementing the native methods of android.graphics.Canvas
- *
- * Through the layoutlib_create tool, the original native methods of Canvas have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Canvas class.
- *
- * @see DelegateManager
- *
- */
-public final class Canvas_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Canvas_Delegate> sManager =
-            new DelegateManager<Canvas_Delegate>(Canvas_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    private final static boolean[] sBoolOut = new boolean[1];
-
-    // ---- delegate data ----
-    private Bitmap_Delegate mBitmap;
-    private GcSnapshot mSnapshot;
-
-    private DrawFilter_Delegate mDrawFilter = null;
-
-    // ---- Public Helper methods ----
-
-    /**
-     * Returns the native delegate associated to a given {@link Canvas} object.
-     */
-    public static Canvas_Delegate getDelegate(Canvas canvas) {
-        return sManager.getDelegate(canvas.mNativeCanvas);
-    }
-
-    /**
-     * Returns the native delegate associated to a given an int referencing a {@link Canvas} object.
-     */
-    public static Canvas_Delegate getDelegate(int native_canvas) {
-        return sManager.getDelegate(native_canvas);
-    }
-
-    /**
-     * Returns the current {@link Graphics2D} used to draw.
-     */
-    public GcSnapshot getSnapshot() {
-        return mSnapshot;
-    }
-
-    /**
-     * Returns the {@link DrawFilter} delegate or null if none have been set.
-     *
-     * @return the delegate or null.
-     */
-    public DrawFilter_Delegate getDrawFilter() {
-        return mDrawFilter;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isOpaque(Canvas thisCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        return canvasDelegate.mBitmap.getConfig() == Config.RGB_565;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getWidth(Canvas thisCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.mBitmap.getImage().getWidth();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getHeight(Canvas thisCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.mBitmap.getImage().getHeight();
-    }
-
-    @LayoutlibDelegate
-   /*package*/ static void translate(Canvas thisCanvas, float dx, float dy) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.getSnapshot().translate(dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void rotate(Canvas thisCanvas, float degrees) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.getSnapshot().rotate(Math.toRadians(degrees));
-    }
-
-    @LayoutlibDelegate
-   /*package*/ static void scale(Canvas thisCanvas, float sx, float sy) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.getSnapshot().scale(sx, sy);
-    }
-
-    @LayoutlibDelegate
-   /*package*/ static void skew(Canvas thisCanvas, float kx, float ky) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the current top graphics2D object.
-        GcSnapshot g = canvasDelegate.getSnapshot();
-
-        // get its current matrix
-        AffineTransform currentTx = g.getTransform();
-        // get the AffineTransform for the given skew.
-        float[] mtx = Matrix_Delegate.getSkew(kx, ky);
-        AffineTransform matrixTx = Matrix_Delegate.getAffineTransform(mtx);
-
-        // combine them so that the given matrix is applied after.
-        currentTx.preConcatenate(matrixTx);
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        g.setTransform(currentTx);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean clipRect(Canvas thisCanvas, RectF rect) {
-        return clipRect(thisCanvas, rect.left, rect.top, rect.right, rect.bottom);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean clipRect(Canvas thisCanvas, Rect rect) {
-        return clipRect(thisCanvas, (float) rect.left, (float) rect.top,
-                (float) rect.right, (float) rect.bottom);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean clipRect(Canvas thisCanvas, float left, float top, float right,
-            float bottom) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        return canvasDelegate.clipRect(left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean clipRect(Canvas thisCanvas, int left, int top, int right,
-            int bottom) {
-
-        return clipRect(thisCanvas, (float) left, (float) top, (float) right, (float) bottom);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int save(Canvas thisCanvas) {
-        return save(thisCanvas, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int save(Canvas thisCanvas, int saveFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.save(saveFlags);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void restore(Canvas thisCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.restore();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getSaveCount(Canvas thisCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.getSnapshot().size();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void restoreToCount(Canvas thisCanvas, int saveCount) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.restoreTo(saveCount);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void drawPoints(Canvas thisCanvas, float[] pts, int offset, int count,
-            Paint paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawPoint is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void drawPoint(Canvas thisCanvas, float x, float y, Paint paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawPoint is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void drawLines(Canvas thisCanvas,
-            final float[] pts, final int offset, final int count,
-            Paint paint) {
-        draw(thisCanvas.mNativeCanvas, paint.mNativePaint, false /*compositeOnly*/,
-                false /*forceSrcMode*/, new GcSnapshot.Drawable() {
-                    @Override
-                    public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
-                        for (int i = 0 ; i < count ; i += 4) {
-                            graphics.drawLine((int)pts[i + offset], (int)pts[i + offset + 1],
-                                    (int)pts[i + offset + 2], (int)pts[i + offset + 3]);
-                        }
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void freeCaches() {
-        // nothing to be done here.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void freeTextLayoutCaches() {
-        // nothing to be done here yet.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int initRaster(int nativeBitmapOrZero) {
-        if (nativeBitmapOrZero > 0) {
-            // get the Bitmap from the int
-            Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmapOrZero);
-
-            // create a new Canvas_Delegate with the given bitmap and return its new native int.
-            Canvas_Delegate newDelegate = new Canvas_Delegate(bitmapDelegate);
-
-            return sManager.addNewDelegate(newDelegate);
-        }
-
-        // create a new Canvas_Delegate and return its new native int.
-        Canvas_Delegate newDelegate = new Canvas_Delegate();
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void copyNativeCanvasState(int srcCanvas, int dstCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate srcCanvasDelegate = sManager.getDelegate(srcCanvas);
-        if (srcCanvasDelegate == null) {
-            return;
-        }
-
-        // get the delegate from the native int.
-        Canvas_Delegate dstCanvasDelegate = sManager.getDelegate(dstCanvas);
-        if (dstCanvasDelegate == null) {
-            return;
-        }
-        // TODO: actually copy the canvas state.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_saveLayer(int nativeCanvas, RectF bounds,
-                                               int paint, int layerFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
-        if (paintDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.saveLayer(bounds, paintDelegate, layerFlags);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_saveLayer(int nativeCanvas, float l,
-                                               float t, float r, float b,
-                                               int paint, int layerFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
-        if (paintDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.saveLayer(new RectF(l, t, r, b),
-                paintDelegate, layerFlags);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_saveLayerAlpha(int nativeCanvas,
-                                                    RectF bounds, int alpha,
-                                                    int layerFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.saveLayerAlpha(bounds, alpha, layerFlags);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_saveLayerAlpha(int nativeCanvas, float l,
-                                                    float t, float r, float b,
-                                                    int alpha, int layerFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.saveLayerAlpha(new RectF(l, t, r, b), alpha, layerFlags);
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static void native_concat(int nCanvas, int nMatrix) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        // get the current top graphics2D object.
-        GcSnapshot snapshot = canvasDelegate.getSnapshot();
-
-        // get its current matrix
-        AffineTransform currentTx = snapshot.getTransform();
-        // get the AffineTransform of the given matrix
-        AffineTransform matrixTx = matrixDelegate.getAffineTransform();
-
-        // combine them so that the given matrix is applied after.
-        currentTx.concatenate(matrixTx);
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        snapshot.setTransform(currentTx);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setMatrix(int nCanvas, int nMatrix) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        // get the current top graphics2D object.
-        GcSnapshot snapshot = canvasDelegate.getSnapshot();
-
-        // get the AffineTransform of the given matrix
-        AffineTransform matrixTx = matrixDelegate.getAffineTransform();
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        snapshot.setTransform(matrixTx);
-
-        if (matrixDelegate.hasPerspective()) {
-            assert false;
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
-                    "android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " +
-                    "supports affine transformations.", null, null /*data*/);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_clipRect(int nCanvas,
-                                                  float left, float top,
-                                                  float right, float bottom,
-                                                  int regionOp) {
-
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        return canvasDelegate.clipRect(left, top, right, bottom, regionOp);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_clipPath(int nativeCanvas,
-                                                  int nativePath,
-                                                  int regionOp) {
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return true;
-        }
-
-        Path_Delegate pathDelegate = Path_Delegate.getDelegate(nativePath);
-        if (pathDelegate == null) {
-            return true;
-        }
-
-        return canvasDelegate.mSnapshot.clip(pathDelegate.getJavaShape(), regionOp);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_clipRegion(int nativeCanvas,
-                                                    int nativeRegion,
-                                                    int regionOp) {
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return true;
-        }
-
-        Region_Delegate region = Region_Delegate.getDelegate(nativeRegion);
-        if (region == null) {
-            return true;
-        }
-
-        return canvasDelegate.mSnapshot.clip(region.getJavaArea(), regionOp);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetDrawFilter(int nativeCanvas, int nativeFilter) {
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.mDrawFilter = DrawFilter_Delegate.getDelegate(nativeFilter);
-
-        if (canvasDelegate.mDrawFilter != null &&
-                canvasDelegate.mDrawFilter.isSupported() == false) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_DRAWFILTER,
-                    canvasDelegate.mDrawFilter.getSupportMessage(), null, null /*data*/);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_getClipBounds(int nativeCanvas,
-                                                       Rect bounds) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        Rectangle rect = canvasDelegate.getSnapshot().getClip().getBounds();
-        if (rect != null && rect.isEmpty() == false) {
-            bounds.left = rect.x;
-            bounds.top = rect.y;
-            bounds.right = rect.x + rect.width;
-            bounds.bottom = rect.y + rect.height;
-            return true;
-        }
-
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_getCTM(int canvas, int matrix) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(canvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        AffineTransform transform = canvasDelegate.getSnapshot().getTransform();
-        matrixDelegate.set(Matrix_Delegate.makeValues(transform));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_quickReject(int nativeCanvas,
-                                                     RectF rect) {
-        // FIXME properly implement quickReject
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_quickReject(int nativeCanvas,
-                                                     int path) {
-        // FIXME properly implement quickReject
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_quickReject(int nativeCanvas,
-                                                     float left, float top,
-                                                     float right, float bottom) {
-        // FIXME properly implement quickReject
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawRGB(int nativeCanvas, int r, int g, int b) {
-        native_drawColor(nativeCanvas, 0xFF000000 | r << 16 | (g&0xFF) << 8 | (b&0xFF),
-                PorterDuff.Mode.SRC_OVER.nativeInt);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawARGB(int nativeCanvas, int a, int r, int g, int b) {
-        native_drawColor(nativeCanvas, a << 24 | (r&0xFF) << 16 | (g&0xFF) << 8 | (b&0xFF),
-                PorterDuff.Mode.SRC_OVER.nativeInt);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawColor(int nativeCanvas, int color) {
-        native_drawColor(nativeCanvas, color, PorterDuff.Mode.SRC_OVER.nativeInt);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawColor(int nativeCanvas, final int color, final int mode) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        final int w = canvasDelegate.mBitmap.getImage().getWidth();
-        final int h = canvasDelegate.mBitmap.getImage().getHeight();
-        draw(nativeCanvas, new GcSnapshot.Drawable() {
-
-            @Override
-            public void draw(Graphics2D graphics, Paint_Delegate paint) {
-                // reset its transform just in case
-                graphics.setTransform(new AffineTransform());
-
-                // set the color
-                graphics.setColor(new Color(color, true /*alpha*/));
-
-                Composite composite = PorterDuffXfermode_Delegate.getComposite(
-                        PorterDuffXfermode_Delegate.getPorterDuffMode(mode), 0xFF);
-                if (composite != null) {
-                    graphics.setComposite(composite);
-                }
-
-                graphics.fillRect(0, 0, w, h);
-            }
-        });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawPaint(int nativeCanvas, int paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawPaint is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawLine(int nativeCanvas,
-            final float startX, final float startY, final float stopX, final float stopY,
-            int paint) {
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                new GcSnapshot.Drawable() {
-                    @Override
-                    public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
-                        graphics.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY);
-                    }
-        });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawRect(int nativeCanvas, RectF rect,
-                                               int paint) {
-        native_drawRect(nativeCanvas, rect.left, rect.top, rect.right, rect.bottom, paint);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawRect(int nativeCanvas,
-            final float left, final float top, final float right, final float bottom, int paint) {
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                new GcSnapshot.Drawable() {
-                    @Override
-                    public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
-                        int style = paintDelegate.getStyle();
-
-                        // draw
-                        if (style == Paint.Style.FILL.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.fillRect((int)left, (int)top,
-                                    (int)(right-left), (int)(bottom-top));
-                        }
-
-                        if (style == Paint.Style.STROKE.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.drawRect((int)left, (int)top,
-                                    (int)(right-left), (int)(bottom-top));
-                        }
-                    }
-        });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawOval(int nativeCanvas, final RectF oval, int paint) {
-        if (oval.right > oval.left && oval.bottom > oval.top) {
-            draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                    new GcSnapshot.Drawable() {
-                        @Override
-                        public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
-                            int style = paintDelegate.getStyle();
-
-                            // draw
-                            if (style == Paint.Style.FILL.nativeInt ||
-                                    style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                                graphics.fillOval((int)oval.left, (int)oval.top,
-                                        (int)oval.width(), (int)oval.height());
-                            }
-
-                            if (style == Paint.Style.STROKE.nativeInt ||
-                                    style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                                graphics.drawOval((int)oval.left, (int)oval.top,
-                                        (int)oval.width(), (int)oval.height());
-                            }
-                        }
-            });
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawCircle(int nativeCanvas,
-            float cx, float cy, float radius, int paint) {
-        native_drawOval(nativeCanvas,
-                new RectF(cx - radius, cy - radius, cx + radius, cy + radius),
-                paint);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawArc(int nativeCanvas,
-            final RectF oval, final float startAngle, final float sweep,
-            final boolean useCenter, int paint) {
-        if (oval.right > oval.left && oval.bottom > oval.top) {
-            draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                    new GcSnapshot.Drawable() {
-                        @Override
-                        public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
-                            int style = paintDelegate.getStyle();
-
-                            Arc2D.Float arc = new Arc2D.Float(
-                                    oval.left, oval.top, oval.width(), oval.height(),
-                                    -startAngle, -sweep,
-                                    useCenter ? Arc2D.PIE : Arc2D.OPEN);
-
-                            // draw
-                            if (style == Paint.Style.FILL.nativeInt ||
-                                    style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                                graphics.fill(arc);
-                            }
-
-                            if (style == Paint.Style.STROKE.nativeInt ||
-                                    style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                                graphics.draw(arc);
-                            }
-                        }
-            });
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawRoundRect(int nativeCanvas,
-            final RectF rect, final float rx, final float ry, int paint) {
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                new GcSnapshot.Drawable() {
-                    @Override
-                    public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
-                        int style = paintDelegate.getStyle();
-
-                        // draw
-                        if (style == Paint.Style.FILL.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.fillRoundRect(
-                                    (int)rect.left, (int)rect.top,
-                                    (int)rect.width(), (int)rect.height(),
-                                    (int)rx, (int)ry);
-                        }
-
-                        if (style == Paint.Style.STROKE.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.drawRoundRect(
-                                    (int)rect.left, (int)rect.top,
-                                    (int)rect.width(), (int)rect.height(),
-                                    (int)rx, (int)ry);
-                        }
-                    }
-        });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawPath(int nativeCanvas, int path, int paint) {
-        final Path_Delegate pathDelegate = Path_Delegate.getDelegate(path);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                new GcSnapshot.Drawable() {
-                    @Override
-                    public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
-                        Shape shape = pathDelegate.getJavaShape();
-                        int style = paintDelegate.getStyle();
-
-                        if (style == Paint.Style.FILL.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.fill(shape);
-                        }
-
-                        if (style == Paint.Style.STROKE.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.draw(shape);
-                        }
-                    }
-        });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawBitmap(Canvas thisCanvas, int nativeCanvas, int bitmap,
-                                                 float left, float top,
-                                                 int nativePaintOrZero,
-                                                 int canvasDensity,
-                                                 int screenDensity,
-                                                 int bitmapDensity) {
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        BufferedImage image = bitmapDelegate.getImage();
-        float right = left + image.getWidth();
-        float bottom = top + image.getHeight();
-
-        drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
-                0, 0, image.getWidth(), image.getHeight(),
-                (int)left, (int)top, (int)right, (int)bottom);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawBitmap(Canvas thisCanvas, int nativeCanvas, int bitmap,
-                                                 Rect src, RectF dst,
-                                                 int nativePaintOrZero,
-                                                 int screenDensity,
-                                                 int bitmapDensity) {
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        BufferedImage image = bitmapDelegate.getImage();
-
-        if (src == null) {
-            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
-                    0, 0, image.getWidth(), image.getHeight(),
-                    (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom);
-        } else {
-            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
-                    src.left, src.top, src.width(), src.height(),
-                    (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawBitmap(int nativeCanvas, int bitmap,
-                                                 Rect src, Rect dst,
-                                                 int nativePaintOrZero,
-                                                 int screenDensity,
-                                                 int bitmapDensity) {
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        BufferedImage image = bitmapDelegate.getImage();
-
-        if (src == null) {
-            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
-                    0, 0, image.getWidth(), image.getHeight(),
-                    dst.left, dst.top, dst.right, dst.bottom);
-        } else {
-            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
-                    src.left, src.top, src.width(), src.height(),
-                    dst.left, dst.top, dst.right, dst.bottom);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawBitmap(int nativeCanvas, int[] colors,
-                                                int offset, int stride, final float x,
-                                                 final float y, int width, int height,
-                                                 boolean hasAlpha,
-                                                 int nativePaintOrZero) {
-
-        // create a temp BufferedImage containing the content.
-        final BufferedImage image = new BufferedImage(width, height,
-                hasAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
-        image.setRGB(0, 0, width, height, colors, offset, stride);
-
-        draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, false /*forceSrcMode*/,
-                new GcSnapshot.Drawable() {
-                    @Override
-                    public void draw(Graphics2D graphics, Paint_Delegate paint) {
-                        if (paint != null && paint.isFilterBitmap()) {
-                            graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-                        }
-
-                        graphics.drawImage(image, (int) x, (int) y, null);
-                    }
-        });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDrawBitmapMatrix(int nCanvas, int nBitmap,
-                                                      int nMatrix, int nPaint) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the delegate from the native int, which can be null
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
-
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nBitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        final BufferedImage image = getImageToDraw(bitmapDelegate, paintDelegate, sBoolOut);
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        final AffineTransform mtx = matrixDelegate.getAffineTransform();
-
-        canvasDelegate.getSnapshot().draw(new GcSnapshot.Drawable() {
-                @Override
-                public void draw(Graphics2D graphics, Paint_Delegate paint) {
-                    if (paint != null && paint.isFilterBitmap()) {
-                        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-                    }
-
-                    //FIXME add support for canvas, screen and bitmap densities.
-                    graphics.drawImage(image, mtx, null);
-                }
-        }, paintDelegate, true /*compositeOnly*/, false /*forceSrcMode*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDrawBitmapMesh(int nCanvas, int nBitmap,
-            int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors,
-            int colorOffset, int nPaint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawBitmapMesh is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDrawVertices(int nCanvas, int mode, int n,
-            float[] verts, int vertOffset,
-            float[] texs, int texOffset,
-            int[] colors, int colorOffset,
-            short[] indices, int indexOffset,
-            int indexCount, int nPaint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawVertices is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawText(int nativeCanvas,
-            final char[] text, final int index, final int count,
-            final float startX, final float startY, final int flags, int paint) {
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                new GcSnapshot.Drawable() {
-            @Override
-            public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
-                // WARNING: the logic in this method is similar to Paint_Delegate.measureText.
-                // Any change to this method should be reflected in Paint.measureText
-                // Paint.TextAlign indicates how the text is positioned relative to X.
-                // LEFT is the default and there's nothing to do.
-                float x = startX;
-                int limit = index + count;
-                boolean isRtl = flags == Canvas.DIRECTION_RTL;
-                if (paintDelegate.getTextAlign() != Paint.Align.LEFT.nativeInt) {
-                    float m = paintDelegate.measureText(text, index, count, isRtl);
-                    if (paintDelegate.getTextAlign() == Paint.Align.CENTER.nativeInt) {
-                        x -= m / 2;
-                    } else if (paintDelegate.getTextAlign() == Paint.Align.RIGHT.nativeInt) {
-                        x -= m;
-                    }
-                }
-
-                new BidiRenderer(graphics, paintDelegate, text).renderText(
-                        index, limit, isRtl, null, 0, true, x, startY);
-            }
-        });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawText(int nativeCanvas, String text,
-            int start, int end, float x, float y, final int flags, int paint) {
-        int count = end - start;
-        char[] buffer = TemporaryBuffer.obtain(count);
-        TextUtils.getChars(text, start, end, buffer, 0);
-
-        native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawTextRun(int nativeCanvas, String text,
-            int start, int end, int contextStart, int contextEnd,
-            float x, float y, int flags, int paint) {
-        int count = end - start;
-        char[] buffer = TemporaryBuffer.obtain(count);
-        TextUtils.getChars(text, start, end, buffer, 0);
-
-        native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawTextRun(int nativeCanvas, char[] text,
-            int start, int count, int contextStart, int contextCount,
-            float x, float y, int flags, int paint) {
-        native_drawText(nativeCanvas, text, start, count, x, y, flags, paint);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawPosText(int nativeCanvas,
-                                                  char[] text, int index,
-                                                  int count, float[] pos,
-                                                  int paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawPosText is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawPosText(int nativeCanvas,
-                                                  String text, float[] pos,
-                                                  int paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawPosText is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawTextOnPath(int nativeCanvas,
-                                                     char[] text, int index,
-                                                     int count, int path,
-                                                     float hOffset,
-                                                     float vOffset, int bidiFlags,
-                                                     int paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawTextOnPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_drawTextOnPath(int nativeCanvas,
-                                                     String text, int path,
-                                                     float hOffset,
-                                                     float vOffset,
-                                                     int flags, int paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawTextOnPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void finalizer(int nativeCanvas) {
-        // get the delegate from the native int so that it can be disposed.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.dispose();
-
-        // remove it from the manager.
-        sManager.removeJavaReferenceFor(nativeCanvas);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * Executes a {@link GcSnapshot.Drawable} with a given canvas and paint.
-     * <p>Note that the drawable may actually be executed several times if there are
-     * layers involved (see {@link #saveLayer(RectF, int, int)}.
-     */
-    private static void draw(int nCanvas, int nPaint, boolean compositeOnly, boolean forceSrcMode,
-            GcSnapshot.Drawable drawable) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the paint which can be null if nPaint is 0;
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
-
-        canvasDelegate.getSnapshot().draw(drawable, paintDelegate, compositeOnly, forceSrcMode);
-    }
-
-    /**
-     * Executes a {@link GcSnapshot.Drawable} with a given canvas. No paint object will be provided
-     * to {@link GcSnapshot.Drawable#draw(Graphics2D, Paint_Delegate)}.
-     * <p>Note that the drawable may actually be executed several times if there are
-     * layers involved (see {@link #saveLayer(RectF, int, int)}.
-     */
-    private static void draw(int nCanvas, GcSnapshot.Drawable drawable) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.mSnapshot.draw(drawable);
-    }
-
-    private Canvas_Delegate(Bitmap_Delegate bitmap) {
-        mSnapshot = GcSnapshot.createDefaultSnapshot(mBitmap = bitmap);
-    }
-
-    private Canvas_Delegate() {
-        mSnapshot = GcSnapshot.createDefaultSnapshot(null /*image*/);
-    }
-
-    /**
-     * Disposes of the {@link Graphics2D} stack.
-     */
-    private void dispose() {
-        mSnapshot.dispose();
-    }
-
-    private int save(int saveFlags) {
-        // get the current save count
-        int count = mSnapshot.size();
-
-        mSnapshot = mSnapshot.save(saveFlags);
-
-        // return the old save count
-        return count;
-    }
-
-    private int saveLayerAlpha(RectF rect, int alpha, int saveFlags) {
-        Paint_Delegate paint = new Paint_Delegate();
-        paint.setAlpha(alpha);
-        return saveLayer(rect, paint, saveFlags);
-    }
-
-    private int saveLayer(RectF rect, Paint_Delegate paint, int saveFlags) {
-        // get the current save count
-        int count = mSnapshot.size();
-
-        mSnapshot = mSnapshot.saveLayer(rect, paint, saveFlags);
-
-        // return the old save count
-        return count;
-    }
-
-    /**
-     * Restores the {@link GcSnapshot} to <var>saveCount</var>
-     * @param saveCount the saveCount
-     */
-    private void restoreTo(int saveCount) {
-        mSnapshot = mSnapshot.restoreTo(saveCount);
-    }
-
-    /**
-     * Restores the {@link GcSnapshot} to <var>saveCount</var>
-     * @param saveCount the saveCount
-     */
-    private void restore() {
-        mSnapshot = mSnapshot.restore();
-    }
-
-    private boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
-        return mSnapshot.clipRect(left, top, right, bottom, regionOp);
-    }
-
-    private void setBitmap(Bitmap_Delegate bitmap) {
-        mBitmap = bitmap;
-        assert mSnapshot.size() == 1;
-        mSnapshot.setBitmap(mBitmap);
-    }
-
-    private static void drawBitmap(
-            int nativeCanvas,
-            Bitmap_Delegate bitmap,
-            int nativePaintOrZero,
-            final int sleft, final int stop, final int sright, final int sbottom,
-            final int dleft, final int dtop, final int dright, final int dbottom) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the paint, which could be null if the int is 0
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nativePaintOrZero);
-
-        final BufferedImage image = getImageToDraw(bitmap, paintDelegate, sBoolOut);
-
-        draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, sBoolOut[0],
-                new GcSnapshot.Drawable() {
-                    @Override
-                    public void draw(Graphics2D graphics, Paint_Delegate paint) {
-                        if (paint != null && paint.isFilterBitmap()) {
-                            graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-                        }
-
-                        //FIXME add support for canvas, screen and bitmap densities.
-                        graphics.drawImage(image, dleft, dtop, dright, dbottom,
-                                sleft, stop, sright, sbottom, null);
-                    }
-        });
-    }
-
-
-    /**
-     * Returns a BufferedImage ready for drawing, based on the bitmap and paint delegate.
-     * The image returns, through a 1-size boolean array, whether the drawing code should
-     * use a SRC composite no matter what the paint says.
-     *
-     * @param bitmap the bitmap
-     * @param paint the paint that will be used to draw
-     * @param forceSrcMode whether the composite will have to be SRC
-     * @return the image to draw
-     */
-    private static BufferedImage getImageToDraw(Bitmap_Delegate bitmap, Paint_Delegate paint,
-            boolean[] forceSrcMode) {
-        BufferedImage image = bitmap.getImage();
-        forceSrcMode[0] = false;
-
-        // if the bitmap config is alpha_8, then we erase all color value from it
-        // before drawing it.
-        if (bitmap.getConfig() == Bitmap.Config.ALPHA_8) {
-            fixAlpha8Bitmap(image);
-        } else if (bitmap.hasAlpha() == false) {
-            // hasAlpha is merely a rendering hint. There can in fact be alpha values
-            // in the bitmap but it should be ignored at drawing time.
-            // There is two ways to do this:
-            // - override the composite to be SRC. This can only be used if the composite
-            //   was going to be SRC or SRC_OVER in the first place
-            // - Create a different bitmap to draw in which all the alpha channel values is set
-            //   to 0xFF.
-            if (paint != null) {
-                Xfermode_Delegate xfermodeDelegate = paint.getXfermode();
-                if (xfermodeDelegate instanceof PorterDuffXfermode_Delegate) {
-                    PorterDuff.Mode mode =
-                        ((PorterDuffXfermode_Delegate)xfermodeDelegate).getMode();
-
-                    forceSrcMode[0] = mode == PorterDuff.Mode.SRC_OVER ||
-                            mode == PorterDuff.Mode.SRC;
-                }
-            }
-
-            // if we can't force SRC mode, then create a temp bitmap of TYPE_RGB
-            if (forceSrcMode[0] == false) {
-                image = Bitmap_Delegate.createCopy(image, BufferedImage.TYPE_INT_RGB, 0xFF);
-            }
-        }
-
-        return image;
-    }
-
-    private static void fixAlpha8Bitmap(final BufferedImage image) {
-        int w = image.getWidth();
-        int h = image.getHeight();
-        int[] argb = new int[w * h];
-        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
-
-        final int length = argb.length;
-        for (int i = 0 ; i < length; i++) {
-            argb[i] &= 0xFF000000;
-        }
-        image.setRGB(0, 0, w, h, argb, 0, w);
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
deleted file mode 100644
index e5a7ab6..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.ColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of ColorFilter have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ColorFilter class.
- *
- * This also serve as a base class for all ColorFilter delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class ColorFilter_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<ColorFilter_Delegate> sManager =
-            new DelegateManager<ColorFilter_Delegate>(ColorFilter_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static ColorFilter_Delegate getDelegate(int nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void finalizer(int native_instance, int nativeColorFilter) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
deleted file mode 100644
index 2de344b..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.ColorMatrixColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of ColorMatrixColorFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ColorMatrixColorFilter class.
- *
- * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link ColorFilter_Delegate}.
- *
- * @see ColorFilter_Delegate
- *
- */
-public class ColorMatrixColorFilter_Delegate extends ColorFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "ColorMatrix Color Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeColorMatrixFilter(float[] array) {
-        ColorMatrixColorFilter_Delegate newDelegate = new ColorMatrixColorFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nColorMatrixFilter(int nativeFilter, float[] array) {
-        // pass
-        return 0;
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java
deleted file mode 100644
index 7c04a87..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.ComposePathEffect
- *
- * Through the layoutlib_create tool, the original native methods of ComposePathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ComposePathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class ComposePathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Compose Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate(int outerpe, int innerpe) {
-        ComposePathEffect_Delegate newDelegate = new ComposePathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
deleted file mode 100644
index f6e1d00..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Paint;
-
-/**
- * Delegate implementing the native methods of android.graphics.ComposeShader
- *
- * Through the layoutlib_create tool, the original native methods of ComposeShader have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ComposeShader class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class ComposeShader_Delegate extends Shader_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Paint getJavaPaint() {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Compose Shaders are not supported in Layout Preview mode.";
-    }
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate1(int native_shaderA, int native_shaderB,
-            int native_mode) {
-        // FIXME not supported yet.
-        ComposeShader_Delegate newDelegate = new ComposeShader_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate2(int native_shaderA, int native_shaderB,
-            int porterDuffMode) {
-        // FIXME not supported yet.
-        ComposeShader_Delegate newDelegate = new ComposeShader_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativePostCreate1(int native_shader, int native_skiaShaderA,
-            int native_skiaShaderB, int native_mode) {
-        // pass, not needed.
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativePostCreate2(int native_shader, int native_skiaShaderA,
-            int native_skiaShaderB, int porterDuffMode) {
-        // pass, not needed.
-        return 0;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java
deleted file mode 100644
index b0f8168..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.CornerPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of CornerPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original CornerPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class CornerPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Corner Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate(float radius) {
-        CornerPathEffect_Delegate newDelegate = new CornerPathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
deleted file mode 100644
index d97c2ec..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.BasicStroke;
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.DashPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of DashPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original DashPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
- * {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public final class DashPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    private final float[] mIntervals;
-    private final float mPhase;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        return new BasicStroke(
-                paint.getStrokeWidth(),
-                paint.getJavaCap(),
-                paint.getJavaJoin(),
-                paint.getJavaStrokeMiter(),
-                mIntervals,
-                mPhase);
-    }
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // no message since isSupported returns true;
-        return null;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate(float intervals[], float phase) {
-        DashPathEffect_Delegate newDelegate = new DashPathEffect_Delegate(intervals, phase);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private DashPathEffect_Delegate(float intervals[], float phase) {
-        mIntervals = new float[intervals.length];
-        System.arraycopy(intervals, 0, mIntervals, 0, intervals.length);
-        mPhase = phase;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java
deleted file mode 100644
index ec4a810..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.DiscretePathEffect
- *
- * Through the layoutlib_create tool, the original native methods of DiscretePathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original DiscretePathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class DiscretePathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Discrete Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate(float length, float deviation) {
-        DiscretePathEffect_Delegate newDelegate = new DiscretePathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java
deleted file mode 100644
index 870c46b..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.DrawFilter
- *
- * Through the layoutlib_create tool, the original native methods of DrawFilter have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original DrawFilter class.
- *
- * This also serve as a base class for all DrawFilter delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class DrawFilter_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<DrawFilter_Delegate> sManager =
-            new DelegateManager<DrawFilter_Delegate>(DrawFilter_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static DrawFilter_Delegate getDelegate(int nativeDrawFilter) {
-        return sManager.getDelegate(nativeDrawFilter);
-    }
-
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(int nativeDrawFilter) {
-        sManager.removeJavaReferenceFor(nativeDrawFilter);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java
deleted file mode 100644
index ebc1c1d..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.EmbossMaskFilter
- *
- * Through the layoutlib_create tool, the original native methods of EmbossMaskFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original EmbossMaskFilter class.
- *
- * Because this extends {@link MaskFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link MaskFilter_Delegate}.
- *
- * @see MaskFilter_Delegate
- *
- */
-public class EmbossMaskFilter_Delegate extends MaskFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Emboss Mask Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeConstructor(float[] direction, float ambient,
-            float specular, float blurRadius) {
-        EmbossMaskFilter_Delegate newDelegate = new EmbossMaskFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
deleted file mode 100644
index 7475c22..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import android.graphics.Shader.TileMode;
-
-/**
- * Base class for true Gradient shader delegate.
- */
-public abstract class Gradient_Delegate extends Shader_Delegate {
-
-    protected final int[] mColors;
-    protected final float[] mPositions;
-
-    @Override
-    public boolean isSupported() {
-        // all gradient shaders are supported.
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // all gradient shaders are supported, no need for a gradient support
-        return null;
-    }
-
-    /**
-     * Creates the base shader and do some basic test on the parameters.
-     *
-     * @param colors The colors to be distributed along the gradient line
-     * @param positions May be null. The relative positions [0..1] of each
-     *            corresponding color in the colors array. If this is null, the
-     *            the colors are distributed evenly along the gradient line.
-     */
-    protected Gradient_Delegate(int colors[], float positions[]) {
-        if (colors.length < 2) {
-            throw new IllegalArgumentException("needs >= 2 number of colors");
-        }
-        if (positions != null && colors.length != positions.length) {
-            throw new IllegalArgumentException("color and position arrays must be of equal length");
-        }
-
-        if (positions == null) {
-            float spacing = 1.f / (colors.length - 1);
-            positions = new float[colors.length];
-            positions[0] = 0.f;
-            positions[colors.length-1] = 1.f;
-            for (int i = 1; i < colors.length - 1 ; i++) {
-                positions[i] = spacing * i;
-            }
-        }
-
-        mColors = colors;
-        mPositions = positions;
-    }
-
-    /**
-     * Base class for (Java) Gradient Paints. This handles computing the gradient colors based
-     * on the color and position lists, as well as the {@link TileMode}
-     *
-     */
-    protected abstract static class GradientPaint implements java.awt.Paint {
-        private final static int GRADIENT_SIZE = 100;
-
-        private final int[] mColors;
-        private final float[] mPositions;
-        private final TileMode mTileMode;
-        private int[] mGradient;
-
-        protected GradientPaint(int[] colors, float[] positions, TileMode tileMode) {
-            mColors = colors;
-            mPositions = positions;
-            mTileMode = tileMode;
-        }
-
-        @Override
-        public int getTransparency() {
-            return java.awt.Paint.TRANSLUCENT;
-        }
-
-        /**
-         * Pre-computes the colors for the gradient. This must be called once before any call
-         * to {@link #getGradientColor(float)}
-         */
-        protected void precomputeGradientColors() {
-            if (mGradient == null) {
-                // actually create an array with an extra size, so that we can really go
-                // from 0 to SIZE (100%), or currentPos in the loop below will never equal 1.0
-                mGradient = new int[GRADIENT_SIZE+1];
-
-                int prevPos = 0;
-                int nextPos = 1;
-                for (int i  = 0 ; i <= GRADIENT_SIZE ; i++) {
-                    // compute current position
-                    float currentPos = (float)i/GRADIENT_SIZE;
-                    while (currentPos > mPositions[nextPos]) {
-                        prevPos = nextPos++;
-                    }
-
-                    float percent = (currentPos - mPositions[prevPos]) /
-                            (mPositions[nextPos] - mPositions[prevPos]);
-
-                    mGradient[i] = computeColor(mColors[prevPos], mColors[nextPos], percent);
-                }
-            }
-        }
-
-        /**
-         * Returns the color based on the position in the gradient.
-         * <var>pos</var> can be anything, even &lt; 0 or &gt; > 1, as the gradient
-         * will use {@link TileMode} value to convert it into a [0,1] value.
-         */
-        protected int getGradientColor(float pos) {
-            if (pos < 0.f) {
-                if (mTileMode != null) {
-                    switch (mTileMode) {
-                        case CLAMP:
-                            pos = 0.f;
-                            break;
-                        case REPEAT:
-                            // remove the integer part to stay in the [0,1] range.
-                            // we also need to invert the value from [-1,0] to [0, 1]
-                            pos = pos - (float)Math.floor(pos);
-                            break;
-                        case MIRROR:
-                            // this is the same as the positive side, just make the value positive
-                            // first.
-                            pos = Math.abs(pos);
-
-                            // get the integer and the decimal part
-                            int intPart = (int)Math.floor(pos);
-                            pos = pos - intPart;
-                            // 0 -> 1 : normal order
-                            // 1 -> 2: mirrored
-                            // etc..
-                            // this means if the intpart is odd we invert
-                            if ((intPart % 2) == 1) {
-                                pos = 1.f - pos;
-                            }
-                            break;
-                    }
-                } else {
-                    pos = 0.0f;
-                }
-            } else if (pos > 1f) {
-                if (mTileMode != null) {
-                    switch (mTileMode) {
-                        case CLAMP:
-                            pos = 1.f;
-                            break;
-                        case REPEAT:
-                            // remove the integer part to stay in the [0,1] range
-                            pos = pos - (float)Math.floor(pos);
-                            break;
-                        case MIRROR:
-                            // get the integer and the decimal part
-                            int intPart = (int)Math.floor(pos);
-                            pos = pos - intPart;
-                            // 0 -> 1 : normal order
-                            // 1 -> 2: mirrored
-                            // etc..
-                            // this means if the intpart is odd we invert
-                            if ((intPart % 2) == 1) {
-                                pos = 1.f - pos;
-                            }
-                            break;
-                    }
-                } else {
-                    pos = 1.0f;
-                }
-            }
-
-            int index = (int)((pos * GRADIENT_SIZE) + .5);
-
-            return mGradient[index];
-        }
-
-        /**
-         * Returns the color between c1, and c2, based on the percent of the distance
-         * between c1 and c2.
-         */
-        private int computeColor(int c1, int c2, float percent) {
-            int a = computeChannel((c1 >> 24) & 0xFF, (c2 >> 24) & 0xFF, percent);
-            int r = computeChannel((c1 >> 16) & 0xFF, (c2 >> 16) & 0xFF, percent);
-            int g = computeChannel((c1 >>  8) & 0xFF, (c2 >>  8) & 0xFF, percent);
-            int b = computeChannel((c1      ) & 0xFF, (c2      ) & 0xFF, percent);
-            return a << 24 | r << 16 | g << 8 | b;
-        }
-
-        /**
-         * Returns the channel value between 2 values based on the percent of the distance between
-         * the 2 values..
-         */
-        private int computeChannel(int c1, int c2, float percent) {
-            return c1 + (int)((percent * (c2-c1)) + .5);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LayerRasterizer_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LayerRasterizer_Delegate.java
deleted file mode 100644
index 51e0576..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/LayerRasterizer_Delegate.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.LayerRasterizer
- *
- * Through the layoutlib_create tool, the original native methods of LayerRasterizer have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original LayerRasterizer class.
- *
- * Because this extends {@link Rasterizer_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link Rasterizer_Delegate}.
- *
- * @see Rasterizer_Delegate
- *
- */
-public class LayerRasterizer_Delegate extends Rasterizer_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Layer Rasterizers are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeConstructor() {
-        LayerRasterizer_Delegate newDelegate = new LayerRasterizer_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeAddLayer(int native_layer, int native_paint, float dx, float dy) {
-
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
deleted file mode 100644
index 0ee883d..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.LightingColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of LightingColorFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original LightingColorFilter class.
- *
- * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link ColorFilter_Delegate}.
- *
- * @see ColorFilter_Delegate
- *
- */
-public class LightingColorFilter_Delegate extends ColorFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Lighting Color Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int native_CreateLightingFilter(int mul, int add) {
-        LightingColorFilter_Delegate newDelegate = new LightingColorFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nCreateLightingFilter(int nativeFilter, int mul, int add) {
-        // pass
-        return 0;
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
deleted file mode 100644
index f117fca..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-/**
- * Delegate implementing the native methods of android.graphics.LinearGradient
- *
- * Through the layoutlib_create tool, the original native methods of LinearGradient have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original LinearGradient class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public final class LinearGradient_Delegate extends Gradient_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate1(LinearGradient thisGradient,
-            float x0, float y0, float x1, float y1,
-            int colors[], float positions[], int tileMode) {
-        LinearGradient_Delegate newDelegate = new LinearGradient_Delegate(x0, y0, x1, y1,
-                colors, positions, Shader_Delegate.getTileMode(tileMode));
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate2(LinearGradient thisGradient,
-            float x0, float y0, float x1, float y1,
-            int color0, int color1, int tileMode) {
-        return nativeCreate1(thisGradient,
-                x0, y0, x1, y1, new int[] { color0, color1}, null /*positions*/,
-                tileMode);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativePostCreate1(LinearGradient thisGradient,
-            int native_shader, float x0, float y0, float x1, float y1,
-            int colors[], float positions[], int tileMode) {
-        // nothing to be done here.
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativePostCreate2(LinearGradient thisGradient,
-            int native_shader, float x0, float y0, float x1, float y1,
-            int color0, int color1, int tileMode) {
-        // nothing to be done here.
-        return 0;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * Create a shader that draws a linear gradient along a line.
-     *
-     * @param x0 The x-coordinate for the start of the gradient line
-     * @param y0 The y-coordinate for the start of the gradient line
-     * @param x1 The x-coordinate for the end of the gradient line
-     * @param y1 The y-coordinate for the end of the gradient line
-     * @param colors The colors to be distributed along the gradient line
-     * @param positions May be null. The relative positions [0..1] of each
-     *            corresponding color in the colors array. If this is null, the
-     *            the colors are distributed evenly along the gradient line.
-     * @param tile The Shader tiling mode
-     */
-    private LinearGradient_Delegate(float x0, float y0, float x1, float y1,
-            int colors[], float positions[], TileMode tile) {
-        super(colors, positions);
-        mJavaPaint = new LinearGradientPaint(x0, y0, x1, y1, mColors, mPositions, tile);
-    }
-
-    // ---- Custom Java Paint ----
-    /**
-     * Linear Gradient (Java) Paint able to handle more than 2 points, as
-     * {@link java.awt.GradientPaint} only supports 2 points and does not support Android's tile
-     * modes.
-     */
-    private class LinearGradientPaint extends GradientPaint {
-
-        private final float mX0;
-        private final float mY0;
-        private final float mDx;
-        private final float mDy;
-        private final float mDSize2;
-
-        public LinearGradientPaint(float x0, float y0, float x1, float y1, int colors[],
-                float positions[], TileMode tile) {
-            super(colors, positions, tile);
-            mX0 = x0;
-            mY0 = y0;
-            mDx = x1 - x0;
-            mDy = y1 - y0;
-            mDSize2 = mDx * mDx + mDy * mDy;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel      colorModel,
-                java.awt.Rectangle             deviceBounds,
-                java.awt.geom.Rectangle2D      userBounds,
-                java.awt.geom.AffineTransform  xform,
-                java.awt.RenderingHints        hints) {
-            precomputeGradientColors();
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in LinearGradient", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in LinearGradient", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new LinearGradientPaintContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class LinearGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            private LinearGradientPaintContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel;
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
-                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
-
-                int[] data = new int[w*h];
-
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix.
-                        pt1[0] = pt2[0];
-                        pt1[1] = pt2[1];
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        data[index++] = getColor(pt2[0], pt2[1]);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-        }
-
-        /**
-         * Returns a color for an arbitrary point.
-         */
-        private int getColor(float x, float y) {
-            float pos;
-            if (mDx == 0) {
-                pos = (y - mY0) / mDy;
-            } else if (mDy == 0) {
-                pos = (x - mX0) / mDx;
-            } else {
-                // find the x position on the gradient vector.
-                float _x = (mDx*mDy*(y-mY0) + mDy*mDy*mX0 + mDx*mDx*x) / mDSize2;
-                // from it get the position relative to the vector
-                pos = (_x - mX0) / mDx;
-            }
-
-            return getGradientColor(pos);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java
deleted file mode 100644
index c2f27e4..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.MaskFilter
- *
- * Through the layoutlib_create tool, the original native methods of MaskFilter have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original MaskFilter class.
- *
- * This also serve as a base class for all MaskFilter delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class MaskFilter_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<MaskFilter_Delegate> sManager =
-            new DelegateManager<MaskFilter_Delegate>(MaskFilter_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static MaskFilter_Delegate getDelegate(int nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(int native_filter) {
-        sManager.removeJavaReferenceFor(native_filter);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
deleted file mode 100644
index 5df2a21..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+++ /dev/null
@@ -1,1129 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Matrix.ScaleToFit;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-
-/**
- * Delegate implementing the native methods of android.graphics.Matrix
- *
- * Through the layoutlib_create tool, the original native methods of Matrix have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Matrix class.
- *
- * @see DelegateManager
- *
- */
-public final class Matrix_Delegate {
-
-    private final static int MATRIX_SIZE = 9;
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Matrix_Delegate> sManager =
-            new DelegateManager<Matrix_Delegate>(Matrix_Delegate.class);
-
-    // ---- delegate data ----
-    private float mValues[] = new float[MATRIX_SIZE];
-
-    // ---- Public Helper methods ----
-
-    public static Matrix_Delegate getDelegate(int native_instance) {
-        return sManager.getDelegate(native_instance);
-    }
-
-    /**
-     * Returns an {@link AffineTransform} matching the given Matrix.
-     */
-    public static AffineTransform getAffineTransform(Matrix m) {
-        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
-        if (delegate == null) {
-            return null;
-        }
-
-        return delegate.getAffineTransform();
-    }
-
-    public static boolean hasPerspective(Matrix m) {
-        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
-        if (delegate == null) {
-            return false;
-        }
-
-        return delegate.hasPerspective();
-    }
-
-    /**
-     * Sets the content of the matrix with the content of another matrix.
-     */
-    public void set(Matrix_Delegate matrix) {
-        System.arraycopy(matrix.mValues, 0, mValues, 0, MATRIX_SIZE);
-    }
-
-    /**
-     * Sets the content of the matrix with the content of another matrix represented as an array
-     * of values.
-     */
-    public void set(float[] values) {
-        System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE);
-    }
-
-    /**
-     * Resets the matrix to be the identity matrix.
-     */
-    public void reset() {
-        reset(mValues);
-    }
-
-    /**
-     * Returns whether or not the matrix is identity.
-     */
-    public boolean isIdentity() {
-        for (int i = 0, k = 0; i < 3; i++) {
-            for (int j = 0; j < 3; j++, k++) {
-                if (mValues[k] != ((i==j) ? 1 : 0)) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    public static float[] makeValues(AffineTransform matrix) {
-        float[] values = new float[MATRIX_SIZE];
-        values[0] = (float) matrix.getScaleX();
-        values[1] = (float) matrix.getShearX();
-        values[2] = (float) matrix.getTranslateX();
-        values[3] = (float) matrix.getShearY();
-        values[4] = (float) matrix.getScaleY();
-        values[5] = (float) matrix.getTranslateY();
-        values[6] = 0.f;
-        values[7] = 0.f;
-        values[8] = 1.f;
-
-        return values;
-    }
-
-    public static Matrix_Delegate make(AffineTransform matrix) {
-        return new Matrix_Delegate(makeValues(matrix));
-    }
-
-    public boolean mapRect(RectF dst, RectF src) {
-        // array with 4 corners
-        float[] corners = new float[] {
-                src.left, src.top,
-                src.right, src.top,
-                src.right, src.bottom,
-                src.left, src.bottom,
-        };
-
-        // apply the transform to them.
-        mapPoints(corners);
-
-        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
-        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
-        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));
-
-        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
-        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));
-
-
-        return (computeTypeMask() & kRectStaysRect_Mask) != 0;
-    }
-
-
-    /**
-     * Returns an {@link AffineTransform} matching the matrix.
-     */
-    public AffineTransform getAffineTransform() {
-        return getAffineTransform(mValues);
-    }
-
-    public boolean hasPerspective() {
-        return (mValues[6] != 0 || mValues[7] != 0 || mValues[8] != 1);
-    }
-
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int native_create(int native_src_or_zero) {
-        // create the delegate
-        Matrix_Delegate newDelegate = new Matrix_Delegate();
-
-        // copy from values if needed.
-        if (native_src_or_zero > 0) {
-            Matrix_Delegate oldDelegate = sManager.getDelegate(native_src_or_zero);
-            if (oldDelegate != null) {
-                System.arraycopy(
-                        oldDelegate.mValues, 0,
-                        newDelegate.mValues, 0,
-                        MATRIX_SIZE);
-            }
-        }
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_isIdentity(int native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        return d.isIdentity();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_rectStaysRect(int native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return true;
-        }
-
-        return (d.computeTypeMask() & kRectStaysRect_Mask) != 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_reset(int native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        reset(d.mValues);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_set(int native_object, int other) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        Matrix_Delegate src = sManager.getDelegate(other);
-        if (src == null) {
-            return;
-        }
-
-        System.arraycopy(src.mValues, 0, d.mValues, 0, MATRIX_SIZE);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setTranslate(int native_object, float dx, float dy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        setTranslate(d.mValues, dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setScale(int native_object, float sx, float sy,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues = getScale(sx, sy, px, py);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setScale(int native_object, float sx, float sy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues[0] = sx;
-        d.mValues[1] = 0;
-        d.mValues[2] = 0;
-        d.mValues[3] = 0;
-        d.mValues[4] = sy;
-        d.mValues[5] = 0;
-        d.mValues[6] = 0;
-        d.mValues[7] = 0;
-        d.mValues[8] = 1;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setRotate(int native_object, float degrees, float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues = getRotate(degrees, px, py);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setRotate(int native_object, float degrees) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        setRotate(d.mValues, degrees);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setSinCos(int native_object, float sinValue, float cosValue,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        setTranslate(d.mValues, -px, -py);
-
-        // scale
-        d.postTransform(getRotate(sinValue, cosValue));
-        // translate back the pivot
-        d.postTransform(getTranslate(px, py));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setSinCos(int native_object, float sinValue, float cosValue) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        setRotate(d.mValues, sinValue, cosValue);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setSkew(int native_object, float kx, float ky,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues = getSkew(kx, ky, px, py);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setSkew(int native_object, float kx, float ky) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues[0] = 1;
-        d.mValues[1] = kx;
-        d.mValues[2] = -0;
-        d.mValues[3] = ky;
-        d.mValues[4] = 1;
-        d.mValues[5] = 0;
-        d.mValues[6] = 0;
-        d.mValues[7] = 0;
-        d.mValues[8] = 1;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_setConcat(int native_object, int a, int b) {
-        if (a == native_object) {
-            return native_preConcat(native_object, b);
-        } else if (b == native_object) {
-            return native_postConcat(native_object, a);
-        }
-
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        Matrix_Delegate a_mtx = sManager.getDelegate(a);
-        if (a_mtx == null) {
-            return false;
-        }
-
-        Matrix_Delegate b_mtx = sManager.getDelegate(b);
-        if (b_mtx == null) {
-            return false;
-        }
-
-        multiply(d.mValues, a_mtx.mValues, b_mtx.mValues);
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_preTranslate(int native_object, float dx, float dy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.preTransform(getTranslate(dx, dy));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_preScale(int native_object, float sx, float sy,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.preTransform(getScale(sx, sy, px, py));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_preScale(int native_object, float sx, float sy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.preTransform(getScale(sx, sy));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_preRotate(int native_object, float degrees,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.preTransform(getRotate(degrees, px, py));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_preRotate(int native_object, float degrees) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        double rad = Math.toRadians(degrees);
-        float sin = (float)Math.sin(rad);
-        float cos = (float)Math.cos(rad);
-
-        d.preTransform(getRotate(sin, cos));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_preSkew(int native_object, float kx, float ky,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.preTransform(getSkew(kx, ky, px, py));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_preSkew(int native_object, float kx, float ky) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.preTransform(getSkew(kx, ky));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_preConcat(int native_object, int other_matrix) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        Matrix_Delegate other = sManager.getDelegate(other_matrix);
-        if (other == null) {
-            return false;
-        }
-
-        d.preTransform(other.mValues);
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_postTranslate(int native_object, float dx, float dy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.postTransform(getTranslate(dx, dy));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_postScale(int native_object, float sx, float sy,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.postTransform(getScale(sx, sy, px, py));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_postScale(int native_object, float sx, float sy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.postTransform(getScale(sx, sy));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_postRotate(int native_object, float degrees,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.postTransform(getRotate(degrees, px, py));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_postRotate(int native_object, float degrees) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.postTransform(getRotate(degrees));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_postSkew(int native_object, float kx, float ky,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.postTransform(getSkew(kx, ky, px, py));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_postSkew(int native_object, float kx, float ky) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        d.postTransform(getSkew(kx, ky));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_postConcat(int native_object, int other_matrix) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        Matrix_Delegate other = sManager.getDelegate(other_matrix);
-        if (other == null) {
-            return false;
-        }
-
-        d.postTransform(other.mValues);
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_setRectToRect(int native_object, RectF src,
-            RectF dst, int stf) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        if (src.isEmpty()) {
-            reset(d.mValues);
-            return false;
-        }
-
-        if (dst.isEmpty()) {
-            d.mValues[0] = d.mValues[1] = d.mValues[2] = d.mValues[3] = d.mValues[4] = d.mValues[5]
-               = d.mValues[6] = d.mValues[7] = 0;
-            d.mValues[8] = 1;
-        } else {
-            float    tx, sx = dst.width() / src.width();
-            float    ty, sy = dst.height() / src.height();
-            boolean  xLarger = false;
-
-            if (stf != ScaleToFit.FILL.nativeInt) {
-                if (sx > sy) {
-                    xLarger = true;
-                    sx = sy;
-                } else {
-                    sy = sx;
-                }
-            }
-
-            tx = dst.left - src.left * sx;
-            ty = dst.top - src.top * sy;
-            if (stf == ScaleToFit.CENTER.nativeInt || stf == ScaleToFit.END.nativeInt) {
-                float diff;
-
-                if (xLarger) {
-                    diff = dst.width() - src.width() * sy;
-                } else {
-                    diff = dst.height() - src.height() * sy;
-                }
-
-                if (stf == ScaleToFit.CENTER.nativeInt) {
-                    diff = diff / 2;
-                }
-
-                if (xLarger) {
-                    tx += diff;
-                } else {
-                    ty += diff;
-                }
-            }
-
-            d.mValues[0] = sx;
-            d.mValues[4] = sy;
-            d.mValues[2] = tx;
-            d.mValues[5] = ty;
-            d.mValues[1]  = d.mValues[3] = d.mValues[6] = d.mValues[7] = 0;
-
-        }
-        // shared cleanup
-        d.mValues[8] = 1;
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_setPolyToPoly(int native_object, float[] src, int srcIndex,
-            float[] dst, int dstIndex, int pointCount) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Matrix.setPolyToPoly is not supported.",
-                null, null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_invert(int native_object, int inverse) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        Matrix_Delegate inv_mtx = sManager.getDelegate(inverse);
-        if (inv_mtx == null) {
-            return false;
-        }
-
-        try {
-            AffineTransform affineTransform = d.getAffineTransform();
-            AffineTransform inverseTransform = affineTransform.createInverse();
-            inv_mtx.mValues[0] = (float)inverseTransform.getScaleX();
-            inv_mtx.mValues[1] = (float)inverseTransform.getShearX();
-            inv_mtx.mValues[2] = (float)inverseTransform.getTranslateX();
-            inv_mtx.mValues[3] = (float)inverseTransform.getScaleX();
-            inv_mtx.mValues[4] = (float)inverseTransform.getShearY();
-            inv_mtx.mValues[5] = (float)inverseTransform.getTranslateY();
-
-            return true;
-        } catch (NoninvertibleTransformException e) {
-            return false;
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_mapPoints(int native_object, float[] dst, int dstIndex,
-            float[] src, int srcIndex, int ptCount, boolean isPts) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        if (isPts) {
-            d.mapPoints(dst, dstIndex, src, srcIndex, ptCount);
-        } else {
-            d.mapVectors(dst, dstIndex, src, srcIndex, ptCount);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_mapRect(int native_object, RectF dst, RectF src) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        return d.mapRect(dst, src);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float native_mapRadius(int native_object, float radius) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return 0.f;
-        }
-
-        float[] src = new float[] { radius, 0.f, 0.f, radius };
-        d.mapVectors(src, 0, src, 0, 2);
-
-        float l1 = getPointLength(src, 0);
-        float l2 = getPointLength(src, 2);
-
-        return (float) Math.sqrt(l1 * l2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_getValues(int native_object, float[] values) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        System.arraycopy(d.mValues, 0, d.mValues, 0, MATRIX_SIZE);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setValues(int native_object, float[] values) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        System.arraycopy(values, 0, d.mValues, 0, MATRIX_SIZE);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_equals(int native_a, int native_b) {
-        Matrix_Delegate a = sManager.getDelegate(native_a);
-        if (a == null) {
-            return false;
-        }
-
-        Matrix_Delegate b = sManager.getDelegate(native_b);
-        if (b == null) {
-            return false;
-        }
-
-        for (int i = 0 ; i < MATRIX_SIZE ; i++) {
-            if (a.mValues[i] != b.mValues[i]) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void finalizer(int native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    // ---- Private helper methods ----
-
-    /*package*/ static AffineTransform getAffineTransform(float[] matrix) {
-        // the AffineTransform constructor takes the value in a different order
-        // for a matrix [ 0 1 2 ]
-        //              [ 3 4 5 ]
-        // the order is 0, 3, 1, 4, 2, 5...
-        return new AffineTransform(
-                matrix[0], matrix[3], matrix[1],
-                matrix[4], matrix[2], matrix[5]);
-    }
-
-    /**
-     * Reset a matrix to the identity
-     */
-    private static void reset(float[] mtx) {
-        for (int i = 0, k = 0; i < 3; i++) {
-            for (int j = 0; j < 3; j++, k++) {
-                mtx[k] = ((i==j) ? 1 : 0);
-            }
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private final static int kIdentity_Mask      = 0;
-    private final static int kTranslate_Mask     = 0x01;  //!< set if the matrix has translation
-    private final static int kScale_Mask         = 0x02;  //!< set if the matrix has X or Y scale
-    private final static int kAffine_Mask        = 0x04;  //!< set if the matrix skews or rotates
-    private final static int kPerspective_Mask   = 0x08;  //!< set if the matrix is in perspective
-    private final static int kRectStaysRect_Mask = 0x10;
-    @SuppressWarnings("unused")
-    private final static int kUnknown_Mask       = 0x80;
-
-    @SuppressWarnings("unused")
-    private final static int kAllMasks           = kTranslate_Mask |
-                                                   kScale_Mask |
-                                                   kAffine_Mask |
-                                                   kPerspective_Mask |
-                                                   kRectStaysRect_Mask;
-
-    // these guys align with the masks, so we can compute a mask from a variable 0/1
-    @SuppressWarnings("unused")
-    private final static int kTranslate_Shift = 0;
-    @SuppressWarnings("unused")
-    private final static int kScale_Shift = 1;
-    @SuppressWarnings("unused")
-    private final static int kAffine_Shift = 2;
-    @SuppressWarnings("unused")
-    private final static int kPerspective_Shift = 3;
-    private final static int kRectStaysRect_Shift = 4;
-
-    private int computeTypeMask() {
-        int mask = 0;
-
-        if (mValues[6] != 0. || mValues[7] != 0. || mValues[8] != 1.) {
-            mask |= kPerspective_Mask;
-        }
-
-        if (mValues[2] != 0. || mValues[5] != 0.) {
-            mask |= kTranslate_Mask;
-        }
-
-        float m00 = mValues[0];
-        float m01 = mValues[1];
-        float m10 = mValues[3];
-        float m11 = mValues[4];
-
-        if (m01 != 0. || m10 != 0.) {
-            mask |= kAffine_Mask;
-        }
-
-        if (m00 != 1. || m11 != 1.) {
-            mask |= kScale_Mask;
-        }
-
-        if ((mask & kPerspective_Mask) == 0) {
-            // map non-zero to 1
-            int im00 = m00 != 0 ? 1 : 0;
-            int im01 = m01 != 0 ? 1 : 0;
-            int im10 = m10 != 0 ? 1 : 0;
-            int im11 = m11 != 0 ? 1 : 0;
-
-            // record if the (p)rimary and (s)econdary diagonals are all 0 or
-            // all non-zero (answer is 0 or 1)
-            int dp0 = (im00 | im11) ^ 1;  // true if both are 0
-            int dp1 = im00 & im11;        // true if both are 1
-            int ds0 = (im01 | im10) ^ 1;  // true if both are 0
-            int ds1 = im01 & im10;        // true if both are 1
-
-            // return 1 if primary is 1 and secondary is 0 or
-            // primary is 0 and secondary is 1
-            mask |= ((dp0 & ds1) | (dp1 & ds0)) << kRectStaysRect_Shift;
-        }
-
-        return mask;
-    }
-
-    private Matrix_Delegate() {
-        reset();
-    }
-
-    private Matrix_Delegate(float[] values) {
-        System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE);
-    }
-
-    /**
-     * Adds the given transformation to the current Matrix
-     * <p/>This in effect does this = this*matrix
-     * @param matrix
-     */
-    private void postTransform(float[] matrix) {
-        float[] tmp = new float[9];
-        multiply(tmp, mValues, matrix);
-        mValues = tmp;
-    }
-
-    /**
-     * Adds the given transformation to the current Matrix
-     * <p/>This in effect does this = matrix*this
-     * @param matrix
-     */
-    private void preTransform(float[] matrix) {
-        float[] tmp = new float[9];
-        multiply(tmp, matrix, mValues);
-        mValues = tmp;
-    }
-
-    /**
-     * Apply this matrix to the array of 2D points specified by src, and write
-      * the transformed points into the array of points specified by dst. The
-      * two arrays represent their "points" as pairs of floats [x, y].
-      *
-      * @param dst   The array of dst points (x,y pairs)
-      * @param dstIndex The index of the first [x,y] pair of dst floats
-      * @param src   The array of src points (x,y pairs)
-      * @param srcIndex The index of the first [x,y] pair of src floats
-      * @param pointCount The number of points (x,y pairs) to transform
-      */
-
-     private void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,
-                           int pointCount) {
-         final int count = pointCount * 2;
-
-         float[] tmpDest = dst;
-         boolean inPlace = dst == src;
-         if (inPlace) {
-             tmpDest = new float[dstIndex + count];
-         }
-
-         for (int i = 0 ; i < count ; i += 2) {
-             // just in case we are doing in place, we better put this in temp vars
-             float x = mValues[0] * src[i + srcIndex] +
-                       mValues[1] * src[i + srcIndex + 1] +
-                       mValues[2];
-             float y = mValues[3] * src[i + srcIndex] +
-                       mValues[4] * src[i + srcIndex + 1] +
-                       mValues[5];
-
-             tmpDest[i + dstIndex]     = x;
-             tmpDest[i + dstIndex + 1] = y;
-         }
-
-         if (inPlace) {
-             System.arraycopy(tmpDest, dstIndex, dst, dstIndex, count);
-         }
-     }
-
-     /**
-      * Apply this matrix to the array of 2D points, and write the transformed
-      * points back into the array
-      *
-      * @param pts The array [x0, y0, x1, y1, ...] of points to transform.
-      */
-
-     private void mapPoints(float[] pts) {
-         mapPoints(pts, 0, pts, 0, pts.length >> 1);
-     }
-
-     private void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int ptCount) {
-         if (hasPerspective()) {
-             // transform the (0,0) point
-             float[] origin = new float[] { 0.f, 0.f};
-             mapPoints(origin);
-
-             // translate the vector data as points
-             mapPoints(dst, dstIndex, src, srcIndex, ptCount);
-
-             // then substract the transformed origin.
-             final int count = ptCount * 2;
-             for (int i = 0 ; i < count ; i += 2) {
-                 dst[dstIndex + i] = dst[dstIndex + i] - origin[0];
-                 dst[dstIndex + i + 1] = dst[dstIndex + i + 1] - origin[1];
-             }
-         } else {
-             // make a copy of the matrix
-             Matrix_Delegate copy = new Matrix_Delegate(mValues);
-
-             // remove the translation
-             setTranslate(copy.mValues, 0, 0);
-
-             // map the content as points.
-             copy.mapPoints(dst, dstIndex, src, srcIndex, ptCount);
-         }
-     }
-
-     private static float getPointLength(float[] src, int index) {
-         return (float) Math.sqrt(src[index] * src[index] + src[index + 1] * src[index + 1]);
-     }
-
-    /**
-     * multiply two matrices and store them in a 3rd.
-     * <p/>This in effect does dest = a*b
-     * dest cannot be the same as a or b.
-     */
-     /*package*/ static void multiply(float dest[], float[] a, float[] b) {
-        // first row
-        dest[0] = b[0] * a[0] + b[1] * a[3] + b[2] * a[6];
-        dest[1] = b[0] * a[1] + b[1] * a[4] + b[2] * a[7];
-        dest[2] = b[0] * a[2] + b[1] * a[5] + b[2] * a[8];
-
-        // 2nd row
-        dest[3] = b[3] * a[0] + b[4] * a[3] + b[5] * a[6];
-        dest[4] = b[3] * a[1] + b[4] * a[4] + b[5] * a[7];
-        dest[5] = b[3] * a[2] + b[4] * a[5] + b[5] * a[8];
-
-        // 3rd row
-        dest[6] = b[6] * a[0] + b[7] * a[3] + b[8] * a[6];
-        dest[7] = b[6] * a[1] + b[7] * a[4] + b[8] * a[7];
-        dest[8] = b[6] * a[2] + b[7] * a[5] + b[8] * a[8];
-    }
-
-    /**
-     * Returns a matrix that represents a given translate
-     * @param dx
-     * @param dy
-     * @return
-     */
-    /*package*/ static float[] getTranslate(float dx, float dy) {
-        return setTranslate(new float[9], dx, dy);
-    }
-
-    /*package*/ static float[] setTranslate(float[] dest, float dx, float dy) {
-        dest[0] = 1;
-        dest[1] = 0;
-        dest[2] = dx;
-        dest[3] = 0;
-        dest[4] = 1;
-        dest[5] = dy;
-        dest[6] = 0;
-        dest[7] = 0;
-        dest[8] = 1;
-        return dest;
-    }
-
-    /*package*/ static float[] getScale(float sx, float sy) {
-        return new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 };
-    }
-
-    /**
-     * Returns a matrix that represents the given scale info.
-     * @param sx
-     * @param sy
-     * @param px
-     * @param py
-     */
-    /*package*/ static float[] getScale(float sx, float sy, float px, float py) {
-        float[] tmp = new float[9];
-        float[] tmp2 = new float[9];
-
-        // TODO: do it in one pass
-
-        // translate tmp so that the pivot is in 0,0
-        setTranslate(tmp, -px, -py);
-
-        // scale into tmp2
-        multiply(tmp2, tmp, getScale(sx, sy));
-
-        // translate back the pivot back into tmp
-        multiply(tmp, tmp2, getTranslate(px, py));
-
-        return tmp;
-    }
-
-
-    /*package*/ static float[] getRotate(float degrees) {
-        double rad = Math.toRadians(degrees);
-        float sin = (float)Math.sin(rad);
-        float cos = (float)Math.cos(rad);
-
-        return getRotate(sin, cos);
-    }
-
-    /*package*/ static float[] getRotate(float sin, float cos) {
-        return setRotate(new float[9], sin, cos);
-    }
-
-    /*package*/ static float[] setRotate(float[] dest, float degrees) {
-        double rad = Math.toRadians(degrees);
-        float sin = (float)Math.sin(rad);
-        float cos = (float)Math.cos(rad);
-
-        return setRotate(dest, sin, cos);
-    }
-
-    /*package*/ static float[] setRotate(float[] dest, float sin, float cos) {
-        dest[0] = cos;
-        dest[1] = -sin;
-        dest[2] = 0;
-        dest[3] = sin;
-        dest[4] = cos;
-        dest[5] = 0;
-        dest[6] = 0;
-        dest[7] = 0;
-        dest[8] = 1;
-        return dest;
-    }
-
-    /*package*/ static float[] getRotate(float degrees, float px, float py) {
-        float[] tmp = new float[9];
-        float[] tmp2 = new float[9];
-
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        setTranslate(tmp, -px, -py);
-
-        // rotate into tmp2
-        double rad = Math.toRadians(degrees);
-        float cos = (float)Math.cos(rad);
-        float sin = (float)Math.sin(rad);
-        multiply(tmp2, tmp, getRotate(sin, cos));
-
-        // translate back the pivot back into tmp
-        multiply(tmp, tmp2, getTranslate(px, py));
-
-        return tmp;
-    }
-
-    /*package*/ static float[] getSkew(float kx, float ky) {
-        return new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 };
-    }
-
-    /*package*/ static float[] getSkew(float kx, float ky, float px, float py) {
-        float[] tmp = new float[9];
-        float[] tmp2 = new float[9];
-
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        setTranslate(tmp, -px, -py);
-
-        // skew into tmp2
-        multiply(tmp2, tmp, new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 });
-        // translate back the pivot back into tmp
-        multiply(tmp, tmp2, getTranslate(px, py));
-
-        return tmp;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
deleted file mode 100644
index fa68796..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.GcSnapshot;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.drawable.NinePatchDrawable;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.lang.ref.SoftReference;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Delegate implementing the native methods of android.graphics.NinePatch
- *
- * Through the layoutlib_create tool, the original native methods of NinePatch have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-public final class NinePatch_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<NinePatch_Delegate> sManager =
-            new DelegateManager<NinePatch_Delegate>(NinePatch_Delegate.class);
-
-    // ---- delegate helper data ----
-    /**
-     * Cache map for {@link NinePatchChunk}.
-     * When the chunks are created they are serialized into a byte[], and both are put
-     * in the cache, using a {@link SoftReference} for the chunk. The default Java classes
-     * for {@link NinePatch} and {@link NinePatchDrawable} only reference to the byte[] data, and
-     * provide this for drawing.
-     * Using the cache map allows us to not have to deserialize the byte[] back into a
-     * {@link NinePatchChunk} every time a rendering is done.
-     */
-    private final static Map<byte[], SoftReference<NinePatchChunk>> sChunkCache =
-        new HashMap<byte[], SoftReference<NinePatchChunk>>();
-
-    // ---- delegate data ----
-    private byte[] chunk;
-
-
-    // ---- Public Helper methods ----
-
-    /**
-     * Serializes the given chunk.
-     *
-     * @return the serialized data for the chunk.
-     */
-    public static byte[] serialize(NinePatchChunk chunk) {
-        // serialize the chunk to get a byte[]
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = null;
-        try {
-            oos = new ObjectOutputStream(baos);
-            oos.writeObject(chunk);
-        } catch (IOException e) {
-            Bridge.getLog().error(null, "Failed to serialize NinePatchChunk.", e, null /*data*/);
-            return null;
-        } finally {
-            if (oos != null) {
-                try {
-                    oos.close();
-                } catch (IOException e) {
-                }
-            }
-        }
-
-        // get the array and add it to the cache
-        byte[] array = baos.toByteArray();
-        sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
-        return array;
-    }
-
-    /**
-     * Returns a {@link NinePatchChunk} object for the given serialized representation.
-     *
-     * If the chunk is present in the cache then the object from the cache is returned, otherwise
-     * the array is deserialized into a {@link NinePatchChunk} object.
-     *
-     * @param array the serialized representation of the chunk.
-     * @return the NinePatchChunk or null if deserialization failed.
-     */
-    public static NinePatchChunk getChunk(byte[] array) {
-        SoftReference<NinePatchChunk> chunkRef = sChunkCache.get(array);
-        NinePatchChunk chunk = chunkRef.get();
-        if (chunk == null) {
-            ByteArrayInputStream bais = new ByteArrayInputStream(array);
-            ObjectInputStream ois = null;
-            try {
-                ois = new ObjectInputStream(bais);
-                chunk = (NinePatchChunk) ois.readObject();
-
-                // put back the chunk in the cache
-                if (chunk != null) {
-                    sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
-                }
-            } catch (IOException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to deserialize NinePatchChunk content.", e, null /*data*/);
-                return null;
-            } catch (ClassNotFoundException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to deserialize NinePatchChunk class.", e, null /*data*/);
-                return null;
-            } finally {
-                if (ois != null) {
-                    try {
-                        ois.close();
-                    } catch (IOException e) {
-                    }
-                }
-            }
-        }
-
-        return chunk;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isNinePatchChunk(byte[] chunk) {
-        NinePatchChunk chunkObject = getChunk(chunk);
-        if (chunkObject != null) {
-            return true;
-        }
-
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int validateNinePatchChunk(int bitmap, byte[] chunk) {
-        // the default JNI implementation only checks that the byte[] has the same
-        // size as the C struct it represent. Since we cannot do the same check (serialization
-        // will return different size depending on content), we do nothing.
-        NinePatch_Delegate newDelegate = new NinePatch_Delegate();
-        newDelegate.chunk = chunk;
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    /*package*/ static void nativeFinalize(int chunk) {
-        sManager.removeJavaReferenceFor(chunk);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDraw(int canvas_instance, RectF loc, int bitmap_instance,
-            int chunk, int paint_instance_or_null, int destDensity, int srcDensity) {
-        draw(canvas_instance,
-                (int) loc.left, (int) loc.top, (int) loc.width(), (int) loc.height(),
-                bitmap_instance, chunk, paint_instance_or_null,
-                destDensity, srcDensity);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDraw(int canvas_instance, Rect loc, int bitmap_instance,
-            int chunk, int paint_instance_or_null, int destDensity, int srcDensity) {
-        draw(canvas_instance,
-                loc.left, loc.top, loc.width(), loc.height(),
-                bitmap_instance, chunk, paint_instance_or_null,
-                destDensity, srcDensity);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetTransparentRegion(int bitmap, int chunk, Rect location) {
-        return 0;
-    }
-
-    // ---- Private Helper methods ----
-
-    private static void draw(int canvas_instance,
-            final int left, final int top, final int right, final int bottom,
-            int bitmap_instance, int chunk, int paint_instance_or_null,
-            final int destDensity, final int srcDensity) {
-        // get the delegate from the native int.
-        final Bitmap_Delegate bitmap_delegate = Bitmap_Delegate.getDelegate(bitmap_instance);
-        if (bitmap_delegate == null) {
-            return;
-        }
-
-        byte[] c = null;
-        NinePatch_Delegate delegate = sManager.getDelegate(chunk);
-        if (delegate != null) {
-            c = delegate.chunk;
-        }
-        if (c == null) {
-            // not a 9-patch?
-            BufferedImage image = bitmap_delegate.getImage();
-            Canvas_Delegate.native_drawBitmap(canvas_instance, bitmap_instance,
-                    new Rect(0, 0, image.getWidth(), image.getHeight()),
-                    new Rect(left, top, right, bottom),
-                    paint_instance_or_null, destDensity, srcDensity);
-            return;
-        }
-
-        final NinePatchChunk chunkObject = getChunk(c);
-        assert chunkObject != null;
-        if (chunkObject == null) {
-            return;
-        }
-
-        Canvas_Delegate canvas_delegate = Canvas_Delegate.getDelegate(canvas_instance);
-        if (canvas_delegate == null) {
-            return;
-        }
-
-        // this one can be null
-        Paint_Delegate paint_delegate = Paint_Delegate.getDelegate(paint_instance_or_null);
-
-        canvas_delegate.getSnapshot().draw(new GcSnapshot.Drawable() {
-                @Override
-                public void draw(Graphics2D graphics, Paint_Delegate paint) {
-                    chunkObject.draw(bitmap_delegate.getImage(), graphics,
-                            left, top, right - left, bottom - top, destDensity, srcDensity);
-                }
-            }, paint_delegate, true /*compositeOnly*/, false /*forceSrcMode*/);
-
-     }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java
deleted file mode 100644
index 71d346a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.PaintFlagsDrawFilter
- *
- * Through the layoutlib_create tool, the original native methods of PaintFlagsDrawFilter have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PaintFlagsDrawFilter class.
- *
- * Because this extends {@link DrawFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the DrawFilter classes will be added to the manager owned by
- * {@link DrawFilter_Delegate}.
- *
- * @see DrawFilter_Delegate
- *
- */
-public class PaintFlagsDrawFilter_Delegate extends DrawFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Paint Flags Draw Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeConstructor(int clearBits, int setBits) {
-        PaintFlagsDrawFilter_Delegate newDelegate = new PaintFlagsDrawFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
deleted file mode 100644
index 41953ed..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ /dev/null
@@ -1,1208 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Paint.FontMetrics;
-import android.graphics.Paint.FontMetricsInt;
-import android.text.TextUtils;
-
-import java.awt.BasicStroke;
-import java.awt.Font;
-import java.awt.Shape;
-import java.awt.Stroke;
-import java.awt.Toolkit;
-import java.awt.font.FontRenderContext;
-import java.awt.geom.AffineTransform;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Delegate implementing the native methods of android.graphics.Paint
- *
- * Through the layoutlib_create tool, the original native methods of Paint have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Paint class.
- *
- * @see DelegateManager
- *
- */
-public class Paint_Delegate {
-
-    /**
-     * Class associating a {@link Font} and it's {@link java.awt.FontMetrics}.
-     */
-    /*package*/ static final class FontInfo {
-        Font mFont;
-        java.awt.FontMetrics mMetrics;
-    }
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Paint_Delegate> sManager =
-            new DelegateManager<Paint_Delegate>(Paint_Delegate.class);
-
-    // ---- delegate helper data ----
-    private List<FontInfo> mFonts;
-    private final FontRenderContext mFontContext = new FontRenderContext(
-            new AffineTransform(), true, true);
-
-    // ---- delegate data ----
-    private int mFlags;
-    private int mColor;
-    private int mStyle;
-    private int mCap;
-    private int mJoin;
-    private int mTextAlign;
-    private Typeface_Delegate mTypeface;
-    private float mStrokeWidth;
-    private float mStrokeMiter;
-    private float mTextSize;
-    private float mTextScaleX;
-    private float mTextSkewX;
-    private int mHintingMode = Paint.HINTING_ON;
-
-    private Xfermode_Delegate mXfermode;
-    private ColorFilter_Delegate mColorFilter;
-    private Shader_Delegate mShader;
-    private PathEffect_Delegate mPathEffect;
-    private MaskFilter_Delegate mMaskFilter;
-    private Rasterizer_Delegate mRasterizer;
-
-    private Locale mLocale = Locale.getDefault();
-
-
-    // ---- Public Helper methods ----
-
-    public static Paint_Delegate getDelegate(int native_paint) {
-        return sManager.getDelegate(native_paint);
-    }
-
-    /**
-     * Returns the list of {@link Font} objects. The first item is the main font, the rest
-     * are fall backs for characters not present in the main font.
-     */
-    public List<FontInfo> getFonts() {
-        return mFonts;
-    }
-
-    public boolean isAntiAliased() {
-        return (mFlags & Paint.ANTI_ALIAS_FLAG) != 0;
-    }
-
-    public boolean isFilterBitmap() {
-        return (mFlags & Paint.FILTER_BITMAP_FLAG) != 0;
-    }
-
-    public int getStyle() {
-        return mStyle;
-    }
-
-    public int getColor() {
-        return mColor;
-    }
-
-    public int getAlpha() {
-        return mColor >>> 24;
-    }
-
-    public void setAlpha(int alpha) {
-        mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
-    }
-
-    public int getTextAlign() {
-        return mTextAlign;
-    }
-
-    public float getStrokeWidth() {
-        return mStrokeWidth;
-    }
-
-    /**
-     * returns the value of stroke miter needed by the java api.
-     */
-    public float getJavaStrokeMiter() {
-        float miter = mStrokeMiter * mStrokeWidth;
-        if (miter < 1.f) {
-            miter = 1.f;
-        }
-        return miter;
-    }
-
-    public int getJavaCap() {
-        switch (Paint.sCapArray[mCap]) {
-            case BUTT:
-                return BasicStroke.CAP_BUTT;
-            case ROUND:
-                return BasicStroke.CAP_ROUND;
-            default:
-            case SQUARE:
-                return BasicStroke.CAP_SQUARE;
-        }
-    }
-
-    public int getJavaJoin() {
-        switch (Paint.sJoinArray[mJoin]) {
-            default:
-            case MITER:
-                return BasicStroke.JOIN_MITER;
-            case ROUND:
-                return BasicStroke.JOIN_ROUND;
-            case BEVEL:
-                return BasicStroke.JOIN_BEVEL;
-        }
-    }
-
-    public Stroke getJavaStroke() {
-        if (mPathEffect != null) {
-            if (mPathEffect.isSupported()) {
-                Stroke stroke = mPathEffect.getStroke(this);
-                assert stroke != null;
-                if (stroke != null) {
-                    return stroke;
-                }
-            } else {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
-                        mPathEffect.getSupportMessage(),
-                        null, null /*data*/);
-            }
-        }
-
-        // if no custom stroke as been set, set the default one.
-        return new BasicStroke(
-                    getStrokeWidth(),
-                    getJavaCap(),
-                    getJavaJoin(),
-                    getJavaStrokeMiter());
-    }
-
-    /**
-     * Returns the {@link Xfermode} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public Xfermode_Delegate getXfermode() {
-        return mXfermode;
-    }
-
-    /**
-     * Returns the {@link ColorFilter} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public ColorFilter_Delegate getColorFilter() {
-        return mColorFilter;
-    }
-
-    /**
-     * Returns the {@link Shader} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public Shader_Delegate getShader() {
-        return mShader;
-    }
-
-    /**
-     * Returns the {@link MaskFilter} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public MaskFilter_Delegate getMaskFilter() {
-        return mMaskFilter;
-    }
-
-    /**
-     * Returns the {@link Rasterizer} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public Rasterizer_Delegate getRasterizer() {
-        return mRasterizer;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int getFlags(Paint thisPaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mFlags;
-    }
-
-
-
-    @LayoutlibDelegate
-    /*package*/ static void setFlags(Paint thisPaint, int flags) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mFlags = flags;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setFilterBitmap(Paint thisPaint, boolean filter) {
-        setFlag(thisPaint, Paint.FILTER_BITMAP_FLAG, filter);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getHinting(Paint thisPaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return Paint.HINTING_ON;
-        }
-
-        return delegate.mHintingMode;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setHinting(Paint thisPaint, int mode) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mHintingMode = mode;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setAntiAlias(Paint thisPaint, boolean aa) {
-        setFlag(thisPaint, Paint.ANTI_ALIAS_FLAG, aa);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setSubpixelText(Paint thisPaint, boolean subpixelText) {
-        setFlag(thisPaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setUnderlineText(Paint thisPaint, boolean underlineText) {
-        setFlag(thisPaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setStrikeThruText(Paint thisPaint, boolean strikeThruText) {
-        setFlag(thisPaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setFakeBoldText(Paint thisPaint, boolean fakeBoldText) {
-        setFlag(thisPaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setDither(Paint thisPaint, boolean dither) {
-        setFlag(thisPaint, Paint.DITHER_FLAG, dither);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setLinearText(Paint thisPaint, boolean linearText) {
-        setFlag(thisPaint, Paint.LINEAR_TEXT_FLAG, linearText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getColor(Paint thisPaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mColor;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setColor(Paint thisPaint, int color) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mColor = color;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getAlpha(Paint thisPaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.getAlpha();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setAlpha(Paint thisPaint, int a) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.setAlpha(a);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float getStrokeWidth(Paint thisPaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mStrokeWidth;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setStrokeWidth(Paint thisPaint, float width) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mStrokeWidth = width;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float getStrokeMiter(Paint thisPaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mStrokeMiter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setStrokeMiter(Paint thisPaint, float miter) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mStrokeMiter = miter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetShadowLayer(Paint thisPaint, float radius, float dx, float dy,
-            int color) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.setShadowLayer is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float getTextSize(Paint thisPaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mTextSize;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setTextSize(Paint thisPaint, float textSize) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mTextSize = textSize;
-        delegate.updateFontObject();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float getTextScaleX(Paint thisPaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mTextScaleX;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setTextScaleX(Paint thisPaint, float scaleX) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mTextScaleX = scaleX;
-        delegate.updateFontObject();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float getTextSkewX(Paint thisPaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mTextSkewX;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setTextSkewX(Paint thisPaint, float skewX) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mTextSkewX = skewX;
-        delegate.updateFontObject();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float ascent(Paint thisPaint) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            // Android expects negative ascent so we invert the value from Java.
-            return - javaMetrics.getAscent();
-        }
-
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float descent(Paint thisPaint) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            return javaMetrics.getDescent();
-        }
-
-        return 0;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float getFontMetrics(Paint thisPaint, FontMetrics metrics) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.getFontMetrics(metrics);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getFontMetricsInt(Paint thisPaint, FontMetricsInt fmi) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            if (fmi != null) {
-                // Android expects negative ascent so we invert the value from Java.
-                fmi.top = - javaMetrics.getMaxAscent();
-                fmi.ascent = - javaMetrics.getAscent();
-                fmi.descent = javaMetrics.getDescent();
-                fmi.bottom = javaMetrics.getMaxDescent();
-                fmi.leading = javaMetrics.getLeading();
-            }
-
-            return javaMetrics.getHeight();
-        }
-
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float native_measureText(Paint thisPaint, char[] text, int index,
-            int count, int bidiFlags) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.measureText(text, index, count, isRtl(bidiFlags));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float native_measureText(Paint thisPaint, String text, int start, int end,
-        int bidiFlags) {
-        return native_measureText(thisPaint, text.toCharArray(), start, end - start, bidiFlags);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float native_measureText(Paint thisPaint, String text, int bidiFlags) {
-        return native_measureText(thisPaint, text.toCharArray(), 0, text.length(), bidiFlags);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_breakText(Paint thisPaint, char[] text, int index, int count,
-            float maxWidth, int bidiFlags, float[] measuredWidth) {
-
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        int inc = count > 0 ? 1 : -1;
-
-        int measureIndex = 0;
-        float measureAcc = 0;
-        for (int i = index; i != index + count; i += inc, measureIndex++) {
-            int start, end;
-            if (i < index) {
-                start = i;
-                end = index;
-            } else {
-                start = index;
-                end = i;
-            }
-
-            // measure from start to end
-            float res = delegate.measureText(text, start, end - start + 1, isRtl(bidiFlags));
-
-            if (measuredWidth != null) {
-                measuredWidth[measureIndex] = res;
-            }
-
-            measureAcc += res;
-            if (res > maxWidth) {
-                // we should not return this char index, but since it's 0-based
-                // and we need to return a count, we simply return measureIndex;
-                return measureIndex;
-            }
-
-        }
-
-        return measureIndex;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_breakText(Paint thisPaint, String text, boolean measureForwards,
-            float maxWidth, int bidiFlags, float[] measuredWidth) {
-        return native_breakText(thisPaint, text.toCharArray(), 0, text.length(), maxWidth,
-                bidiFlags, measuredWidth);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_init() {
-        Paint_Delegate newDelegate = new Paint_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_initWithPaint(int paint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(paint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        Paint_Delegate newDelegate = new Paint_Delegate(delegate);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_reset(int native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.reset();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_set(int native_dst, int native_src) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
-        if (delegate_dst == null) {
-            return;
-        }
-
-        // get the delegate from the native int.
-        Paint_Delegate delegate_src = sManager.getDelegate(native_src);
-        if (delegate_src == null) {
-            return;
-        }
-
-        delegate_dst.set(delegate_src);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_getStyle(int native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mStyle;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setStyle(int native_object, int style) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mStyle = style;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_getStrokeCap(int native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mCap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setStrokeCap(int native_object, int cap) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mCap = cap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_getStrokeJoin(int native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mJoin;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setStrokeJoin(int native_object, int join) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mJoin = join;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_getFillPath(int native_object, int src, int dst) {
-        Paint_Delegate paint = sManager.getDelegate(native_object);
-        if (paint == null) {
-            return false;
-        }
-
-        Path_Delegate srcPath = Path_Delegate.getDelegate(src);
-        if (srcPath == null) {
-            return true;
-        }
-
-        Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
-        if (dstPath == null) {
-            return true;
-        }
-
-        Stroke stroke = paint.getJavaStroke();
-        Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
-
-        dstPath.setJavaShape(strokeShape);
-
-        // FIXME figure out the return value?
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_setShader(int native_object, int shader) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return shader;
-        }
-
-        delegate.mShader = Shader_Delegate.getDelegate(shader);
-
-        return shader;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_setColorFilter(int native_object, int filter) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return filter;
-        }
-
-        delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);;
-
-        // since none of those are supported, display a fidelity warning right away
-        if (delegate.mColorFilter != null && delegate.mColorFilter.isSupported() == false) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
-                    delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
-        }
-
-        return filter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_setXfermode(int native_object, int xfermode) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return xfermode;
-        }
-
-        delegate.mXfermode = Xfermode_Delegate.getDelegate(xfermode);
-
-        return xfermode;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_setPathEffect(int native_object, int effect) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return effect;
-        }
-
-        delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
-
-        return effect;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_setMaskFilter(int native_object, int maskfilter) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return maskfilter;
-        }
-
-        delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
-
-        // since none of those are supported, display a fidelity warning right away
-        if (delegate.mMaskFilter != null && delegate.mMaskFilter.isSupported() == false) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
-                    delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
-        }
-
-        return maskfilter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_setTypeface(int native_object, int typeface) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
-        delegate.updateFontObject();
-        return typeface;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_setRasterizer(int native_object, int rasterizer) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return rasterizer;
-        }
-
-        delegate.mRasterizer = Rasterizer_Delegate.getDelegate(rasterizer);
-
-        // since none of those are supported, display a fidelity warning right away
-        if (delegate.mRasterizer != null && delegate.mRasterizer.isSupported() == false) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_RASTERIZER,
-                    delegate.mRasterizer.getSupportMessage(), null, null /*data*/);
-        }
-
-        return rasterizer;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_getTextAlign(int native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mTextAlign;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setTextAlign(int native_object, int align) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mTextAlign = align;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setTextLocale(int native_object, String locale) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.setTextLocale(locale);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_getTextWidths(int native_object, char[] text, int index,
-            int count, int bidiFlags, float[] widths) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            // FIXME: handle multi-char characters (see measureText)
-            float totalAdvance = 0;
-            for (int i = 0; i < count; i++) {
-                char c = text[i + index];
-                boolean found = false;
-                for (FontInfo info : delegate.mFonts) {
-                    if (info.mFont.canDisplay(c)) {
-                        float adv = info.mMetrics.charWidth(c);
-                        totalAdvance += adv;
-                        if (widths != null) {
-                            widths[i] = adv;
-                        }
-
-                        found = true;
-                        break;
-                    }
-                }
-
-                if (found == false) {
-                    // no advance for this char.
-                    if (widths != null) {
-                        widths[i] = 0.f;
-                    }
-                }
-            }
-
-            return (int) totalAdvance;
-        }
-
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_getTextWidths(int native_object, String text, int start,
-            int end, int bidiFlags, float[] widths) {
-        return native_getTextWidths(native_object, text.toCharArray(), start, end - start,
-                bidiFlags, widths);
-    }
-
-    @LayoutlibDelegate
-    /* package */static int native_getTextGlyphs(int native_object, String text, int start,
-            int end, int contextStart, int contextEnd, int flags, char[] glyphs) {
-        // FIXME
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float native_getTextRunAdvances(int native_object,
-            char[] text, int index, int count, int contextIndex, int contextCount,
-            int flags, float[] advances, int advancesIndex) {
-
-        if (advances != null)
-            for (int i = advancesIndex; i< advancesIndex+count; i++)
-                advances[i]=0;
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null || delegate.mFonts == null || delegate.mFonts.size() == 0) {
-            return 0.f;
-        }
-        boolean isRtl = isRtl(flags);
-
-        int limit = index + count;
-        return new BidiRenderer(null, delegate, text).renderText(
-                index, limit, isRtl, advances, advancesIndex, false, 0, 0);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float native_getTextRunAdvances(int native_object,
-            String text, int start, int end, int contextStart, int contextEnd,
-            int flags, float[] advances, int advancesIndex) {
-        // FIXME: support contextStart and contextEnd
-        int count = end - start;
-        char[] buffer = TemporaryBuffer.obtain(count);
-        TextUtils.getChars(text, start, end, buffer, 0);
-
-        return native_getTextRunAdvances(native_object, buffer, 0, count, contextStart,
-                contextEnd - contextStart, flags, advances, advancesIndex);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_getTextRunCursor(Paint thisPaint, int native_object, char[] text,
-            int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextRunCursor is not supported.", null, null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_getTextRunCursor(Paint thisPaint, int native_object, String text,
-            int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextRunCursor is not supported.", null, null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_getTextPath(int native_object, int bidiFlags,
-                char[] text, int index, int count, float x, float y, int path) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_getTextPath(int native_object, int bidiFlags,
-            String text, int start, int end, float x, float y, int path) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeGetStringBounds(int nativePaint, String text, int start,
-            int end, int bidiFlags, Rect bounds) {
-        nativeGetCharArrayBounds(nativePaint, text.toCharArray(), start, end - start, bidiFlags,
-                bounds);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeGetCharArrayBounds(int nativePaint, char[] text, int index,
-            int count, int bidiFlags, Rect bounds) {
-
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null || delegate.mFonts == null || delegate.mFonts.size() == 0) {
-            return;
-        }
-        int w = (int) delegate.measureText(text, index, count, isRtl(bidiFlags));
-        int h= delegate.getFonts().get(0).mMetrics.getHeight();
-        bounds.set(0, 0, w, h);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void finalizer(int nativePaint) {
-        sManager.removeJavaReferenceFor(nativePaint);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /*package*/ Paint_Delegate() {
-        reset();
-    }
-
-    private Paint_Delegate(Paint_Delegate paint) {
-        set(paint);
-    }
-
-    private void set(Paint_Delegate paint) {
-        mFlags = paint.mFlags;
-        mColor = paint.mColor;
-        mStyle = paint.mStyle;
-        mCap = paint.mCap;
-        mJoin = paint.mJoin;
-        mTextAlign = paint.mTextAlign;
-        mTypeface = paint.mTypeface;
-        mStrokeWidth = paint.mStrokeWidth;
-        mStrokeMiter = paint.mStrokeMiter;
-        mTextSize = paint.mTextSize;
-        mTextScaleX = paint.mTextScaleX;
-        mTextSkewX = paint.mTextSkewX;
-        mXfermode = paint.mXfermode;
-        mColorFilter = paint.mColorFilter;
-        mShader = paint.mShader;
-        mPathEffect = paint.mPathEffect;
-        mMaskFilter = paint.mMaskFilter;
-        mRasterizer = paint.mRasterizer;
-        mHintingMode = paint.mHintingMode;
-        updateFontObject();
-    }
-
-    private void reset() {
-        mFlags = Paint.DEFAULT_PAINT_FLAGS;
-        mColor = 0xFF000000;
-        mStyle = Paint.Style.FILL.nativeInt;
-        mCap = Paint.Cap.BUTT.nativeInt;
-        mJoin = Paint.Join.MITER.nativeInt;
-        mTextAlign = 0;
-        mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
-        mStrokeWidth = 1.f;
-        mStrokeMiter = 4.f;
-        mTextSize = 20.f;
-        mTextScaleX = 1.f;
-        mTextSkewX = 0.f;
-        mXfermode = null;
-        mColorFilter = null;
-        mShader = null;
-        mPathEffect = null;
-        mMaskFilter = null;
-        mRasterizer = null;
-        updateFontObject();
-        mHintingMode = Paint.HINTING_ON;
-    }
-
-    /**
-     * Update the {@link Font} object from the typeface, text size and scaling
-     */
-    @SuppressWarnings("deprecation")
-    private void updateFontObject() {
-        if (mTypeface != null) {
-            // Get the fonts from the TypeFace object.
-            List<Font> fonts = mTypeface.getFonts();
-
-            // create new font objects as well as FontMetrics, based on the current text size
-            // and skew info.
-            ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(fonts.size());
-            for (Font font : fonts) {
-                FontInfo info = new FontInfo();
-                info.mFont = font.deriveFont(mTextSize);
-                if (mTextScaleX != 1.0 || mTextSkewX != 0) {
-                    // TODO: support skew
-                    info.mFont = info.mFont.deriveFont(new AffineTransform(
-                            mTextScaleX, mTextSkewX, 0, 1, 0, 0));
-                }
-                // The metrics here don't have anti-aliasing set.
-                info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
-
-                infoList.add(info);
-            }
-
-            mFonts = Collections.unmodifiableList(infoList);
-        }
-    }
-
-    /*package*/ float measureText(char[] text, int index, int count, boolean isRtl) {
-        return new BidiRenderer(null, this, text).renderText(
-                index, index + count, isRtl, null, 0, false, 0, 0);
-    }
-
-    private float getFontMetrics(FontMetrics metrics) {
-        if (mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
-            if (metrics != null) {
-                // Android expects negative ascent so we invert the value from Java.
-                metrics.top = - javaMetrics.getMaxAscent();
-                metrics.ascent = - javaMetrics.getAscent();
-                metrics.descent = javaMetrics.getDescent();
-                metrics.bottom = javaMetrics.getMaxDescent();
-                metrics.leading = javaMetrics.getLeading();
-            }
-
-            return javaMetrics.getHeight();
-        }
-
-        return 0;
-    }
-
-    private void setTextLocale(String locale) {
-        mLocale = new Locale(locale);
-    }
-
-    private static void setFlag(Paint thisPaint, int flagMask, boolean flagValue) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (flagValue) {
-            delegate.mFlags |= flagMask;
-        } else {
-            delegate.mFlags &= ~flagMask;
-        }
-    }
-
-    private static boolean isRtl(int flag) {
-        switch(flag) {
-        case Paint.BIDI_RTL:
-        case Paint.BIDI_FORCE_RTL:
-        case Paint.BIDI_DEFAULT_RTL:
-            return true;
-        default:
-            return false;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java
deleted file mode 100644
index c448f0e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.PathDashPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of PathDashPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PathDashPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class PathDashPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Path Dash Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate(int native_path, float advance, float phase,
-            int native_style) {
-        PathDashPathEffect_Delegate newDelegate = new PathDashPathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
deleted file mode 100644
index bd2b6de..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.PathEffect
- *
- * Through the layoutlib_create tool, the original native methods of PathEffect have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PathEffect class.
- *
- * This also serve as a base class for all PathEffect delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class PathEffect_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<PathEffect_Delegate> sManager =
-            new DelegateManager<PathEffect_Delegate>(PathEffect_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static PathEffect_Delegate getDelegate(int nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract Stroke getStroke(Paint_Delegate paint);
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(int native_patheffect) {
-        sManager.removeJavaReferenceFor(native_patheffect);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
deleted file mode 100644
index 64f19d3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ /dev/null
@@ -1,815 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Path.Direction;
-import android.graphics.Path.FillType;
-
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Arc2D;
-import java.awt.geom.Area;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.RoundRectangle2D;
-
-/**
- * Delegate implementing the native methods of android.graphics.Path
- *
- * Through the layoutlib_create tool, the original native methods of Path have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Path class.
- *
- * @see DelegateManager
- *
- */
-public final class Path_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Path_Delegate> sManager =
-            new DelegateManager<Path_Delegate>(Path_Delegate.class);
-
-    // ---- delegate data ----
-    private FillType mFillType = FillType.WINDING;
-    private GeneralPath mPath = new GeneralPath();
-
-    private float mLastX = 0;
-    private float mLastY = 0;
-
-    // ---- Public Helper methods ----
-
-    public static Path_Delegate getDelegate(int nPath) {
-        return sManager.getDelegate(nPath);
-    }
-
-    public Shape getJavaShape() {
-        return mPath;
-    }
-
-    public void setJavaShape(Shape shape) {
-        mPath.reset();
-        mPath.append(shape, false /*connect*/);
-    }
-
-    public void reset() {
-        mPath.reset();
-    }
-
-    public void setPathIterator(PathIterator iterator) {
-        mPath.reset();
-        mPath.append(iterator, false /*connect*/);
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int init1() {
-        // create the delegate
-        Path_Delegate newDelegate = new Path_Delegate();
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int init2(int nPath) {
-        // create the delegate
-        Path_Delegate newDelegate = new Path_Delegate();
-
-        // get the delegate to copy, which could be null if nPath is 0
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate != null) {
-            newDelegate.set(pathDelegate);
-        }
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_reset(int nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mPath.reset();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_rewind(int nPath) {
-        // call out to reset since there's nothing to optimize in
-        // terms of data structs.
-        native_reset(nPath);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_set(int native_dst, int native_src) {
-        Path_Delegate pathDstDelegate = sManager.getDelegate(native_dst);
-        if (pathDstDelegate == null) {
-            return;
-        }
-
-        Path_Delegate pathSrcDelegate = sManager.getDelegate(native_src);
-        if (pathSrcDelegate == null) {
-            return;
-        }
-
-        pathDstDelegate.set(pathSrcDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int native_getFillType(int nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return 0;
-        }
-
-        return pathDelegate.mFillType.nativeInt;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setFillType(int nPath, int ft) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mFillType = Path.sFillTypeArray[ft];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_isEmpty(int nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return true;
-        }
-
-        return pathDelegate.isEmpty();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_isRect(int nPath, RectF rect) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return false;
-        }
-
-        // create an Area that can test if the path is a rect
-        Area area = new Area(pathDelegate.mPath);
-        if (area.isRectangular()) {
-            if (rect != null) {
-                pathDelegate.fillBounds(rect);
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_computeBounds(int nPath, RectF bounds) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.fillBounds(bounds);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_incReserve(int nPath, int extraPtCount) {
-        // since we use a java2D path, there's no way to pre-allocate new points,
-        // so we do nothing.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_moveTo(int nPath, float x, float y) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.moveTo(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_rMoveTo(int nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rMoveTo(dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_lineTo(int nPath, float x, float y) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.lineTo(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_rLineTo(int nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rLineTo(dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_quadTo(int nPath, float x1, float y1, float x2, float y2) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.quadTo(x1, y1, x2, y2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_rQuadTo(int nPath, float dx1, float dy1, float dx2, float dy2) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rQuadTo(dx1, dy1, dx2, dy2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_cubicTo(int nPath, float x1, float y1,
-            float x2, float y2, float x3, float y3) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.cubicTo(x1, y1, x2, y2, x3, y3);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_rCubicTo(int nPath, float x1, float y1,
-            float x2, float y2, float x3, float y3) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rCubicTo(x1, y1, x2, y2, x3, y3);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_arcTo(int nPath, RectF oval,
-                    float startAngle, float sweepAngle, boolean forceMoveTo) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.arcTo(oval, startAngle, sweepAngle, forceMoveTo);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_close(int nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.close();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_addRect(int nPath, RectF rect, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.addRect(rect.left, rect.top, rect.right, rect.bottom, dir);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_addRect(int nPath,
-            float left, float top, float right, float bottom, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.addRect(left, top, right, bottom, dir);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_addOval(int nPath, RectF oval, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mPath.append(new Ellipse2D.Float(
-                oval.left, oval.top, oval.width(), oval.height()), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_addCircle(int nPath, float x, float y, float radius, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        // because x/y is the center of the circle, need to offset this by the radius
-        pathDelegate.mPath.append(new Ellipse2D.Float(
-                x - radius, y - radius, radius * 2, radius * 2), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_addArc(int nPath, RectF oval,
-            float startAngle, float sweepAngle) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        // because x/y is the center of the circle, need to offset this by the radius
-        pathDelegate.mPath.append(new Arc2D.Float(
-                oval.left, oval.top, oval.width(), oval.height(),
-                -startAngle, -sweepAngle, Arc2D.OPEN), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_addRoundRect(
-            int nPath, RectF rect, float rx, float ry, int dir) {
-
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mPath.append(new RoundRectangle2D.Float(
-                rect.left, rect.top, rect.width(), rect.height(), rx * 2, ry * 2), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_addRoundRect(int nPath, RectF rect, float[] radii, int dir) {
-        // Java2D doesn't support different rounded corners in each corner, so just use the
-        // first value.
-        native_addRoundRect(nPath, rect, radii[0], radii[1], dir);
-
-        // there can be a case where this API is used but with similar values for all corners, so
-        // in that case we don't warn.
-        // we only care if 2 corners are different so just compare to the next one.
-        for (int i = 0 ; i < 3 ; i++) {
-            if (radii[i * 2] != radii[(i + 1) * 2] || radii[i * 2 + 1] != radii[(i + 1) * 2 + 1]) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                        "Different corner sizes are not supported in Path.addRoundRect.",
-                        null, null /*data*/);
-                break;
-            }
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_addPath(int nPath, int src, float dx, float dy) {
-        addPath(nPath, src, AffineTransform.getTranslateInstance(dx, dy));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_addPath(int nPath, int src) {
-        addPath(nPath, src, null /*transform*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_addPath(int nPath, int src, int matrix) {
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        addPath(nPath, src, matrixDelegate.getAffineTransform());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_offset(int nPath, float dx, float dy, int dst_path) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        // could be null if the int is 0;
-        Path_Delegate dstDelegate = sManager.getDelegate(dst_path);
-
-        pathDelegate.offset(dx, dy, dstDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_offset(int nPath, float dx, float dy) {
-        native_offset(nPath, dx, dy, 0);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setLastPoint(int nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mLastX = dx;
-        pathDelegate.mLastY = dy;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_transform(int nPath, int matrix,
-                                                int dst_path) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        // this can be null if dst_path is 0
-        Path_Delegate dstDelegate = sManager.getDelegate(dst_path);
-
-        pathDelegate.transform(matrixDelegate, dstDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_transform(int nPath, int matrix) {
-        native_transform(nPath, matrix, 0);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void finalizer(int nPath) {
-        sManager.removeJavaReferenceFor(nPath);
-    }
-
-
-    // ---- Private helper methods ----
-
-    private void set(Path_Delegate delegate) {
-        mPath.reset();
-        setFillType(delegate.mFillType);
-        mPath.append(delegate.mPath, false /*connect*/);
-    }
-
-    private void setFillType(FillType fillType) {
-        mFillType = fillType;
-        mPath.setWindingRule(getWindingRule(fillType));
-    }
-
-    /**
-     * Returns the Java2D winding rules matching a given Android {@link FillType}.
-     * @param type the android fill type
-     * @return the matching java2d winding rule.
-     */
-    private static int getWindingRule(FillType type) {
-        switch (type) {
-            case WINDING:
-            case INVERSE_WINDING:
-                return GeneralPath.WIND_NON_ZERO;
-            case EVEN_ODD:
-            case INVERSE_EVEN_ODD:
-                return GeneralPath.WIND_EVEN_ODD;
-        }
-
-        assert false;
-        throw new IllegalArgumentException();
-    }
-
-    private static Direction getDirection(int direction) {
-        for (Direction d : Direction.values()) {
-            if (direction == d.nativeInt) {
-                return d;
-            }
-        }
-
-        assert false;
-        return null;
-    }
-
-    private static void addPath(int destPath, int srcPath, AffineTransform transform) {
-        Path_Delegate destPathDelegate = sManager.getDelegate(destPath);
-        if (destPathDelegate == null) {
-            return;
-        }
-
-        Path_Delegate srcPathDelegate = sManager.getDelegate(srcPath);
-        if (srcPathDelegate == null) {
-            return;
-        }
-
-        if (transform != null) {
-            destPathDelegate.mPath.append(
-                    srcPathDelegate.mPath.getPathIterator(transform), false);
-        } else {
-            destPathDelegate.mPath.append(srcPathDelegate.mPath, false);
-        }
-    }
-
-
-    /**
-     * Returns whether the path is empty.
-     * @return true if the path is empty.
-     */
-    private boolean isEmpty() {
-        return mPath.getCurrentPoint() == null;
-    }
-
-    /**
-     * Fills the given {@link RectF} with the path bounds.
-     * @param bounds the RectF to be filled.
-     */
-    private void fillBounds(RectF bounds) {
-        Rectangle2D rect = mPath.getBounds2D();
-        bounds.left = (float)rect.getMinX();
-        bounds.right = (float)rect.getMaxX();
-        bounds.top = (float)rect.getMinY();
-        bounds.bottom = (float)rect.getMaxY();
-    }
-
-    /**
-     * Set the beginning of the next contour to the point (x,y).
-     *
-     * @param x The x-coordinate of the start of a new contour
-     * @param y The y-coordinate of the start of a new contour
-     */
-    private void moveTo(float x, float y) {
-        mPath.moveTo(mLastX = x, mLastY = y);
-    }
-
-    /**
-     * Set the beginning of the next contour relative to the last point on the
-     * previous contour. If there is no previous contour, this is treated the
-     * same as moveTo().
-     *
-     * @param dx The amount to add to the x-coordinate of the end of the
-     *           previous contour, to specify the start of a new contour
-     * @param dy The amount to add to the y-coordinate of the end of the
-     *           previous contour, to specify the start of a new contour
-     */
-    private void rMoveTo(float dx, float dy) {
-        dx += mLastX;
-        dy += mLastY;
-        mPath.moveTo(mLastX = dx, mLastY = dy);
-    }
-
-    /**
-     * Add a line from the last point to the specified point (x,y).
-     * If no moveTo() call has been made for this contour, the first point is
-     * automatically set to (0,0).
-     *
-     * @param x The x-coordinate of the end of a line
-     * @param y The y-coordinate of the end of a line
-     */
-    private void lineTo(float x, float y) {
-        mPath.lineTo(mLastX = x, mLastY = y);
-    }
-
-    /**
-     * Same as lineTo, but the coordinates are considered relative to the last
-     * point on this contour. If there is no previous point, then a moveTo(0,0)
-     * is inserted automatically.
-     *
-     * @param dx The amount to add to the x-coordinate of the previous point on
-     *           this contour, to specify a line
-     * @param dy The amount to add to the y-coordinate of the previous point on
-     *           this contour, to specify a line
-     */
-    private void rLineTo(float dx, float dy) {
-        if (isEmpty()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx += mLastX;
-        dy += mLastY;
-        mPath.lineTo(mLastX = dx, mLastY = dy);
-    }
-
-    /**
-     * Add a quadratic bezier from the last point, approaching control point
-     * (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
-     * this contour, the first point is automatically set to (0,0).
-     *
-     * @param x1 The x-coordinate of the control point on a quadratic curve
-     * @param y1 The y-coordinate of the control point on a quadratic curve
-     * @param x2 The x-coordinate of the end point on a quadratic curve
-     * @param y2 The y-coordinate of the end point on a quadratic curve
-     */
-    private void quadTo(float x1, float y1, float x2, float y2) {
-        mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
-    }
-
-    /**
-     * Same as quadTo, but the coordinates are considered relative to the last
-     * point on this contour. If there is no previous point, then a moveTo(0,0)
-     * is inserted automatically.
-     *
-     * @param dx1 The amount to add to the x-coordinate of the last point on
-     *            this contour, for the control point of a quadratic curve
-     * @param dy1 The amount to add to the y-coordinate of the last point on
-     *            this contour, for the control point of a quadratic curve
-     * @param dx2 The amount to add to the x-coordinate of the last point on
-     *            this contour, for the end point of a quadratic curve
-     * @param dy2 The amount to add to the y-coordinate of the last point on
-     *            this contour, for the end point of a quadratic curve
-     */
-    private void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
-        if (isEmpty()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx1 += mLastX;
-        dy1 += mLastY;
-        dx2 += mLastX;
-        dy2 += mLastY;
-        mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
-    }
-
-    /**
-     * Add a cubic bezier from the last point, approaching control points
-     * (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
-     * made for this contour, the first point is automatically set to (0,0).
-     *
-     * @param x1 The x-coordinate of the 1st control point on a cubic curve
-     * @param y1 The y-coordinate of the 1st control point on a cubic curve
-     * @param x2 The x-coordinate of the 2nd control point on a cubic curve
-     * @param y2 The y-coordinate of the 2nd control point on a cubic curve
-     * @param x3 The x-coordinate of the end point on a cubic curve
-     * @param y3 The y-coordinate of the end point on a cubic curve
-     */
-    private void cubicTo(float x1, float y1, float x2, float y2,
-                        float x3, float y3) {
-        mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
-    }
-
-    /**
-     * Same as cubicTo, but the coordinates are considered relative to the
-     * current point on this contour. If there is no previous point, then a
-     * moveTo(0,0) is inserted automatically.
-     */
-    private void rCubicTo(float dx1, float dy1, float dx2, float dy2,
-                         float dx3, float dy3) {
-        if (isEmpty()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx1 += mLastX;
-        dy1 += mLastY;
-        dx2 += mLastX;
-        dy2 += mLastY;
-        dx3 += mLastX;
-        dy3 += mLastY;
-        mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3);
-    }
-
-    /**
-     * Append the specified arc to the path as a new contour. If the start of
-     * the path is different from the path's current last point, then an
-     * automatic lineTo() is added to connect the current contour to the
-     * start of the arc. However, if the path is empty, then we call moveTo()
-     * with the first point of the arc. The sweep angle is tread mod 360.
-     *
-     * @param oval        The bounds of oval defining shape and size of the arc
-     * @param startAngle  Starting angle (in degrees) where the arc begins
-     * @param sweepAngle  Sweep angle (in degrees) measured clockwise, treated
-     *                    mod 360.
-     * @param forceMoveTo If true, always begin a new contour with the arc
-     */
-    private void arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo) {
-        Arc2D arc = new Arc2D.Float(oval.left, oval.top, oval.width(), oval.height(), -startAngle,
-                -sweepAngle, Arc2D.OPEN);
-        mPath.append(arc, true /*connect*/);
-
-        resetLastPointFromPath();
-    }
-
-    /**
-     * Close the current contour. If the current point is not equal to the
-     * first point of the contour, a line segment is automatically added.
-     */
-    private void close() {
-        mPath.closePath();
-    }
-
-    private void resetLastPointFromPath() {
-        Point2D last = mPath.getCurrentPoint();
-        mLastX = (float) last.getX();
-        mLastY = (float) last.getY();
-    }
-
-    /**
-     * Add a closed rectangle contour to the path
-     *
-     * @param left   The left side of a rectangle to add to the path
-     * @param top    The top of a rectangle to add to the path
-     * @param right  The right side of a rectangle to add to the path
-     * @param bottom The bottom of a rectangle to add to the path
-     * @param dir    The direction to wind the rectangle's contour
-     */
-    private void addRect(float left, float top, float right, float bottom,
-                        int dir) {
-        moveTo(left, top);
-
-        Direction direction = getDirection(dir);
-
-        switch (direction) {
-            case CW:
-                lineTo(right, top);
-                lineTo(right, bottom);
-                lineTo(left, bottom);
-                break;
-            case CCW:
-                lineTo(left, bottom);
-                lineTo(right, bottom);
-                lineTo(right, top);
-                break;
-        }
-
-        close();
-
-        resetLastPointFromPath();
-    }
-
-    /**
-     * Offset the path by (dx,dy), returning true on success
-     *
-     * @param dx  The amount in the X direction to offset the entire path
-     * @param dy  The amount in the Y direction to offset the entire path
-     * @param dst The translated path is written here. If this is null, then
-     *            the original path is modified.
-     */
-    public void offset(float dx, float dy, Path_Delegate dst) {
-        GeneralPath newPath = new GeneralPath();
-
-        PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
-
-        newPath.append(iterator, false /*connect*/);
-
-        if (dst != null) {
-            dst.mPath = newPath;
-        } else {
-            mPath = newPath;
-        }
-    }
-
-    /**
-     * Transform the points in this path by matrix, and write the answer
-     * into dst. If dst is null, then the the original path is modified.
-     *
-     * @param matrix The matrix to apply to the path
-     * @param dst    The transformed path is written here. If dst is null,
-     *               then the the original path is modified
-     */
-    public void transform(Matrix_Delegate matrix, Path_Delegate dst) {
-        if (matrix.hasPerspective()) {
-            assert false;
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
-                    "android.graphics.Path#transform() only " +
-                    "supports affine transformations.", null, null /*data*/);
-        }
-
-        GeneralPath newPath = new GeneralPath();
-
-        PathIterator iterator = mPath.getPathIterator(matrix.getAffineTransform());
-
-        newPath.append(iterator, false /*connect*/);
-
-        if (dst != null) {
-            dst.mPath = newPath;
-        } else {
-            mPath = newPath;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java
deleted file mode 100644
index 4ab044b..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Composite;
-
-/**
- * Delegate implementing the native methods of android.graphics.PixelXorXfermode
- *
- * Through the layoutlib_create tool, the original native methods of PixelXorXfermode have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PixelXorXfermode class.
- *
- * Because this extends {@link Xfermode_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
- * {@link Xfermode_Delegate}.
- *
- * @see Xfermode_Delegate
- */
-public class PixelXorXfermode_Delegate extends Xfermode_Delegate {
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Composite getComposite(int alpha) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Pixel XOR Xfermodes are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate(int opColor) {
-        PixelXorXfermode_Delegate newDelegate = new PixelXorXfermode_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
deleted file mode 100644
index c45dbaa..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.PorterDuffColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of PorterDuffColorFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PorterDuffColorFilter class.
- *
- * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link ColorFilter_Delegate}.
- *
- * @see ColorFilter_Delegate
- *
- */
-public class PorterDuffColorFilter_Delegate extends ColorFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "PorterDuff Color Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int native_CreatePorterDuffFilter(int srcColor, int porterDuffMode) {
-        PorterDuffColorFilter_Delegate newDelegate = new PorterDuffColorFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nCreatePorterDuffFilter(int nativeFilter, int srcColor,
-            int porterDuffMode) {
-        // pass
-        return 0;
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
deleted file mode 100644
index 4301c1a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.AlphaComposite;
-import java.awt.Composite;
-
-/**
- * Delegate implementing the native methods of android.graphics.PorterDuffXfermode
- *
- * Through the layoutlib_create tool, the original native methods of PorterDuffXfermode have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PorterDuffXfermode class.
- *
- * Because this extends {@link Xfermode_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
- * {@link Xfermode_Delegate}.
- *
- */
-public class PorterDuffXfermode_Delegate extends Xfermode_Delegate {
-
-    // ---- delegate data ----
-
-    private final int mMode;
-
-    // ---- Public Helper methods ----
-
-    public PorterDuff.Mode getMode() {
-        return getPorterDuffMode(mMode);
-    }
-
-    @Override
-    public Composite getComposite(int alpha) {
-        return getComposite(getPorterDuffMode(mMode), alpha);
-    }
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // no message since isSupported returns true;
-        return null;
-    }
-
-    public static PorterDuff.Mode getPorterDuffMode(int mode) {
-        for (PorterDuff.Mode m : PorterDuff.Mode.values()) {
-            if (m.nativeInt == mode) {
-                return m;
-            }
-        }
-
-        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                String.format("Unknown PorterDuff.Mode: %d", mode), null /*data*/);
-        assert false;
-        return PorterDuff.Mode.SRC_OVER;
-    }
-
-    public static Composite getComposite(PorterDuff.Mode mode, int alpha) {
-        float falpha = alpha != 0xFF ? (float)alpha / 255.f : 1.f;
-        switch (mode) {
-            case CLEAR:
-                return AlphaComposite.getInstance(AlphaComposite.CLEAR, falpha);
-            case DARKEN:
-                break;
-            case DST:
-                return AlphaComposite.getInstance(AlphaComposite.DST, falpha);
-            case DST_ATOP:
-                return AlphaComposite.getInstance(AlphaComposite.DST_ATOP, falpha);
-            case DST_IN:
-                return AlphaComposite.getInstance(AlphaComposite.DST_IN, falpha);
-            case DST_OUT:
-                return AlphaComposite.getInstance(AlphaComposite.DST_OUT, falpha);
-            case DST_OVER:
-                return AlphaComposite.getInstance(AlphaComposite.DST_OVER, falpha);
-            case LIGHTEN:
-                break;
-            case MULTIPLY:
-                break;
-            case SCREEN:
-                break;
-            case SRC:
-                return AlphaComposite.getInstance(AlphaComposite.SRC, falpha);
-            case SRC_ATOP:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, falpha);
-            case SRC_IN:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_IN, falpha);
-            case SRC_OUT:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_OUT, falpha);
-            case SRC_OVER:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha);
-            case XOR:
-                return AlphaComposite.getInstance(AlphaComposite.XOR, falpha);
-        }
-
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
-                String.format("Unsupported PorterDuff Mode: %s", mode.name()),
-                null, null /*data*/);
-
-        return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha);
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreateXfermode(int mode) {
-        PorterDuffXfermode_Delegate newDelegate = new PorterDuffXfermode_Delegate(mode);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private PorterDuffXfermode_Delegate(int mode) {
-        mMode = mode;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
deleted file mode 100644
index 3fe45fa..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-/**
- * Delegate implementing the native methods of android.graphics.RadialGradient
- *
- * Through the layoutlib_create tool, the original native methods of RadialGradient have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original RadialGradient class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class RadialGradient_Delegate extends Gradient_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate1(float x, float y, float radius,
-            int colors[], float positions[], int tileMode) {
-        RadialGradient_Delegate newDelegate = new RadialGradient_Delegate(x, y, radius,
-                colors, positions, Shader_Delegate.getTileMode(tileMode));
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate2(float x, float y, float radius,
-            int color0, int color1, int tileMode) {
-        return nativeCreate1(x, y, radius, new int[] { color0, color1 }, null /*positions*/,
-                tileMode);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativePostCreate1(int native_shader, float x, float y, float radius,
-            int colors[], float positions[], int tileMode) {
-        // nothing to be done here.
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativePostCreate2(int native_shader, float x, float y, float radius,
-            int color0, int color1, int tileMode) {
-        // nothing to be done here.
-        return 0;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * Create a shader that draws a radial gradient given the center and radius.
-     *
-     * @param x The x-coordinate of the center of the radius
-     * @param y The y-coordinate of the center of the radius
-     * @param radius Must be positive. The radius of the circle for this
-     *            gradient
-     * @param colors The colors to be distributed between the center and edge of
-     *            the circle
-     * @param positions May be NULL. The relative position of each corresponding
-     *            color in the colors array. If this is NULL, the the colors are
-     *            distributed evenly between the center and edge of the circle.
-     * @param tile The Shader tiling mode
-     */
-    private RadialGradient_Delegate(float x, float y, float radius, int colors[], float positions[],
-            TileMode tile) {
-        super(colors, positions);
-        mJavaPaint = new RadialGradientPaint(x, y, radius, mColors, mPositions, tile);
-    }
-
-    private class RadialGradientPaint extends GradientPaint {
-
-        private final float mX;
-        private final float mY;
-        private final float mRadius;
-
-        public RadialGradientPaint(float x, float y, float radius,
-                int[] colors, float[] positions, TileMode mode) {
-            super(colors, positions, mode);
-            mX = x;
-            mY = y;
-            mRadius = radius;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel     colorModel,
-                java.awt.Rectangle            deviceBounds,
-                java.awt.geom.Rectangle2D     userBounds,
-                java.awt.geom.AffineTransform xform,
-                java.awt.RenderingHints       hints) {
-            precomputeGradientColors();
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in RadialGradient", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in RadialGradient", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new RadialGradientPaintContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class RadialGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            public RadialGradientPaintContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel;
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
-                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
-
-                int[] data = new int[w*h];
-
-                // compute distance from each point to the center, and figure out the distance from
-                // it.
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix
-                        pt1[0] = pt2[0] - mX;
-                        pt1[1] = pt2[1] - mY;
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        float _x = pt2[0];
-                        float _y = pt2[1];
-                        float distance = (float) Math.sqrt(_x * _x + _y * _y);
-
-                        data[index++] = getGradientColor(distance / mRadius);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-
-        }
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Rasterizer_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Rasterizer_Delegate.java
deleted file mode 100644
index 2812b6b..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Rasterizer_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.Rasterizer
- *
- * Through the layoutlib_create tool, the original native methods of Rasterizer have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Rasterizer class.
- *
- * This also serve as a base class for all Rasterizer delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class Rasterizer_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<Rasterizer_Delegate> sManager =
-            new DelegateManager<Rasterizer_Delegate>(Rasterizer_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static Rasterizer_Delegate getDelegate(int nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void finalizer(int native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
deleted file mode 100644
index cb31b8f..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.os.Parcel;
-
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Area;
-import java.awt.geom.Rectangle2D;
-
-/**
- * Delegate implementing the native methods of android.graphics.Region
- *
- * Through the layoutlib_create tool, the original native methods of Region have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Region class.
- *
- * This also serve as a base class for all Region delegate classes.
- *
- * @see DelegateManager
- *
- */
-public class Region_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<Region_Delegate> sManager =
-            new DelegateManager<Region_Delegate>(Region_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-    private Area mArea = new Area();
-
-    // ---- Public Helper methods ----
-
-    public static Region_Delegate getDelegate(int nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public Area getJavaArea() {
-        return mArea;
-    }
-
-    /**
-     * Combines two {@link Shape} into another one (actually an {@link Area}), according
-     * to the given {@link Region.Op}.
-     *
-     * If the Op is not one that combines two shapes, then this return null
-     *
-     * @param shape1 the firt shape to combine which can be null if there's no original clip.
-     * @param shape2 the 2nd shape to combine
-     * @param regionOp the operande for the combine
-     * @return a new area or null.
-     */
-    public static Area combineShapes(Shape shape1, Shape shape2, int regionOp) {
-        if (regionOp == Region.Op.DIFFERENCE.nativeInt) {
-            // if shape1 is null (empty), then the result is null.
-            if (shape1 == null) {
-                return null;
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.subtract(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.INTERSECT.nativeInt) {
-            // if shape1 is null, then the result is simply shape2.
-            if (shape1 == null) {
-                return new Area(shape2);
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.intersect(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.UNION.nativeInt) {
-            // if shape1 is null, then the result is simply shape2.
-            if (shape1 == null) {
-                return new Area(shape2);
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.add(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.XOR.nativeInt) {
-            // if shape1 is null, then the result is simply shape2
-            if (shape1 == null) {
-                return new Area(shape2);
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.exclusiveOr(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.REVERSE_DIFFERENCE.nativeInt) {
-            // result is always a new area.
-            Area result = new Area(shape2);
-
-            if (shape1 != null) {
-                result.subtract(shape1 instanceof Area ? (Area) shape1 : new Area(shape1));
-            }
-
-            return result;
-        }
-
-        return null;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isEmpty(Region thisRegion) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return true;
-        }
-
-        return regionDelegate.mArea.isEmpty();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isRect(Region thisRegion) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return true;
-        }
-
-        return regionDelegate.mArea.isRectangular();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isComplex(Region thisRegion) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return true;
-        }
-
-        return regionDelegate.mArea.isSingular() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean contains(Region thisRegion, int x, int y) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.contains(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean quickContains(Region thisRegion,
-            int left, int top, int right, int bottom) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.isRectangular() &&
-                regionDelegate.mArea.contains(left, top, right - left, bottom - top);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean quickReject(Region thisRegion,
-            int left, int top, int right, int bottom) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.isEmpty() ||
-                regionDelegate.mArea.intersects(left, top, right - left, bottom - top) == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean quickReject(Region thisRegion, Region rgn) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        Region_Delegate targetRegionDelegate = sManager.getDelegate(rgn.mNativeRegion);
-        if (targetRegionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.isEmpty() ||
-                regionDelegate.mArea.getBounds().intersects(
-                        targetRegionDelegate.mArea.getBounds()) == false;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void translate(Region thisRegion, int dx, int dy, Region dst) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return;
-        }
-
-        Region_Delegate targetRegionDelegate = sManager.getDelegate(dst.mNativeRegion);
-        if (targetRegionDelegate == null) {
-            return;
-        }
-
-        if (regionDelegate.mArea.isEmpty()) {
-            targetRegionDelegate.mArea = new Area();
-        } else {
-            targetRegionDelegate.mArea = new Area(regionDelegate.mArea);
-            AffineTransform mtx = new AffineTransform();
-            mtx.translate(dx, dy);
-            targetRegionDelegate.mArea.transform(mtx);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void scale(Region thisRegion, float scale, Region dst) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return;
-        }
-
-        Region_Delegate targetRegionDelegate = sManager.getDelegate(dst.mNativeRegion);
-        if (targetRegionDelegate == null) {
-            return;
-        }
-
-        if (regionDelegate.mArea.isEmpty()) {
-            targetRegionDelegate.mArea = new Area();
-        } else {
-            targetRegionDelegate.mArea = new Area(regionDelegate.mArea);
-            AffineTransform mtx = new AffineTransform();
-            mtx.scale(scale, scale);
-            targetRegionDelegate.mArea.transform(mtx);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeConstructor() {
-        Region_Delegate newDelegate = new Region_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(int native_region) {
-        sManager.removeJavaReferenceFor(native_region);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSetRegion(int native_dst, int native_src) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        Region_Delegate srcRegion = sManager.getDelegate(native_src);
-        if (srcRegion == null) {
-            return true;
-        }
-
-        dstRegion.mArea.reset();
-        dstRegion.mArea.add(srcRegion.mArea);
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSetRect(int native_dst,
-            int left, int top, int right, int bottom) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        dstRegion.mArea = new Area(new Rectangle2D.Float(left, top, right - left, bottom - top));
-        return dstRegion.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSetPath(int native_dst, int native_path, int native_clip) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        Path_Delegate path = Path_Delegate.getDelegate(native_path);
-        if (path == null) {
-            return true;
-        }
-
-        dstRegion.mArea = new Area(path.getJavaShape());
-
-        Region_Delegate clip = sManager.getDelegate(native_clip);
-        if (clip != null) {
-            dstRegion.mArea.subtract(clip.getJavaArea());
-        }
-
-        return dstRegion.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeGetBounds(int native_region, Rect rect) {
-        Region_Delegate region = sManager.getDelegate(native_region);
-        if (region == null) {
-            return true;
-        }
-
-        Rectangle bounds = region.mArea.getBounds();
-        if (bounds.isEmpty()) {
-            rect.left = rect.top = rect.right = rect.bottom = 0;
-            return false;
-        }
-
-        rect.left = bounds.x;
-        rect.top = bounds.y;
-        rect.right = bounds.x + bounds.width;
-        rect.bottom = bounds.y + bounds.height;
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeGetBoundaryPath(int native_region, int native_path) {
-        Region_Delegate region = sManager.getDelegate(native_region);
-        if (region == null) {
-            return false;
-        }
-
-        Path_Delegate path = Path_Delegate.getDelegate(native_path);
-        if (path == null) {
-            return false;
-        }
-
-        if (region.mArea.isEmpty()) {
-            path.reset();
-            return false;
-        }
-
-        path.setPathIterator(region.mArea.getPathIterator(new AffineTransform()));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeOp(int native_dst,
-            int left, int top, int right, int bottom, int op) {
-        Region_Delegate region = sManager.getDelegate(native_dst);
-        if (region == null) {
-            return false;
-        }
-
-        region.mArea = combineShapes(region.mArea,
-                new Rectangle2D.Float(left, top, right - left, bottom - top), op);
-
-        assert region.mArea != null;
-        if (region.mArea != null) {
-            region.mArea = new Area();
-        }
-
-        return region.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeOp(int native_dst, Rect rect, int native_region, int op) {
-        Region_Delegate region = sManager.getDelegate(native_dst);
-        if (region == null) {
-            return false;
-        }
-
-        region.mArea = combineShapes(region.mArea,
-                new Rectangle2D.Float(rect.left, rect.top, rect.width(), rect.height()), op);
-
-        assert region.mArea != null;
-        if (region.mArea != null) {
-            region.mArea = new Area();
-        }
-
-        return region.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeOp(int native_dst,
-            int native_region1, int native_region2, int op) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        Region_Delegate region1 = sManager.getDelegate(native_region1);
-        if (region1 == null) {
-            return false;
-        }
-
-        Region_Delegate region2 = sManager.getDelegate(native_region2);
-        if (region2 == null) {
-            return false;
-        }
-
-        dstRegion.mArea = combineShapes(region1.mArea, region2.mArea, op);
-
-        assert dstRegion.mArea != null;
-        if (dstRegion.mArea != null) {
-            dstRegion.mArea = new Area();
-        }
-
-        return dstRegion.mArea.getBounds().isEmpty() == false;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreateFromParcel(Parcel p) {
-        // This is only called by Region.CREATOR (Parcelable.Creator<Region>), which is only
-        // used during aidl call so really this should not be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Regions cannot be created from parcels.",
-                null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeWriteToParcel(int native_region,
-                                                      Parcel p) {
-        // This is only called when sending a region through aidl, so really this should not
-        // be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Regions cannot be written to parcels.",
-                null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeEquals(int native_r1, int native_r2) {
-        Region_Delegate region1 = sManager.getDelegate(native_r1);
-        if (region1 == null) {
-            return false;
-        }
-
-        Region_Delegate region2 = sManager.getDelegate(native_r2);
-        if (region2 == null) {
-            return false;
-        }
-
-        return region1.mArea.equals(region2.mArea);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String nativeToString(int native_region) {
-        Region_Delegate region = sManager.getDelegate(native_region);
-        if (region == null) {
-            return "not found";
-        }
-
-        return region.mArea.toString();
-    }
-
-    // ---- Private delegate/helper methods ----
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
deleted file mode 100644
index 368c0384..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-/**
- * Delegate implementing the native methods of android.graphics.Shader
- *
- * Through the layoutlib_create tool, the original native methods of Shader have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Shader class.
- *
- * This also serve as a base class for all Shader delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class Shader_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<Shader_Delegate> sManager =
-            new DelegateManager<Shader_Delegate>(Shader_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-    private Matrix_Delegate mLocalMatrix = null;
-
-    // ---- Public Helper methods ----
-
-    public static Shader_Delegate getDelegate(int nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    /**
-     * Returns the {@link TileMode} matching the given int.
-     * @param tileMode the tile mode int value
-     * @return the TileMode enum.
-     */
-    public static TileMode getTileMode(int tileMode) {
-        for (TileMode tm : TileMode.values()) {
-            if (tm.nativeInt == tileMode) {
-                return tm;
-            }
-        }
-
-        assert false;
-        return TileMode.CLAMP;
-    }
-
-    public abstract java.awt.Paint getJavaPaint();
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(int native_shader, int native_skiaShader) {
-        sManager.removeJavaReferenceFor(native_shader);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetLocalMatrix(int native_shader, int native_skiaShader,
-            int matrix_instance) {
-        // get the delegate from the native int.
-        Shader_Delegate shaderDelegate = sManager.getDelegate(native_shader);
-        if (shaderDelegate == null) {
-            return;
-        }
-
-        shaderDelegate.mLocalMatrix = Matrix_Delegate.getDelegate(matrix_instance);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    protected java.awt.geom.AffineTransform getLocalMatrix() {
-        if (mLocalMatrix != null) {
-            return mLocalMatrix.getAffineTransform();
-        }
-
-        return new java.awt.geom.AffineTransform();
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java
deleted file mode 100644
index 410df0c..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.SumPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of SumPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original SumPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class SumPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Sum Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate(int first, int second) {
-        SumPathEffect_Delegate newDelegate = new SumPathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
deleted file mode 100644
index 13ae12e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.SweepGradient
- *
- * Through the layoutlib_create tool, the original native methods of SweepGradient have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original SweepGradient class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class SweepGradient_Delegate extends Gradient_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate1(float x, float y, int colors[], float positions[]) {
-        SweepGradient_Delegate newDelegate = new SweepGradient_Delegate(x, y, colors, positions);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeCreate2(float x, float y, int color0, int color1) {
-        return nativeCreate1(x, y, new int[] { color0, color1 }, null /*positions*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativePostCreate1(int native_shader, float cx, float cy,
-            int[] colors, float[] positions) {
-        // nothing to be done here.
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativePostCreate2(int native_shader, float cx, float cy,
-            int color0, int color1) {
-        // nothing to be done here.
-        return 0;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * A subclass of Shader that draws a sweep gradient around a center point.
-     *
-     * @param cx       The x-coordinate of the center
-     * @param cy       The y-coordinate of the center
-     * @param colors   The colors to be distributed between around the center.
-     *                 There must be at least 2 colors in the array.
-     * @param positions May be NULL. The relative position of
-     *                 each corresponding color in the colors array, beginning
-     *                 with 0 and ending with 1.0. If the values are not
-     *                 monotonic, the drawing may produce unexpected results.
-     *                 If positions is NULL, then the colors are automatically
-     *                 spaced evenly.
-     */
-    private SweepGradient_Delegate(float cx, float cy,
-                         int colors[], float positions[]) {
-        super(colors, positions);
-        mJavaPaint = new SweepGradientPaint(cx, cy, mColors, mPositions);
-    }
-
-    private class SweepGradientPaint extends GradientPaint {
-
-        private final float mCx;
-        private final float mCy;
-
-        public SweepGradientPaint(float cx, float cy, int[] colors,
-                float[] positions) {
-            super(colors, positions, null /*tileMode*/);
-            mCx = cx;
-            mCy = cy;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel     colorModel,
-                java.awt.Rectangle            deviceBounds,
-                java.awt.geom.Rectangle2D     userBounds,
-                java.awt.geom.AffineTransform xform,
-                java.awt.RenderingHints       hints) {
-            precomputeGradientColors();
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in SweepGradient", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in SweepGradient", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new SweepGradientPaintContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class SweepGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            public SweepGradientPaintContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel;
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
-                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
-
-                int[] data = new int[w*h];
-
-                // compute angle from each point to the center, and figure out the distance from
-                // it.
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix
-                        pt1[0] = pt2[0] - mCx;
-                        pt1[1] = pt2[1] - mCy;
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        float dx = pt2[0];
-                        float dy = pt2[1];
-
-                        float angle;
-                        if (dx == 0) {
-                            angle = (float) (dy < 0 ? 3 * Math.PI / 2 : Math.PI / 2);
-                        } else if (dy == 0) {
-                            angle = (float) (dx < 0 ? Math.PI : 0);
-                        } else {
-                            angle = (float) Math.atan(dy / dx);
-                            if (dx > 0) {
-                                if (dy < 0) {
-                                    angle += Math.PI * 2;
-                                }
-                            } else {
-                                angle += Math.PI;
-                            }
-                        }
-
-                        // convert to 0-1. value and get color
-                        data[index++] = getGradientColor((float) (angle / (2 * Math.PI)));
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java
deleted file mode 100644
index adad2ac..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java
+++ /dev/null
@@ -1,27 +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.graphics;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class Typeface_Accessor {
-
-    public static void resetDefaults() {
-        Typeface.sDefaults = null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
deleted file mode 100644
index 8701cc8..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.FontLoader;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.res.AssetManager;
-
-import java.awt.Font;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Delegate implementing the native methods of android.graphics.Typeface
- *
- * Through the layoutlib_create tool, the original native methods of Typeface have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Typeface class.
- *
- * @see DelegateManager
- *
- */
-public final class Typeface_Delegate {
-
-    private static final String SYSTEM_FONTS = "/system/fonts/";
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Typeface_Delegate> sManager =
-            new DelegateManager<Typeface_Delegate>(Typeface_Delegate.class);
-
-    // ---- delegate helper data ----
-    private static final String DEFAULT_FAMILY = "sans-serif";
-
-    private static FontLoader sFontLoader;
-    private static final List<Typeface_Delegate> sPostInitDelegate =
-            new ArrayList<Typeface_Delegate>();
-
-    // ---- delegate data ----
-
-    private final String mFamily;
-    private int mStyle;
-    private List<Font> mFonts;
-
-
-    // ---- Public Helper methods ----
-
-    public static synchronized void init(FontLoader fontLoader) {
-        sFontLoader = fontLoader;
-
-        for (Typeface_Delegate delegate : sPostInitDelegate) {
-            delegate.init();
-        }
-        sPostInitDelegate.clear();
-    }
-
-    public static Typeface_Delegate getDelegate(int nativeTypeface) {
-        return sManager.getDelegate(nativeTypeface);
-    }
-
-    public static List<Font> getFonts(Typeface typeface) {
-        return getFonts(typeface.native_instance);
-    }
-
-    public static List<Font> getFonts(int native_int) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_int);
-        if (delegate == null) {
-            return null;
-        }
-
-        return delegate.getFonts();
-    }
-
-    public List<Font> getFonts() {
-        return mFonts;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized int nativeCreate(String familyName, int style) {
-        if (familyName == null) {
-            familyName = DEFAULT_FAMILY;
-        }
-
-        Typeface_Delegate newDelegate = new Typeface_Delegate(familyName, style);
-        if (sFontLoader != null) {
-            newDelegate.init();
-        } else {
-            // font loader has not been initialized yet, add the delegate to a list of delegates
-            // to init when the font loader is initialized.
-            // There won't be any rendering before this happens anyway.
-            sPostInitDelegate.add(newDelegate);
-        }
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized int nativeCreateFromTypeface(int native_instance, int style) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            return 0;
-        }
-
-        Typeface_Delegate newDelegate = new Typeface_Delegate(delegate.mFamily, style);
-        if (sFontLoader != null) {
-            newDelegate.init();
-        } else {
-            // font loader has not been initialized yet, add the delegate to a list of delegates
-            // to init when the font loader is initialized.
-            // There won't be any rendering before this happens anyway.
-            sPostInitDelegate.add(newDelegate);
-        }
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized int nativeCreateFromAsset(AssetManager mgr, String path) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Typeface.createFromAsset() is not supported.", null /*throwable*/, null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized int nativeCreateFromFile(String path) {
-        if (path.startsWith(SYSTEM_FONTS) ) {
-            String relativePath = path.substring(SYSTEM_FONTS.length());
-            File f = new File(sFontLoader.getOsFontsLocation(), relativePath);
-
-            try {
-                Font font = Font.createFont(Font.TRUETYPE_FONT, f);
-                if (font != null) {
-                    Typeface_Delegate newDelegate = new Typeface_Delegate(font);
-                    return sManager.addNewDelegate(newDelegate);
-                }
-            } catch (Exception e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
-                        String.format("Unable to load font %1$s", relativePath),
-                            null /*throwable*/, null /*data*/);
-            }
-        } else {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                    "Typeface.createFromFile() can only work with platform fonts located in " +
-                        SYSTEM_FONTS,
-                    null /*throwable*/, null /*data*/);
-        }
-
-
-        // return a copy of the base font
-        return nativeCreate(null, 0);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeUnref(int native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetStyle(int native_instance) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mStyle;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private Typeface_Delegate(String family, int style) {
-        mFamily = family;
-        mStyle = style;
-    }
-
-    private Typeface_Delegate(Font font) {
-        mFamily = font.getFamily();
-        mStyle = Typeface.NORMAL;
-
-        mFonts = sFontLoader.getFallbackFonts(mStyle);
-
-        // insert the font glyph first.
-        mFonts.add(0, font);
-    }
-
-    private void init() {
-        mFonts = sFontLoader.getFont(mFamily, mStyle);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
deleted file mode 100644
index 962d69c..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Composite;
-
-/**
- * Delegate implementing the native methods of android.graphics.Xfermode
- *
- * Through the layoutlib_create tool, the original native methods of Xfermode have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Xfermode class.
- *
- * This also serve as a base class for all Xfermode delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class Xfermode_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<Xfermode_Delegate> sManager =
-            new DelegateManager<Xfermode_Delegate>(Xfermode_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static Xfermode_Delegate getDelegate(int native_instance) {
-        return sManager.getDelegate(native_instance);
-    }
-
-    public abstract Composite getComposite(int alpha);
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void finalizer(int native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-}
diff --git a/tools/layoutlib/bridge/src/android/os/Build_Delegate.java b/tools/layoutlib/bridge/src/android/os/Build_Delegate.java
deleted file mode 100644
index ff82a5e..0000000
--- a/tools/layoutlib/bridge/src/android/os/Build_Delegate.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.util.Map;
-
-/**
- * Delegate implementing the native methods of android.os.Build
- *
- * Through the layoutlib_create tool, the original native methods of Build have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-public class Build_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static String getString(String property) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(property);
-        if (value != null) {
-            return value;
-        }
-
-        return Build.UNKNOWN;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java b/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java
deleted file mode 100644
index afbe97c..0000000
--- a/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java
+++ /dev/null
@@ -1,80 +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.os;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Delegate overriding selected methods of android.os.HandlerThread
- *
- * Through the layoutlib_create tool, selected methods of Handler have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- *
- */
-public class HandlerThread_Delegate {
-
-    private static Map<BridgeContext, List<HandlerThread>> sThreads =
-            new HashMap<BridgeContext, List<HandlerThread>>();
-
-    public static void cleanUp(BridgeContext context) {
-        List<HandlerThread> list = sThreads.get(context);
-        if (list != null) {
-            for (HandlerThread thread : list) {
-                thread.quit();
-            }
-
-            list.clear();
-            sThreads.remove(context);
-        }
-    }
-
-    // -------- Delegate methods
-
-    @LayoutlibDelegate
-    /*package*/ static void run(HandlerThread theThread) {
-        // record the thread so that it can be quit() on clean up.
-        BridgeContext context = RenderAction.getCurrentContext();
-        List<HandlerThread> list = sThreads.get(context);
-        if (list == null) {
-            list = new ArrayList<HandlerThread>();
-            sThreads.put(context, list);
-        }
-
-        list.add(theThread);
-
-        // ---- START DEFAULT IMPLEMENTATION.
-
-        theThread.mTid = Process.myTid();
-        Looper.prepare();
-        synchronized (theThread) {
-            theThread.mLooper = Looper.myLooper();
-            theThread.notifyAll();
-        }
-        Process.setThreadPriority(theThread.mPriority);
-        theThread.onLooperPrepared();
-        Looper.loop();
-        theThread.mTid = -1;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java b/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java
deleted file mode 100644
index 2152c8a..0000000
--- a/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-
-/**
- * Delegate overriding selected methods of android.os.Handler
- *
- * Through the layoutlib_create tool, selected methods of Handler have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- *
- */
-public class Handler_Delegate {
-
-    // -------- Delegate methods
-
-    @LayoutlibDelegate
-    /*package*/ static boolean sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) {
-        // get the callback
-        IHandlerCallback callback = sCallbacks.get();
-        if (callback != null) {
-            callback.sendMessageAtTime(handler, msg, uptimeMillis);
-        }
-        return true;
-    }
-
-    // -------- Delegate implementation
-
-    public interface IHandlerCallback {
-        void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis);
-    }
-
-    private final static ThreadLocal<IHandlerCallback> sCallbacks =
-        new ThreadLocal<IHandlerCallback>();
-
-    public static void setCallback(IHandlerCallback callback) {
-        sCallbacks.set(callback);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/os/Looper_Accessor.java b/tools/layoutlib/bridge/src/android/os/Looper_Accessor.java
deleted file mode 100644
index 09f3e47..0000000
--- a/tools/layoutlib/bridge/src/android/os/Looper_Accessor.java
+++ /dev/null
@@ -1,47 +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.os;
-
-import java.lang.reflect.Field;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class Looper_Accessor {
-
-    public static void cleanupThread() {
-        // clean up the looper
-        Looper.sThreadLocal.remove();
-        try {
-            Field sMainLooper = Looper.class.getDeclaredField("sMainLooper");
-            sMainLooper.setAccessible(true);
-            sMainLooper.set(null, null);
-        } catch (SecurityException e) {
-            catchReflectionException();
-        } catch (IllegalArgumentException e) {
-            catchReflectionException();
-        } catch (NoSuchFieldException e) {
-            catchReflectionException();
-        } catch (IllegalAccessException e) {
-            catchReflectionException();
-        }
-
-    }
-
-    private static void catchReflectionException() {
-        assert(false);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/ServiceManager.java b/tools/layoutlib/bridge/src/android/os/ServiceManager.java
deleted file mode 100644
index 6a68ee2..0000000
--- a/tools/layoutlib/bridge/src/android/os/ServiceManager.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import java.util.Map;
-
-public final class ServiceManager {
-
-    /**
-     * Returns a reference to a service with the given name.
-     *
-     * @param name the name of the service to get
-     * @return a reference to the service, or <code>null</code> if the service doesn't exist
-     */
-    public static IBinder getService(String name) {
-        return null;
-    }
-
-    /**
-     * Place a new @a service called @a name into the service
-     * manager.
-     *
-     * @param name the name of the new service
-     * @param service the service object
-     */
-    public static void addService(String name, IBinder service) {
-        // pass
-    }
-
-    /**
-     * Retrieve an existing service called @a name from the
-     * service manager.  Non-blocking.
-     */
-    public static IBinder checkService(String name) {
-        return null;
-    }
-
-    /**
-     * Return a list of all currently running services.
-     */
-    public static String[] listServices() throws RemoteException {
-        // actual implementation returns null sometimes, so it's ok
-        // to return null instead of an empty list.
-        return null;
-    }
-
-    /**
-     * This is only intended to be called when the process is first being brought
-     * up and bound by the activity manager. There is only one thread in the process
-     * at that time, so no locking is done.
-     *
-     * @param cache the cache of service references
-     * @hide
-     */
-    public static void initServiceCache(Map<String, IBinder> cache) {
-        // pass
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
deleted file mode 100644
index fd594f7..0000000
--- a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.os.SystemClock
- *
- * Through the layoutlib_create tool, the original native methods of SystemClock have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-public class SystemClock_Delegate {
-    private static long sBootTime = System.currentTimeMillis();
-    private static long sBootTimeNano = System.nanoTime();
-
-    @LayoutlibDelegate
-    /*package*/ static boolean setCurrentTimeMillis(long millis) {
-        return true;
-    }
-
-    /**
-     * Returns milliseconds since boot, not counting time spent in deep sleep.
-     * <b>Note:</b> This value may get reset occasionally (before it would
-     * otherwise wrap around).
-     *
-     * @return milliseconds of non-sleep uptime since boot.
-     */
-    @LayoutlibDelegate
-    /*package*/ static long uptimeMillis() {
-        return System.currentTimeMillis() - sBootTime;
-    }
-
-    /**
-     * Returns milliseconds since boot, including time spent in sleep.
-     *
-     * @return elapsed milliseconds since boot.
-     */
-    @LayoutlibDelegate
-    /*package*/ static long elapsedRealtime() {
-        return System.currentTimeMillis() - sBootTime;
-    }
-
-    /**
-     * Returns nanoseconds since boot, including time spent in sleep.
-     *
-     * @return elapsed nanoseconds since boot.
-     */
-    @LayoutlibDelegate
-    /*package*/ static long elapsedRealtimeNanos() {
-        return System.nanoTime() - sBootTimeNano;
-    }
-
-    /**
-     * Returns milliseconds running in the current thread.
-     *
-     * @return elapsed milliseconds in the thread
-     */
-    @LayoutlibDelegate
-    /*package*/ static long currentThreadTimeMillis() {
-        return System.currentTimeMillis();
-    }
-
-    /**
-     * Returns microseconds running in the current thread.
-     *
-     * @return elapsed microseconds in the thread
-     *
-     * @hide
-     */
-    @LayoutlibDelegate
-    /*package*/ static long currentThreadTimeMicro() {
-        return System.currentTimeMillis() * 1000;
-    }
-
-    /**
-     * Returns current wall time in  microseconds.
-     *
-     * @return elapsed microseconds in wall time
-     *
-     * @hide
-     */
-    @LayoutlibDelegate
-    /*package*/ static long currentTimeMicro() {
-        return elapsedRealtime() * 1000;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java b/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
deleted file mode 100644
index 973fa0e..0000000
--- a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.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.text;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.ibm.icu.text.Bidi;
-
-
-/**
- * Delegate used to provide new implementation for the native methods of {@link AndroidBidi}
- *
- * Through the layoutlib_create tool, the original  methods of AndroidBidi have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class AndroidBidi_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static int runBidi(int dir, char[] chars, byte[] charInfo, int count,
-            boolean haveInfo) {
-
-        switch (dir) {
-        case 0: // Layout.DIR_REQUEST_LTR
-        case 1: // Layout.DIR_REQUEST_RTL
-            break;  // No change.
-        case -1:
-            dir = Bidi.LEVEL_DEFAULT_LTR;
-            break;
-        case -2:
-            dir = Bidi.LEVEL_DEFAULT_RTL;
-            break;
-        default:
-            // Invalid code. Log error, assume LEVEL_DEFAULT_LTR and continue.
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Invalid direction flag", null);
-            dir = Bidi.LEVEL_DEFAULT_LTR;
-        }
-        Bidi bidi = new Bidi(chars, 0, null, 0, count, dir);
-        if (charInfo != null) {
-            for (int i = 0; i < count; ++i)
-            charInfo[i] = bidi.getLevelAt(i);
-        }
-        return bidi.getParaLevel();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/format/DateFormat_Delegate.java b/tools/layoutlib/bridge/src/android/text/format/DateFormat_Delegate.java
deleted file mode 100644
index 8cd1a69..0000000
--- a/tools/layoutlib/bridge/src/android/text/format/DateFormat_Delegate.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text.format;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-
-
-/**
- * Delegate used to provide new implementation for the native methods of {@link DateFormat}
- *
- * Through the layoutlib_create tool, the original  methods of DateFormat have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class DateFormat_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static boolean is24HourFormat(Context context) {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/format/Time_Delegate.java b/tools/layoutlib/bridge/src/android/text/format/Time_Delegate.java
deleted file mode 100644
index 15cd687..0000000
--- a/tools/layoutlib/bridge/src/android/text/format/Time_Delegate.java
+++ /dev/null
@@ -1,61 +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.text.format;
-
-import java.util.Calendar;
-import java.util.UnknownFormatConversionException;
-import java.util.regex.Pattern;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation for native methods of {@link Time}
- *
- * Through the layoutlib_create tool, some native methods of Time have been replaced by calls to
- * methods of the same name in this delegate class.
- */
-public class Time_Delegate {
-
-    // Regex to match odd number of '%'.
-    private static final Pattern p = Pattern.compile("(?<!%)(%%)*%(?!%)");
-
-    @LayoutlibDelegate
-    /*package*/ static String format1(Time thisTime, String format) {
-
-        try {
-            // Change the format by adding changing '%' to "%1$t". This is required to tell the
-            // formatter which argument to use from the argument list. '%%' is left as is. In the
-            // replacement string, $0 refers to matched pattern. \\1 means '1', written this way to
-            // separate it from 0. \\$ means '$', written this way to suppress the special meaning
-            // of $.
-            return String.format(
-                    p.matcher(format).replaceAll("$0\\1\\$t"),
-                    timeToCalendar(thisTime, Calendar.getInstance()));
-        } catch (UnknownFormatConversionException e) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_STRFTIME, "Unrecognized format", e, format);
-            return format;
-        }
-    }
-
-    private static Calendar timeToCalendar(Time time, Calendar calendar) {
-        calendar.set(time.year, time.month, time.monthDay, time.hour, time.minute, time.second);
-        return calendar;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java b/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
deleted file mode 100644
index 6ac5b02..0000000
--- a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
+++ /dev/null
@@ -1,283 +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;
-
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.ResourceType;
-
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * A correct implementation of the {@link AttributeSet} interface on top of a XmlPullParser
- */
-public class BridgeXmlPullAttributes extends XmlPullAttributes {
-
-    private final BridgeContext mContext;
-    private final boolean mPlatformFile;
-
-    public BridgeXmlPullAttributes(XmlPullParser parser, BridgeContext context,
-            boolean platformFile) {
-        super(parser);
-        mContext = context;
-        mPlatformFile = platformFile;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see android.util.XmlPullAttributes#getAttributeNameResource(int)
-     *
-     * This methods must return com.android.internal.R.attr.<name> matching
-     * the name of the attribute.
-     * It returns 0 if it doesn't find anything.
-     */
-    @Override
-    public int getAttributeNameResource(int index) {
-        // get the attribute name.
-        String name = getAttributeName(index);
-
-        // get the attribute namespace
-        String ns = mParser.getAttributeNamespace(index);
-
-        if (BridgeConstants.NS_RESOURCES.equals(ns)) {
-            Integer v = Bridge.getResourceId(ResourceType.ATTR, name);
-            if (v != null) {
-                return v.intValue();
-            }
-
-            return 0;
-        }
-
-        // this is not an attribute in the android namespace, we query the customviewloader, if
-        // the namespaces match.
-        if (mContext.getProjectCallback().getNamespace().equals(ns)) {
-            Integer v = mContext.getProjectCallback().getResourceId(ResourceType.ATTR, name);
-            if (v != null) {
-                return v.intValue();
-            }
-        }
-
-        return 0;
-    }
-
-    @Override
-    public int getAttributeListValue(String namespace, String attribute,
-            String[] options, int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToList(value, options, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(String namespace, String attribute,
-            boolean defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToBoolean(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-
-        return resolveResourceValue(value, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(String namespace, String attribute,
-            int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToInt(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(String namespace, String attribute,
-            int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public float getAttributeFloatValue(String namespace, String attribute,
-            float defaultValue) {
-        String s = getAttributeValue(namespace, attribute);
-        if (s != null) {
-            ResourceValue r = getResourceValue(s);
-
-            if (r != null) {
-                s = r.getValue();
-            }
-
-            return Float.parseFloat(s);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeListValue(int index,
-            String[] options, int defaultValue) {
-        return XmlUtils.convertValueToList(
-            getAttributeValue(index), options, defaultValue);
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
-        String value = getAttributeValue(index);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToBoolean(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeResourceValue(int index, int defaultValue) {
-        String value = getAttributeValue(index);
-
-        return resolveResourceValue(value, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(int index, int defaultValue) {
-        String value = getAttributeValue(index);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToInt(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
-        String value = getAttributeValue(index);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public float getAttributeFloatValue(int index, float defaultValue) {
-        String s = getAttributeValue(index);
-        if (s != null) {
-            ResourceValue r = getResourceValue(s);
-
-            if (r != null) {
-                s = r.getValue();
-            }
-
-            return Float.parseFloat(s);
-        }
-
-        return defaultValue;
-    }
-
-    // -- private helper methods
-
-    /**
-     * Returns a resolved {@link ResourceValue} from a given value.
-     */
-    private ResourceValue getResourceValue(String value) {
-        // now look for this particular value
-        RenderResources resources = mContext.getRenderResources();
-        return resources.resolveResValue(resources.findResValue(value, mPlatformFile));
-    }
-
-    /**
-     * Resolves and return a value to its associated integer.
-     */
-    private int resolveResourceValue(String value, int defaultValue) {
-        ResourceValue resource = getResourceValue(value);
-        if (resource != null) {
-            Integer id = null;
-            if (mPlatformFile || resource.isFramework()) {
-                id = Bridge.getResourceId(resource.getResourceType(), resource.getName());
-            } else {
-                id = mContext.getProjectCallback().getResourceId(
-                        resource.getResourceType(), resource.getName());
-            }
-
-            if (id != null) {
-                return id;
-            }
-        }
-
-        return defaultValue;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java b/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
deleted file mode 100644
index 8b4c60b..0000000
--- a/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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 android.util;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.util.FloatMath
- *
- * Through the layoutlib_create tool, the original native methods of FloatMath have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-/*package*/ final class FloatMath_Delegate {
-
-    /** Prevents instantiation. */
-    private FloatMath_Delegate() {}
-
-    /**
-     * Returns the float conversion of the most positive (i.e. closest to
-     * positive infinity) integer value which is less than the argument.
-     *
-     * @param value to be converted
-     * @return the floor of value
-     */
-    @LayoutlibDelegate
-    /*package*/ static float floor(float value) {
-        return (float)Math.floor(value);
-    }
-
-    /**
-     * Returns the float conversion of the most negative (i.e. closest to
-     * negative infinity) integer value which is greater than the argument.
-     *
-     * @param value to be converted
-     * @return the ceiling of value
-     */
-    @LayoutlibDelegate
-    /*package*/ static float ceil(float value) {
-        return (float)Math.ceil(value);
-    }
-
-    /**
-     * Returns the closest float approximation of the sine of the argument.
-     *
-     * @param angle to compute the cosine of, in radians
-     * @return the sine of angle
-     */
-    @LayoutlibDelegate
-    /*package*/ static  float sin(float angle) {
-        return (float)Math.sin(angle);
-    }
-
-    /**
-     * Returns the closest float approximation of the cosine of the argument.
-     *
-     * @param angle to compute the cosine of, in radians
-     * @return the cosine of angle
-     */
-    @LayoutlibDelegate
-    /*package*/ static float cos(float angle) {
-        return (float)Math.cos(angle);
-    }
-
-    /**
-     * Returns the closest float approximation of the square root of the
-     * argument.
-     *
-     * @param value to compute sqrt of
-     * @return the square root of value
-     */
-    @LayoutlibDelegate
-    /*package*/ static float sqrt(float value) {
-        return (float)Math.sqrt(value);
-    }
-
-    /**
-     * Returns the closest float approximation of the raising "e" to the power
-     * of the argument.
-     *
-     * @param value to compute the exponential of
-     * @return the exponential of value
-     */
-    @LayoutlibDelegate
-    /*package*/ static float exp(float value) {
-        return (float)Math.exp(value);
-    }
-
-    /**
-     * Returns the closest float approximation of the result of raising {@code
-     * x} to the power of {@code y}.
-     *
-     * @param x the base of the operation.
-     * @param y the exponent of the operation.
-     * @return {@code x} to the power of {@code y}.
-     */
-    @LayoutlibDelegate
-    /*package*/ static float pow(float x, float y) {
-        return (float)Math.pow(x, y);
-    }
-
-    /**
-     * Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +} <i>
-     * {@code y}</i><sup>{@code 2}</sup>{@code )}.
-     *
-     * @param x a float number
-     * @param y a float number
-     * @return the hypotenuse
-     */
-    @LayoutlibDelegate
-    /*package*/ static float hypot(float x, float y) {
-        return (float)Math.sqrt(x*x + y*y);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/Log_Delegate.java b/tools/layoutlib/bridge/src/android/util/Log_Delegate.java
deleted file mode 100644
index 7f432ab..0000000
--- a/tools/layoutlib/bridge/src/android/util/Log_Delegate.java
+++ /dev/null
@@ -1,51 +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.util;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-class Log_Delegate {
-    // to replicate prefix visible when using 'adb logcat'
-    private static char priorityChar(int priority) {
-        switch (priority) {
-            case Log.VERBOSE:
-                return 'V';
-            case Log.DEBUG:
-                return 'D';
-            case Log.INFO:
-                return 'I';
-            case Log.WARN:
-                return 'W';
-            case Log.ERROR:
-                return 'E';
-            case Log.ASSERT:
-                return 'A';
-            default:
-                return '?';
-        }
-    }
-
-    @LayoutlibDelegate
-    static int println_native(int bufID, int priority, String tag, String msgs) {
-        String prefix = priorityChar(priority) + "/" + tag + ": ";
-        for (String msg: msgs.split("\n")) {
-            System.out.println(prefix + msg);
-        }
-        return 0;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/util/LruCache.java b/tools/layoutlib/bridge/src/android/util/LruCache.java
deleted file mode 100644
index 5208606..0000000
--- a/tools/layoutlib/bridge/src/android/util/LruCache.java
+++ /dev/null
@@ -1,391 +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.util;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * BEGIN LAYOUTLIB CHANGE
- * This is a custom version that doesn't use the non standard LinkedHashMap#eldest.
- * END LAYOUTLIB CHANGE
- *
- * A cache that holds strong references to a limited number of values. Each time
- * a value is accessed, it is moved to the head of a queue. When a value is
- * added to a full cache, the value at the end of that queue is evicted and may
- * become eligible for garbage collection.
- *
- * <p>If your cached values hold resources that need to be explicitly released,
- * override {@link #entryRemoved}.
- *
- * <p>If a cache miss should be computed on demand for the corresponding keys,
- * override {@link #create}. This simplifies the calling code, allowing it to
- * assume a value will always be returned, even when there's a cache miss.
- *
- * <p>By default, the cache size is measured in the number of entries. Override
- * {@link #sizeOf} to size the cache in different units. For example, this cache
- * is limited to 4MiB of bitmaps:
- * <pre>   {@code
- *   int cacheSize = 4 * 1024 * 1024; // 4MiB
- *   LruCache<String, Bitmap> bitmapCache = new LruCache<String, Bitmap>(cacheSize) {
- *       protected int sizeOf(String key, Bitmap value) {
- *           return value.getByteCount();
- *       }
- *   }}</pre>
- *
- * <p>This class is thread-safe. Perform multiple cache operations atomically by
- * synchronizing on the cache: <pre>   {@code
- *   synchronized (cache) {
- *     if (cache.get(key) == null) {
- *         cache.put(key, value);
- *     }
- *   }}</pre>
- *
- * <p>This class does not allow null to be used as a key or value. A return
- * value of null from {@link #get}, {@link #put} or {@link #remove} is
- * unambiguous: the key was not in the cache.
- *
- * <p>This class appeared in Android 3.1 (Honeycomb MR1); it's available as part
- * of <a href="http://developer.android.com/sdk/compatibility-library.html">Android's
- * Support Package</a> for earlier releases.
- */
-public class LruCache<K, V> {
-    private final LinkedHashMap<K, V> map;
-
-    /** Size of this cache in units. Not necessarily the number of elements. */
-    private int size;
-    private int maxSize;
-
-    private int putCount;
-    private int createCount;
-    private int evictionCount;
-    private int hitCount;
-    private int missCount;
-
-    /**
-     * @param maxSize for caches that do not override {@link #sizeOf}, this is
-     *     the maximum number of entries in the cache. For all other caches,
-     *     this is the maximum sum of the sizes of the entries in this cache.
-     */
-    public LruCache(int maxSize) {
-        if (maxSize <= 0) {
-            throw new IllegalArgumentException("maxSize <= 0");
-        }
-        this.maxSize = maxSize;
-        this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
-    }
-
-    /**
-     * Sets the size of the cache.
-     * @param maxSize The new maximum size.
-     *
-     * @hide
-     */
-    public void resize(int maxSize) {
-        if (maxSize <= 0) {
-            throw new IllegalArgumentException("maxSize <= 0");
-        }
-
-        synchronized (this) {
-            this.maxSize = maxSize;
-        }
-        trimToSize(maxSize);
-    }
-
-    /**
-     * Returns the value for {@code key} if it exists in the cache or can be
-     * created by {@code #create}. If a value was returned, it is moved to the
-     * head of the queue. This returns null if a value is not cached and cannot
-     * be created.
-     */
-    public final V get(K key) {
-        if (key == null) {
-            throw new NullPointerException("key == null");
-        }
-
-        V mapValue;
-        synchronized (this) {
-            mapValue = map.get(key);
-            if (mapValue != null) {
-                hitCount++;
-                return mapValue;
-            }
-            missCount++;
-        }
-
-        /*
-         * Attempt to create a value. This may take a long time, and the map
-         * may be different when create() returns. If a conflicting value was
-         * added to the map while create() was working, we leave that value in
-         * the map and release the created value.
-         */
-
-        V createdValue = create(key);
-        if (createdValue == null) {
-            return null;
-        }
-
-        synchronized (this) {
-            createCount++;
-            mapValue = map.put(key, createdValue);
-
-            if (mapValue != null) {
-                // There was a conflict so undo that last put
-                map.put(key, mapValue);
-            } else {
-                size += safeSizeOf(key, createdValue);
-            }
-        }
-
-        if (mapValue != null) {
-            entryRemoved(false, key, createdValue, mapValue);
-            return mapValue;
-        } else {
-            trimToSize(maxSize);
-            return createdValue;
-        }
-    }
-
-    /**
-     * Caches {@code value} for {@code key}. The value is moved to the head of
-     * the queue.
-     *
-     * @return the previous value mapped by {@code key}.
-     */
-    public final V put(K key, V value) {
-        if (key == null || value == null) {
-            throw new NullPointerException("key == null || value == null");
-        }
-
-        V previous;
-        synchronized (this) {
-            putCount++;
-            size += safeSizeOf(key, value);
-            previous = map.put(key, value);
-            if (previous != null) {
-                size -= safeSizeOf(key, previous);
-            }
-        }
-
-        if (previous != null) {
-            entryRemoved(false, key, previous, value);
-        }
-
-        trimToSize(maxSize);
-        return previous;
-    }
-
-    /**
-     * @param maxSize the maximum size of the cache before returning. May be -1
-     *     to evict even 0-sized elements.
-     */
-    private void trimToSize(int maxSize) {
-        while (true) {
-            K key;
-            V value;
-            synchronized (this) {
-                if (size < 0 || (map.isEmpty() && size != 0)) {
-                    throw new IllegalStateException(getClass().getName()
-                            + ".sizeOf() is reporting inconsistent results!");
-                }
-
-                if (size <= maxSize) {
-                    break;
-                }
-
-                // BEGIN LAYOUTLIB CHANGE
-                // get the last item in the linked list.
-                // This is not efficient, the goal here is to minimize the changes
-                // compared to the platform version.
-                Map.Entry<K, V> toEvict = null;
-                for (Map.Entry<K, V> entry : map.entrySet()) {
-                    toEvict = entry;
-                }
-                // END LAYOUTLIB CHANGE
-
-                if (toEvict == null) {
-                    break;
-                }
-
-                key = toEvict.getKey();
-                value = toEvict.getValue();
-                map.remove(key);
-                size -= safeSizeOf(key, value);
-                evictionCount++;
-            }
-
-            entryRemoved(true, key, value, null);
-        }
-    }
-
-    /**
-     * Removes the entry for {@code key} if it exists.
-     *
-     * @return the previous value mapped by {@code key}.
-     */
-    public final V remove(K key) {
-        if (key == null) {
-            throw new NullPointerException("key == null");
-        }
-
-        V previous;
-        synchronized (this) {
-            previous = map.remove(key);
-            if (previous != null) {
-                size -= safeSizeOf(key, previous);
-            }
-        }
-
-        if (previous != null) {
-            entryRemoved(false, key, previous, null);
-        }
-
-        return previous;
-    }
-
-    /**
-     * Called for entries that have been evicted or removed. This method is
-     * invoked when a value is evicted to make space, removed by a call to
-     * {@link #remove}, or replaced by a call to {@link #put}. The default
-     * implementation does nothing.
-     *
-     * <p>The method is called without synchronization: other threads may
-     * access the cache while this method is executing.
-     *
-     * @param evicted true if the entry is being removed to make space, false
-     *     if the removal was caused by a {@link #put} or {@link #remove}.
-     * @param newValue the new value for {@code key}, if it exists. If non-null,
-     *     this removal was caused by a {@link #put}. Otherwise it was caused by
-     *     an eviction or a {@link #remove}.
-     */
-    protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {}
-
-    /**
-     * Called after a cache miss to compute a value for the corresponding key.
-     * Returns the computed value or null if no value can be computed. The
-     * default implementation returns null.
-     *
-     * <p>The method is called without synchronization: other threads may
-     * access the cache while this method is executing.
-     *
-     * <p>If a value for {@code key} exists in the cache when this method
-     * returns, the created value will be released with {@link #entryRemoved}
-     * and discarded. This can occur when multiple threads request the same key
-     * at the same time (causing multiple values to be created), or when one
-     * thread calls {@link #put} while another is creating a value for the same
-     * key.
-     */
-    protected V create(K key) {
-        return null;
-    }
-
-    private int safeSizeOf(K key, V value) {
-        int result = sizeOf(key, value);
-        if (result < 0) {
-            throw new IllegalStateException("Negative size: " + key + "=" + value);
-        }
-        return result;
-    }
-
-    /**
-     * Returns the size of the entry for {@code key} and {@code value} in
-     * user-defined units.  The default implementation returns 1 so that size
-     * is the number of entries and max size is the maximum number of entries.
-     *
-     * <p>An entry's size must not change while it is in the cache.
-     */
-    protected int sizeOf(K key, V value) {
-        return 1;
-    }
-
-    /**
-     * Clear the cache, calling {@link #entryRemoved} on each removed entry.
-     */
-    public final void evictAll() {
-        trimToSize(-1); // -1 will evict 0-sized elements
-    }
-
-    /**
-     * For caches that do not override {@link #sizeOf}, this returns the number
-     * of entries in the cache. For all other caches, this returns the sum of
-     * the sizes of the entries in this cache.
-     */
-    public synchronized final int size() {
-        return size;
-    }
-
-    /**
-     * For caches that do not override {@link #sizeOf}, this returns the maximum
-     * number of entries in the cache. For all other caches, this returns the
-     * maximum sum of the sizes of the entries in this cache.
-     */
-    public synchronized final int maxSize() {
-        return maxSize;
-    }
-
-    /**
-     * Returns the number of times {@link #get} returned a value that was
-     * already present in the cache.
-     */
-    public synchronized final int hitCount() {
-        return hitCount;
-    }
-
-    /**
-     * Returns the number of times {@link #get} returned null or required a new
-     * value to be created.
-     */
-    public synchronized final int missCount() {
-        return missCount;
-    }
-
-    /**
-     * Returns the number of times {@link #create(Object)} returned a value.
-     */
-    public synchronized final int createCount() {
-        return createCount;
-    }
-
-    /**
-     * Returns the number of times {@link #put} was called.
-     */
-    public synchronized final int putCount() {
-        return putCount;
-    }
-
-    /**
-     * Returns the number of values that have been evicted.
-     */
-    public synchronized final int evictionCount() {
-        return evictionCount;
-    }
-
-    /**
-     * Returns a copy of the current contents of the cache, ordered from least
-     * recently accessed to most recently accessed.
-     */
-    public synchronized final Map<K, V> snapshot() {
-        return new LinkedHashMap<K, V>(map);
-    }
-
-    @Override public synchronized final String toString() {
-        int accesses = hitCount + missCount;
-        int hitPercent = accesses != 0 ? (100 * hitCount / accesses) : 0;
-        return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]",
-                maxSize, hitCount, missCount, hitPercent);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java b/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
deleted file mode 100644
index 4901f72..0000000
--- a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.layoutlib.bridge.android.BridgeWindow;
-import com.android.layoutlib.bridge.android.BridgeWindowSession;
-
-import android.content.Context;
-import android.os.Handler;
-import android.view.View.AttachInfo;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class AttachInfo_Accessor {
-
-    public static void setAttachInfo(View view) {
-        Context context = view.getContext();
-        WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
-        Display display = wm.getDefaultDisplay();
-        ViewRootImpl root = new ViewRootImpl(context, display);
-        AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(),
-                display, root, new Handler(), null);
-        info.mHasWindowFocus = true;
-        info.mWindowVisibility = View.VISIBLE;
-        info.mInTouchMode = false; // this is so that we can display selections.
-        info.mHardwareAccelerated = false;
-        view.dispatchAttachedToWindow(info, 0);
-    }
-
-    public static void dispatchOnPreDraw(View view) {
-        view.mAttachInfo.mTreeObserver.dispatchOnPreDraw();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
deleted file mode 100644
index 941f1ce6..0000000
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ /dev/null
@@ -1,272 +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.view;
-
-import com.android.ide.common.rendering.api.IProjectCallback;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.MergeCookie;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.InflateException;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.io.File;
-
-/**
- * Custom implementation of {@link LayoutInflater} to handle custom views.
- */
-public final class BridgeInflater extends LayoutInflater {
-
-    private final IProjectCallback mProjectCallback;
-    private boolean mIsInMerge = false;
-    private ResourceReference mResourceReference;
-
-    /**
-     * List of class prefixes which are tried first by default.
-     * <p/>
-     * This should match the list in com.android.internal.policy.impl.PhoneLayoutInflater.
-     */
-    private static final String[] sClassPrefixList = {
-        "android.widget.",
-        "android.webkit."
-    };
-
-    protected BridgeInflater(LayoutInflater original, Context newContext) {
-        super(original, newContext);
-        mProjectCallback = null;
-    }
-
-    /**
-     * Instantiate a new BridgeInflater with an {@link IProjectCallback} object.
-     *
-     * @param context The Android application context.
-     * @param projectCallback the {@link IProjectCallback} object.
-     */
-    public BridgeInflater(Context context, IProjectCallback projectCallback) {
-        super(context);
-        mProjectCallback = projectCallback;
-        mConstructorArgs[0] = context;
-    }
-
-    @Override
-    public View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException {
-        View view = null;
-
-        try {
-            // First try to find a class using the default Android prefixes
-            for (String prefix : sClassPrefixList) {
-                try {
-                    view = createView(name, prefix, attrs);
-                    if (view != null) {
-                        break;
-                    }
-                } catch (ClassNotFoundException e) {
-                    // Ignore. We'll try again using the base class below.
-                }
-            }
-
-            // Next try using the parent loader. This will most likely only work for
-            // fully-qualified class names.
-            try {
-                if (view == null) {
-                    view = super.onCreateView(name, attrs);
-                }
-            } catch (ClassNotFoundException e) {
-                // Ignore. We'll try again using the custom view loader below.
-            }
-
-            // Finally try again using the custom view loader
-            try {
-                if (view == null) {
-                    view = loadCustomView(name, attrs);
-                }
-            } catch (ClassNotFoundException e) {
-                // If the class was not found, we throw the exception directly, because this
-                // method is already expected to throw it.
-                throw e;
-            }
-        } catch (Exception e) {
-            // Wrap the real exception in a ClassNotFoundException, so that the calling method
-            // can deal with it.
-            ClassNotFoundException exception = new ClassNotFoundException("onCreateView", e);
-            throw exception;
-        }
-
-        setupViewInContext(view, attrs);
-
-        return view;
-    }
-
-    @Override
-    public View createViewFromTag(View parent, String name, AttributeSet attrs) {
-        View view = null;
-        try {
-            view = super.createViewFromTag(parent, name, attrs);
-        } catch (InflateException e) {
-            // try to load the class from using the custom view loader
-            try {
-                view = loadCustomView(name, attrs);
-            } catch (Exception e2) {
-                // Wrap the real exception in an InflateException so that the calling
-                // method can deal with it.
-                InflateException exception = new InflateException();
-                if (e2.getClass().equals(ClassNotFoundException.class) == false) {
-                    exception.initCause(e2);
-                } else {
-                    exception.initCause(e);
-                }
-                throw exception;
-            }
-        }
-
-        setupViewInContext(view, attrs);
-
-        return view;
-    }
-
-    @Override
-    public View inflate(int resource, ViewGroup root) {
-        Context context = getContext();
-        if (context instanceof BridgeContext) {
-            BridgeContext bridgeContext = (BridgeContext)context;
-
-            ResourceValue value = null;
-
-            Pair<ResourceType, String> layoutInfo = Bridge.resolveResourceId(resource);
-            if (layoutInfo != null) {
-                value = bridgeContext.getRenderResources().getFrameworkResource(
-                        ResourceType.LAYOUT, layoutInfo.getSecond());
-            } else {
-                layoutInfo = mProjectCallback.resolveResourceId(resource);
-
-                if (layoutInfo != null) {
-                    value = bridgeContext.getRenderResources().getProjectResource(
-                            ResourceType.LAYOUT, layoutInfo.getSecond());
-                }
-            }
-
-            if (value != null) {
-                File f = new File(value.getValue());
-                if (f.isFile()) {
-                    try {
-                        XmlPullParser parser = ParserFactory.create(f);
-
-                        BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
-                                parser, bridgeContext, false);
-
-                        return inflate(bridgeParser, root);
-                    } catch (Exception e) {
-                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                                "Failed to parse file " + f.getAbsolutePath(), e, null /*data*/);
-
-                        return null;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    private View loadCustomView(String name, AttributeSet attrs) throws ClassNotFoundException,
-            Exception{
-        if (mProjectCallback != null) {
-            // first get the classname in case it's not the node name
-            if (name.equals("view")) {
-                name = attrs.getAttributeValue(null, "class");
-            }
-
-            mConstructorArgs[1] = attrs;
-
-            Object customView = mProjectCallback.loadView(name, mConstructorSignature,
-                    mConstructorArgs);
-
-            if (customView instanceof View) {
-                return (View)customView;
-            }
-        }
-
-        return null;
-    }
-
-    private void setupViewInContext(View view, AttributeSet attrs) {
-        if (getContext() instanceof BridgeContext) {
-            BridgeContext bc = (BridgeContext) getContext();
-            if (attrs instanceof BridgeXmlBlockParser) {
-                BridgeXmlBlockParser parser = (BridgeXmlBlockParser) attrs;
-
-                // get the view key
-                Object viewKey = parser.getViewCookie();
-
-                if (viewKey == null) {
-                    int currentDepth = parser.getDepth();
-
-                    // test whether we are in an included file or in a adapter binding view.
-                    BridgeXmlBlockParser previousParser = bc.getPreviousParser();
-                    if (previousParser != null) {
-                        // looks like we inside an embedded layout.
-                        // only apply the cookie of the calling node (<include>) if we are at the
-                        // top level of the embedded layout. If there is a merge tag, then
-                        // skip it and look for the 2nd level
-                        int testDepth = mIsInMerge ? 2 : 1;
-                        if (currentDepth == testDepth) {
-                            viewKey = previousParser.getViewCookie();
-                            // if we are in a merge, wrap the cookie in a MergeCookie.
-                            if (viewKey != null && mIsInMerge) {
-                                viewKey = new MergeCookie(viewKey);
-                            }
-                        }
-                    } else if (mResourceReference != null && currentDepth == 1) {
-                        // else if there's a resource reference, this means we are in an adapter
-                        // binding case. Set the resource ref as the view cookie only for the top
-                        // level view.
-                        viewKey = mResourceReference;
-                    }
-                }
-
-                if (viewKey != null) {
-                    bc.addViewKey(view, viewKey);
-                }
-            }
-        }
-    }
-
-    public void setIsInMerge(boolean isInMerge) {
-        mIsInMerge = isInMerge;
-    }
-
-    public void setResourceReference(ResourceReference reference) {
-        mResourceReference = reference;
-    }
-
-    @Override
-    public LayoutInflater cloneInContext(Context newContext) {
-        return new BridgeInflater(this, newContext);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java b/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java
deleted file mode 100644
index f75ee50..0000000
--- a/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Choreographer}
- *
- * Through the layoutlib_create tool, the original  methods of Choreographer have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-public class Choreographer_Delegate {
-
-    @LayoutlibDelegate
-    public static float getRefreshRate() {
-        return 60.f;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
deleted file mode 100644
index 53dc821..0000000
--- a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
+++ /dev/null
@@ -1,36 +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.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Display}
- *
- * Through the layoutlib_create tool, the original  methods of Display have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class Display_Delegate {
-
-    @LayoutlibDelegate
-    static void updateDisplayInfoLocked(Display theDisplay) {
-        // do nothing
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
deleted file mode 100644
index dd2cbc1..0000000
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ /dev/null
@@ -1,501 +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.view;
-
-import android.graphics.Point;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-
-import android.content.res.CompatibilityInfo;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.IRemoteCallback;
-import android.os.RemoteException;
-import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.Gravity;
-import android.view.IApplicationToken;
-import android.view.IInputFilter;
-import android.view.IOnKeyguardExitResult;
-import android.view.IRotationWatcher;
-import android.view.IWindowManager;
-import android.view.IWindowSession;
-
-import java.util.List;
-
-/**
- * Basic implementation of {@link IWindowManager} so that {@link Display} (and
- * {@link Display_Delegate}) can return a valid instance.
- */
-public class IWindowManagerImpl implements IWindowManager {
-
-    private final Configuration mConfig;
-    private final DisplayMetrics mMetrics;
-    private final int mRotation;
-    private final boolean mHasNavigationBar;
-
-    public IWindowManagerImpl(Configuration config, DisplayMetrics metrics, int rotation,
-            boolean hasNavigationBar) {
-        mConfig = config;
-        mMetrics = metrics;
-        mRotation = rotation;
-        mHasNavigationBar = hasNavigationBar;
-    }
-
-    // custom API.
-
-    public DisplayMetrics getMetrics() {
-        return mMetrics;
-    }
-
-    // ---- implementation of IWindowManager that we care about ----
-
-    @Override
-    public int getRotation() throws RemoteException {
-        return mRotation;
-    }
-
-    @Override
-    public boolean hasNavigationBar() {
-        return mHasNavigationBar;
-    }
-
-    // ---- unused implementation of IWindowManager ----
-
-    @Override
-    public void addAppToken(int arg0, IApplicationToken arg1, int arg2, int arg3, int arg4,
-            boolean arg5, boolean arg6, int arg7, int arg8)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void addWindowToken(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void clearForcedDisplaySize(int displayId) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void clearForcedDisplayDensity(int displayId) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setOverscan(int displayId, int left, int top, int right, int bottom)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void closeSystemDialogs(String arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void startFreezingScreen(int exitAnim, int enterAnim) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void stopFreezingScreen() {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void disableKeyguard(IBinder arg0, String arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void executeAppTransition() throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void exitKeyguardSecurely(IOnKeyguardExitResult arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void freezeRotation(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public float getAnimationScale(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public float[] getAnimationScales() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getAppOrientation(IApplicationToken arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int getPendingAppTransition() throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public boolean inKeyguardRestrictedInputMode() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean inputMethodClientHasFocus(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isKeyguardLocked() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isKeyguardSecure() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isViewServerRunning() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public IWindowSession openSession(IInputMethodClient arg0, IInputContext arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void overridePendingAppTransition(String arg0, int arg1, int arg2,
-            IRemoteCallback startedCallback) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
-            int startHeight) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
-            IRemoteCallback startedCallback, boolean scaleUp) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void pauseKeyDispatching(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void prepareAppTransition(int arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void reenableKeyguard(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void removeAppToken(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void removeWindowToken(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void resumeKeyDispatching(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public Bitmap screenshotApplications(IBinder arg0, int displayId, int arg1,
-            int arg2, boolean arg3) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void setAnimationScale(int arg0, float arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setAnimationScales(float[] arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setAppGroupId(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setAppOrientation(IApplicationToken arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setAppStartingWindow(IBinder arg0, String arg1, int arg2, CompatibilityInfo arg3,
-            CharSequence arg4, int arg5, int arg6, int arg7, int arg8, IBinder arg9, boolean arg10)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setAppVisibility(IBinder arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setAppWillBeHidden(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setEventDispatching(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setFocusedApp(IBinder arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void getInitialDisplaySize(int displayId, Point size) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void getBaseDisplaySize(int displayId, Point size) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setForcedDisplaySize(int displayId, int arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public int getInitialDisplayDensity(int displayId) {
-        return -1;
-    }
-
-    @Override
-    public int getBaseDisplayDensity(int displayId) {
-        return -1;
-    }
-
-    @Override
-    public void setForcedDisplayDensity(int displayId, int density) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setInTouchMode(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setNewConfiguration(Configuration arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void updateRotation(boolean arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setStrictModeVisualIndicatorPreference(String arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void showStrictModeViolation(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void startAppFreezingScreen(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean startViewServer(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void statusBarVisibilityChanged(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void stopAppFreezingScreen(IBinder arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean stopViewServer() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void thawRotation() throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Configuration updateOrientationFromAppTokens(Configuration arg0, IBinder arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int watchRotation(IRotationWatcher arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void removeRotationWatcher(IRotationWatcher arg0) throws RemoteException {
-    }
-
-    @Override
-    public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
-        return false;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getPreferredOptionsPanelGravity() throws RemoteException {
-        return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
-    }
-
-    @Override
-    public void dismissKeyguard() {
-    }
-
-    @Override
-    public void lockNow(Bundle options) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean isSafeModeEnabled() {
-        return false;
-    }
-
-    @Override
-    public IBinder getFocusedWindowToken() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void setInputFilter(IInputFilter filter) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void getWindowFrame(IBinder token, Rect outFrame) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setMagnificationCallbacks(IMagnificationCallbacks callbacks) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setMagnificationSpec(MagnificationSpec spec) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isRotationFrozen() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void setTouchExplorationEnabled(boolean enabled) {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
deleted file mode 100644
index 3db3a1b..0000000
--- a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
+++ /dev/null
@@ -1,199 +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.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.util.AttributeSet;
-import android.util.Xml;
-
-import java.io.IOException;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link LayoutInflater}
- *
- * Through the layoutlib_create tool, the original  methods of LayoutInflater have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class LayoutInflater_Delegate {
-
-    private static final String TAG_MERGE = "merge";
-
-    public static boolean sIsInInclude = false;
-
-    /**
-     * Recursive method used to descend down the xml hierarchy and instantiate
-     * views, instantiate their children, and then call onFinishInflate().
-     *
-     * This implementation just records the merge status before calling the default implementation.
-     */
-    @LayoutlibDelegate
-    /*package*/ static void rInflate(LayoutInflater thisInflater,
-            XmlPullParser parser, View parent, final AttributeSet attrs,
-            boolean finishInflate) throws XmlPullParserException, IOException {
-
-        if (finishInflate == false) {
-            // this is a merge rInflate!
-            if (thisInflater instanceof BridgeInflater) {
-                ((BridgeInflater) thisInflater).setIsInMerge(true);
-            }
-        }
-
-        // ---- START DEFAULT IMPLEMENTATION.
-
-        thisInflater.rInflate_Original(parser, parent, attrs, finishInflate);
-
-        // ---- END DEFAULT IMPLEMENTATION.
-
-        if (finishInflate == false) {
-            // this is a merge rInflate!
-            if (thisInflater instanceof BridgeInflater) {
-                ((BridgeInflater) thisInflater).setIsInMerge(false);
-            }
-        }
-    }
-
-    @LayoutlibDelegate
-    public static void parseInclude(
-            LayoutInflater thisInflater,
-            XmlPullParser parser, View parent, AttributeSet attrs)
-            throws XmlPullParserException, IOException {
-
-        int type;
-
-        if (parent instanceof ViewGroup) {
-            final int layout = attrs.getAttributeResourceValue(null, "layout", 0);
-            if (layout == 0) {
-                final String value = attrs.getAttributeValue(null, "layout");
-                if (value == null) {
-                    throw new InflateException("You must specifiy a layout in the"
-                            + " include tag: <include layout=\"@layout/layoutID\" />");
-                } else {
-                    throw new InflateException("You must specifiy a valid layout "
-                            + "reference. The layout ID " + value + " is not valid.");
-                }
-            } else {
-                final XmlResourceParser childParser =
-                    thisInflater.getContext().getResources().getLayout(layout);
-
-                try {
-                    final AttributeSet childAttrs = Xml.asAttributeSet(childParser);
-
-                    while ((type = childParser.next()) != XmlPullParser.START_TAG &&
-                            type != XmlPullParser.END_DOCUMENT) {
-                        // Empty.
-                    }
-
-                    if (type != XmlPullParser.START_TAG) {
-                        throw new InflateException(childParser.getPositionDescription() +
-                                ": No start tag found!");
-                    }
-
-                    final String childName = childParser.getName();
-
-                    if (TAG_MERGE.equals(childName)) {
-                        // Inflate all children.
-                        thisInflater.rInflate(childParser, parent, childAttrs, false);
-                    } else {
-                        final View view = thisInflater.createViewFromTag(parent, childName, childAttrs);
-                        final ViewGroup group = (ViewGroup) parent;
-
-                        // We try to load the layout params set in the <include /> tag. If
-                        // they don't exist, we will rely on the layout params set in the
-                        // included XML file.
-                        // During a layoutparams generation, a runtime exception is thrown
-                        // if either layout_width or layout_height is missing. We catch
-                        // this exception and set localParams accordingly: true means we
-                        // successfully loaded layout params from the <include /> tag,
-                        // false means we need to rely on the included layout params.
-                        ViewGroup.LayoutParams params = null;
-                        try {
-                            // ---- START CHANGES
-                            sIsInInclude = true;
-                            // ---- END CHANGES
-
-                            params = group.generateLayoutParams(attrs);
-
-                        } catch (RuntimeException e) {
-                            // ---- START CHANGES
-                            sIsInInclude = false;
-                            // ---- END CHANGES
-
-                            params = group.generateLayoutParams(childAttrs);
-                        } finally {
-                            // ---- START CHANGES
-                            sIsInInclude = false;
-                            // ---- END CHANGES
-
-                            if (params != null) {
-                                view.setLayoutParams(params);
-                            }
-                        }
-
-                        // Inflate all children.
-                        thisInflater.rInflate(childParser, view, childAttrs, true);
-
-                        // Attempt to override the included layout's android:id with the
-                        // one set on the <include /> tag itself.
-                        TypedArray a = thisInflater.mContext.obtainStyledAttributes(attrs,
-                            com.android.internal.R.styleable.View, 0, 0);
-                        int id = a.getResourceId(com.android.internal.R.styleable.View_id, View.NO_ID);
-                        // While we're at it, let's try to override android:visibility.
-                        int visibility = a.getInt(com.android.internal.R.styleable.View_visibility, -1);
-                        a.recycle();
-
-                        if (id != View.NO_ID) {
-                            view.setId(id);
-                        }
-
-                        switch (visibility) {
-                            case 0:
-                                view.setVisibility(View.VISIBLE);
-                                break;
-                            case 1:
-                                view.setVisibility(View.INVISIBLE);
-                                break;
-                            case 2:
-                                view.setVisibility(View.GONE);
-                                break;
-                        }
-
-                        group.addView(view);
-                    }
-                } finally {
-                    childParser.close();
-                }
-            }
-        } else {
-            throw new InflateException("<include /> can only be used inside of a ViewGroup");
-        }
-
-        final int currentDepth = parser.getDepth();
-        while (((type = parser.next()) != XmlPullParser.END_TAG ||
-                parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) {
-            // Empty
-        }
-    }
-
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/SurfaceView.java b/tools/layoutlib/bridge/src/android/view/SurfaceView.java
deleted file mode 100644
index 6aa4b3b..0000000
--- a/tools/layoutlib/bridge/src/android/view/SurfaceView.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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;
-
-import com.android.layoutlib.bridge.MockView;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-
-/**
- * Mock version of the SurfaceView.
- * Only non override public methods from the real SurfaceView have been added in there.
- * Methods that take an unknown class as parameter or as return object, have been removed for now.
- *
- * TODO: generate automatically.
- *
- */
-public class SurfaceView extends MockView {
-
-    public SurfaceView(Context context) {
-        this(context, null);
-    }
-
-    public SurfaceView(Context context, AttributeSet attrs) {
-        this(context, attrs , 0);
-    }
-
-    public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public SurfaceHolder getHolder() {
-        return mSurfaceHolder;
-    }
-
-    private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
-
-        @Override
-        public boolean isCreating() {
-            return false;
-        }
-
-        @Override
-        public void addCallback(Callback callback) {
-        }
-
-        @Override
-        public void removeCallback(Callback callback) {
-        }
-
-        @Override
-        public void setFixedSize(int width, int height) {
-        }
-
-        @Override
-        public void setSizeFromLayout() {
-        }
-
-        @Override
-        public void setFormat(int format) {
-        }
-
-        @Override
-        public void setType(int type) {
-        }
-
-        @Override
-        public void setKeepScreenOn(boolean screenOn) {
-        }
-
-        @Override
-        public Canvas lockCanvas() {
-            return null;
-        }
-
-        @Override
-        public Canvas lockCanvas(Rect dirty) {
-            return null;
-        }
-
-        @Override
-        public void unlockCanvasAndPost(Canvas canvas) {
-        }
-
-        @Override
-        public Surface getSurface() {
-            return null;
-        }
-
-        @Override
-        public Rect getSurfaceFrame() {
-            return null;
-        }
-    };
-}
-
diff --git a/tools/layoutlib/bridge/src/android/view/ViewConfiguration_Accessor.java b/tools/layoutlib/bridge/src/android/view/ViewConfiguration_Accessor.java
deleted file mode 100644
index c3533e0..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewConfiguration_Accessor.java
+++ /dev/null
@@ -1,29 +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.view;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class ViewConfiguration_Accessor {
-
-    public static void clearConfigurations() {
-        // clear the stored ViewConfiguration since the map is per density and not per context.
-        ViewConfiguration.sConfigurations.clear();
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java
deleted file mode 100644
index 14b84ef..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link ViewRootImpl}
- *
- * Through the layoutlib_create tool, the original  methods of ViewRootImpl have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class ViewRootImpl_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isInTouchMode() {
-        return false; // this allows displaying selection.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/View_Delegate.java b/tools/layoutlib/bridge/src/android/view/View_Delegate.java
deleted file mode 100644
index 8215f7c..0000000
--- a/tools/layoutlib/bridge/src/android/view/View_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link View}
- *
- * Through the layoutlib_create tool, the original  methods of View have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class View_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isInEditMode(View thisView) {
-        return true;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java b/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java
deleted file mode 100644
index 2606e55..0000000
--- a/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of
- * {@link WindowManagerGlobal}
- *
- * Through the layoutlib_create tool, the original  methods of WindowManagerGlobal have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-public class WindowManagerGlobal_Delegate {
-
-    private static IWindowManager sService;
-
-    @LayoutlibDelegate
-    public static IWindowManager getWindowManagerService() {
-        return sService;
-    }
-
-    // ---- internal implementation stuff ----
-
-    public static void setWindowManagerService(IWindowManager service) {
-        sService = service;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java b/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
deleted file mode 100644
index 1fd7836..0000000
--- a/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.accessibility;
-
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.content.Context;
-import android.content.pm.ServiceInfo;
-import android.view.IWindow;
-import android.view.View;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * System level service that serves as an event dispatch for {@link AccessibilityEvent}s.
- * Such events are generated when something notable happens in the user interface,
- * for example an {@link android.app.Activity} starts, the focus or selection of a
- * {@link android.view.View} changes etc. Parties interested in handling accessibility
- * events implement and register an accessibility service which extends
- * {@link android.accessibilityservice.AccessibilityService}.
- *
- * @see AccessibilityEvent
- * @see android.accessibilityservice.AccessibilityService
- * @see android.content.Context#getSystemService
- */
-public final class AccessibilityManager {
-    private static AccessibilityManager sInstance = new AccessibilityManager();
-
-    /**
-     * Listener for the accessibility state.
-     */
-    public interface AccessibilityStateChangeListener {
-
-        /**
-         * Called back on change in the accessibility state.
-         *
-         * @param enabled Whether accessibility is enabled.
-         */
-        public void onAccessibilityStateChanged(boolean enabled);
-    }
-
-    /**
-     * Get an AccessibilityManager instance (create one if necessary).
-     *
-     * @hide
-     */
-    public static AccessibilityManager getInstance(Context context) {
-        return sInstance;
-    }
-
-    /**
-     * Create an instance.
-     *
-     * @param context A {@link Context}.
-     */
-    private AccessibilityManager() {
-    }
-
-    /**
-     * Returns if the {@link AccessibilityManager} is enabled.
-     *
-     * @return True if this {@link AccessibilityManager} is enabled, false otherwise.
-     */
-    public boolean isEnabled() {
-        return false;
-    }
-
-    /**
-     * Sends an {@link AccessibilityEvent}. If this {@link AccessibilityManager} is not
-     * enabled the call is a NOOP.
-     *
-     * @param event The {@link AccessibilityEvent}.
-     *
-     * @throws IllegalStateException if a client tries to send an {@link AccessibilityEvent}
-     *         while accessibility is not enabled.
-     */
-    public void sendAccessibilityEvent(AccessibilityEvent event) {
-    }
-
-    /**
-     * Requests interruption of the accessibility feedback from all accessibility services.
-     */
-    public void interrupt() {
-    }
-
-    /**
-     * Returns the {@link ServiceInfo}s of the installed accessibility services.
-     *
-     * @return An unmodifiable list with {@link ServiceInfo}s.
-     */
-    public List<ServiceInfo> getAccessibilityServiceList() {
-        // normal implementation does this in some case, so let's do the same
-        // (unmodifiableList wrapped around null).
-        List<ServiceInfo> services = null;
-        return Collections.unmodifiableList(services);
-    }
-
-    public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() {
-        // normal implementation does this in some case, so let's do the same
-        // (unmodifiableList wrapped around null).
-        List<AccessibilityServiceInfo> services = null;
-        return Collections.unmodifiableList(services);
-    }
-
-    public boolean addAccessibilityStateChangeListener(
-            AccessibilityStateChangeListener listener) {
-        return true;
-    }
-
-    public boolean removeAccessibilityStateChangeListener(
-            AccessibilityStateChangeListener listener) {
-        return true;
-    }
-
-    public int addAccessibilityInteractionConnection(IWindow windowToken,
-            IAccessibilityInteractionConnection connection) {
-        return View.NO_ID;
-    }
-
-    public void removeAccessibilityInteractionConnection(IWindow windowToken) {
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java b/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java
deleted file mode 100644
index dc4f9c8..0000000
--- a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java
+++ /dev/null
@@ -1,27 +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.view.inputmethod;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class InputMethodManager_Accessor {
-
-    public static void resetInstance() {
-        InputMethodManager.sInstance = null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java b/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java
deleted file mode 100644
index 7c98847..0000000
--- a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.inputmethod;
-
-import com.android.layoutlib.bridge.android.BridgeIInputMethodManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.os.Looper;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link InputMethodManager}
- *
- * Through the layoutlib_create tool, the original  methods of InputMethodManager have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class InputMethodManager_Delegate {
-
-    // ---- Overridden methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static InputMethodManager getInstance() {
-        synchronized (InputMethodManager.class) {
-            InputMethodManager imm = InputMethodManager.peekInstance();
-            if (imm == null) {
-                imm = new InputMethodManager(
-                        new BridgeIInputMethodManager(), Looper.getMainLooper());
-                InputMethodManager.sInstance = imm;
-            }
-            return imm;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/webkit/WebView.java b/tools/layoutlib/bridge/src/android/webkit/WebView.java
deleted file mode 100644
index 202f204..0000000
--- a/tools/layoutlib/bridge/src/android/webkit/WebView.java
+++ /dev/null
@@ -1,238 +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.webkit;
-
-import com.android.layoutlib.bridge.MockView;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Picture;
-import android.os.Bundle;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * Mock version of the WebView.
- * Only non override public methods from the real WebView have been added in there.
- * Methods that take an unknown class as parameter or as return object, have been removed for now.
- * 
- * TODO: generate automatically.
- *
- */
-public class WebView extends MockView {
-
-    /**
-     * Construct a new WebView with a Context object.
-     * @param context A Context object used to access application assets.
-     */
-    public WebView(Context context) {
-        this(context, null);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     */
-    public WebView(Context context, AttributeSet attrs) {
-        this(context, attrs, com.android.internal.R.attr.webViewStyle);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters and a default style.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     * @param defStyle The default style resource ID.
-     */
-    public WebView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-    
-    // START FAKE PUBLIC METHODS
-    
-    public void setHorizontalScrollbarOverlay(boolean overlay) {
-    }
-
-    public void setVerticalScrollbarOverlay(boolean overlay) {
-    }
-
-    public boolean overlayHorizontalScrollbar() {
-        return false;
-    }
-
-    public boolean overlayVerticalScrollbar() {
-        return false;
-    }
-
-    public void savePassword(String host, String username, String password) {
-    }
-
-    public void setHttpAuthUsernamePassword(String host, String realm,
-            String username, String password) {
-    }
-
-    public String[] getHttpAuthUsernamePassword(String host, String realm) {
-        return null;
-    }
-
-    public void destroy() {
-    }
-
-    public static void enablePlatformNotifications() {
-    }
-
-    public static void disablePlatformNotifications() {
-    }
-
-    public void loadUrl(String url) {
-    }
-
-    public void loadData(String data, String mimeType, String encoding) {
-    }
-
-    public void loadDataWithBaseURL(String baseUrl, String data,
-            String mimeType, String encoding, String failUrl) {
-    }
-
-    public void stopLoading() {
-    }
-
-    public void reload() {
-    }
-
-    public boolean canGoBack() {
-        return false;
-    }
-
-    public void goBack() {
-    }
-
-    public boolean canGoForward() {
-        return false;
-    }
-
-    public void goForward() {
-    }
-
-    public boolean canGoBackOrForward(int steps) {
-        return false;
-    }
-
-    public void goBackOrForward(int steps) {
-    }
-
-    public boolean pageUp(boolean top) {
-        return false;
-    }
-    
-    public boolean pageDown(boolean bottom) {
-        return false;
-    }
-
-    public void clearView() {
-    }
-    
-    public Picture capturePicture() {
-        return null;
-    }
-
-    public float getScale() {
-        return 0;
-    }
-
-    public void setInitialScale(int scaleInPercent) {
-    }
-
-    public void invokeZoomPicker() {
-    }
-
-    public void requestFocusNodeHref(Message hrefMsg) {
-    }
-
-    public void requestImageRef(Message msg) {
-    }
-
-    public String getUrl() {
-        return null;
-    }
-
-    public String getTitle() {
-        return null;
-    }
-
-    public Bitmap getFavicon() {
-        return null;
-    }
-
-    public int getProgress() {
-        return 0;
-    }
-    
-    public int getContentHeight() {
-        return 0;
-    }
-
-    public void pauseTimers() {
-    }
-
-    public void resumeTimers() {
-    }
-
-    public void clearCache() {
-    }
-
-    public void clearFormData() {
-    }
-
-    public void clearHistory() {
-    }
-
-    public void clearSslPreferences() {
-    }
-
-    public static String findAddress(String addr) {
-        return null;
-    }
-
-    public void documentHasImages(Message response) {
-    }
-
-    public void setWebViewClient(WebViewClient client) {
-    }
-
-    public void setDownloadListener(DownloadListener listener) {
-    }
-
-    public void setWebChromeClient(WebChromeClient client) {
-    }
-
-    public void addJavascriptInterface(Object obj, String interfaceName) {
-    }
-
-    public View getZoomControls() {
-        return null;
-    }
-
-    public boolean zoomIn() {
-        return false;
-    }
-
-    public boolean zoomOut() {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/policy/PolicyManager.java b/tools/layoutlib/bridge/src/com/android/internal/policy/PolicyManager.java
deleted file mode 100644
index 0100dc5..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/policy/PolicyManager.java
+++ /dev/null
@@ -1,72 +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.internal.policy;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.RenderAction;
-
-import android.content.Context;
-import android.view.BridgeInflater;
-import android.view.FallbackEventHandler;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManagerPolicy;
-
-/**
- * Custom implementation of PolicyManager that does nothing to run in LayoutLib.
- *
- */
-public class PolicyManager {
-
-    public static Window makeNewWindow(Context context) {
-        // this will likely crash somewhere beyond so we log it.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Call to PolicyManager.makeNewWindow is not supported", null);
-        return null;
-    }
-
-    public static LayoutInflater makeNewLayoutInflater(Context context) {
-        return new BridgeInflater(context, RenderAction.getCurrentContext().getProjectCallback());
-    }
-
-    public static WindowManagerPolicy makeNewWindowManager() {
-        // this will likely crash somewhere beyond so we log it.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Call to PolicyManager.makeNewWindowManager is not supported", null);
-        return null;
-    }
-
-    public static FallbackEventHandler makeNewFallbackEventHandler(Context context) {
-        return new FallbackEventHandler() {
-            @Override
-            public void setView(View v) {
-            }
-
-            @Override
-            public void preDispatchKeyEvent(KeyEvent event) {
-            }
-
-            @Override
-            public boolean dispatchKeyEvent(KeyEvent event) {
-                return false;
-            }
-        };
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/textservice/ITextServicesManager_Stub_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/textservice/ITextServicesManager_Stub_Delegate.java
deleted file mode 100644
index 3017292..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/textservice/ITextServicesManager_Stub_Delegate.java
+++ /dev/null
@@ -1,111 +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.internal.textservice;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.view.textservice.SpellCheckerInfo;
-import android.view.textservice.SpellCheckerSubtype;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of
- * {@link ITextServicesManager$Stub}
- *
- * Through the layoutlib_create tool, the original  methods of Stub have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class ITextServicesManager_Stub_Delegate {
-
-    @LayoutlibDelegate
-    public static ITextServicesManager asInterface(IBinder obj) {
-        // ignore the obj and return a fake interface implementation
-        return new FakeTextServicesManager();
-    }
-
-    private static class FakeTextServicesManager implements ITextServicesManager {
-
-        @Override
-        public void finishSpellCheckerService(ISpellCheckerSessionListener arg0)
-                throws RemoteException {
-            // TODO Auto-generated method stub
-
-        }
-
-        @Override
-        public SpellCheckerInfo getCurrentSpellChecker(String arg0) throws RemoteException {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public SpellCheckerSubtype getCurrentSpellCheckerSubtype(String arg0, boolean arg1)
-                throws RemoteException {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public SpellCheckerInfo[] getEnabledSpellCheckers() throws RemoteException {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public void getSpellCheckerService(String arg0, String arg1,
-                ITextServicesSessionListener arg2, ISpellCheckerSessionListener arg3, Bundle arg4)
-                throws RemoteException {
-            // TODO Auto-generated method stub
-
-        }
-
-        @Override
-        public boolean isSpellCheckerEnabled() throws RemoteException {
-            // TODO Auto-generated method stub
-            return false;
-        }
-
-        @Override
-        public void setCurrentSpellChecker(String arg0, String arg1) throws RemoteException {
-            // TODO Auto-generated method stub
-
-        }
-
-        @Override
-        public void setCurrentSpellCheckerSubtype(String arg0, int arg1) throws RemoteException {
-            // TODO Auto-generated method stub
-
-        }
-
-        @Override
-        public void setSpellCheckerEnabled(boolean arg0) throws RemoteException {
-            // TODO Auto-generated method stub
-
-        }
-
-        @Override
-        public IBinder asBinder() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-    }
- }
diff --git a/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java
deleted file mode 100644
index bf998b8..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java
+++ /dev/null
@@ -1,74 +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.internal.util;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link XmlUtils}
- *
- * Through the layoutlib_create tool, the original  methods of XmlUtils have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class XmlUtils_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static final int convertValueToInt(CharSequence charSeq, int defaultValue) {
-        if (null == charSeq)
-            return defaultValue;
-
-        String nm = charSeq.toString();
-
-        // This code is copied from the original implementation. The issue is that
-        // The Dalvik libraries are able to handle Integer.parse("XXXXXXXX", 16) where XXXXXXX
-        // is > 80000000 but the Java VM cannot.
-
-        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 ((int)Long.parseLong(nm.substring(index), base)) * sign;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
deleted file mode 100644
index ab4be71..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ /dev/null
@@ -1,639 +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 com.android.layoutlib.bridge;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
-import com.android.ide.common.rendering.api.Capability;
-import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.impl.FontLoader;
-import com.android.layoutlib.bridge.impl.RenderDrawable;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import com.android.layoutlib.bridge.util.DynamicIdMap;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.create.MethodAdapter;
-import com.android.tools.layoutlib.create.OverrideMethod;
-import com.android.util.Pair;
-import com.ibm.icu.util.ULocale;
-
-import android.content.res.BridgeAssetManager;
-import android.graphics.Bitmap;
-import android.graphics.Typeface_Accessor;
-import android.graphics.Typeface_Delegate;
-import android.os.Looper;
-import android.os.Looper_Accessor;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-
-import java.io.File;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * Main entry point of the LayoutLib Bridge.
- * <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
- * {@link #createScene(SceneParams)}
- */
-public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
-
-    private static final String ICU_LOCALE_DIRECTION_RTL = "right-to-left";
-
-    public static class StaticMethodNotImplementedException extends RuntimeException {
-        private static final long serialVersionUID = 1L;
-
-        public StaticMethodNotImplementedException(String msg) {
-            super(msg);
-        }
-    }
-
-    /**
-     * Lock to ensure only one rendering/inflating happens at a time.
-     * This is due to some singleton in the Android framework.
-     */
-    private final static ReentrantLock sLock = new ReentrantLock();
-
-    /**
-     * Maps from id to resource type/name. This is for com.android.internal.R
-     */
-    private final static Map<Integer, Pair<ResourceType, String>> sRMap =
-        new HashMap<Integer, Pair<ResourceType, String>>();
-
-    /**
-     * Same as sRMap except for int[] instead of int resources. This is for android.R only.
-     */
-    private final static Map<IntArray, String> sRArrayMap = new HashMap<IntArray, String>();
-    /**
-     * Reverse map compared to sRMap, resource type -> (resource name -> id).
-     * This is for com.android.internal.R.
-     */
-    private final static Map<ResourceType, Map<String, Integer>> sRevRMap =
-        new EnumMap<ResourceType, Map<String,Integer>>(ResourceType.class);
-
-    // framework resources are defined as 0x01XX#### where XX is the resource type (layout,
-    // drawable, etc...). Using FF as the type allows for 255 resource types before we get a
-    // collision which should be fine.
-    private final static int DYNAMIC_ID_SEED_START = 0x01ff0000;
-    private final static DynamicIdMap sDynamicIds = new DynamicIdMap(DYNAMIC_ID_SEED_START);
-
-    private final static Map<Object, Map<String, SoftReference<Bitmap>>> sProjectBitmapCache =
-        new HashMap<Object, Map<String, SoftReference<Bitmap>>>();
-    private final static Map<Object, Map<String, SoftReference<NinePatchChunk>>> sProject9PatchCache =
-        new HashMap<Object, Map<String, SoftReference<NinePatchChunk>>>();
-
-    private final static Map<String, SoftReference<Bitmap>> sFrameworkBitmapCache =
-        new HashMap<String, SoftReference<Bitmap>>();
-    private final static Map<String, SoftReference<NinePatchChunk>> sFramework9PatchCache =
-        new HashMap<String, SoftReference<NinePatchChunk>>();
-
-    private static Map<String, Map<String, Integer>> sEnumValueMap;
-    private static Map<String, String> sPlatformProperties;
-
-    /**
-     * int[] wrapper to use as keys in maps.
-     */
-    private final static class IntArray {
-        private int[] mArray;
-
-        private IntArray() {
-            // do nothing
-        }
-
-        private IntArray(int[] a) {
-            mArray = a;
-        }
-
-        private void set(int[] a) {
-            mArray = a;
-        }
-
-        @Override
-        public int hashCode() {
-            return Arrays.hashCode(mArray);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) return true;
-            if (obj == null) return false;
-            if (getClass() != obj.getClass()) return false;
-
-            IntArray other = (IntArray) obj;
-            if (!Arrays.equals(mArray, other.mArray)) return false;
-            return true;
-        }
-    }
-
-    /** Instance of IntArrayWrapper to be reused in {@link #resolveResourceId(int[])}. */
-    private final static IntArray sIntArrayWrapper = new IntArray();
-
-    /**
-     * A default log than prints to stdout/stderr.
-     */
-    private final static LayoutLog sDefaultLog = new LayoutLog() {
-        @Override
-        public void error(String tag, String message, Object data) {
-            System.err.println(message);
-        }
-
-        @Override
-        public void error(String tag, String message, Throwable throwable, Object data) {
-            System.err.println(message);
-        }
-
-        @Override
-        public void warning(String tag, String message, Object data) {
-            System.out.println(message);
-        }
-    };
-
-    /**
-     * Current log.
-     */
-    private static LayoutLog sCurrentLog = sDefaultLog;
-
-    private EnumSet<Capability> mCapabilities;
-
-    @Override
-    public int getApiLevel() {
-        return com.android.ide.common.rendering.api.Bridge.API_CURRENT;
-    }
-
-    @Override
-    public EnumSet<Capability> getCapabilities() {
-        return mCapabilities;
-    }
-
-    @Override
-    public boolean init(Map<String,String> platformProperties,
-            File fontLocation,
-            Map<String, Map<String, Integer>> enumValueMap,
-            LayoutLog log) {
-        sPlatformProperties = platformProperties;
-        sEnumValueMap = enumValueMap;
-
-        // don't use EnumSet.allOf(), because the bridge doesn't come with its specific version
-        // of layoutlib_api. It is provided by the client which could have a more recent version
-        // with newer, unsupported capabilities.
-        mCapabilities = EnumSet.of(
-                Capability.UNBOUND_RENDERING,
-                Capability.CUSTOM_BACKGROUND_COLOR,
-                Capability.RENDER,
-                Capability.LAYOUT_ONLY,
-                Capability.EMBEDDED_LAYOUT,
-                Capability.VIEW_MANIPULATION,
-                Capability.PLAY_ANIMATION,
-                Capability.ANIMATED_VIEW_MANIPULATION,
-                Capability.ADAPTER_BINDING,
-                Capability.EXTENDED_VIEWINFO,
-                Capability.FIXED_SCALABLE_NINE_PATCH,
-                Capability.RTL);
-
-
-        BridgeAssetManager.initSystem();
-
-        // When DEBUG_LAYOUT is set and is not 0 or false, setup a default listener
-        // on static (native) methods which prints the signature on the console and
-        // throws an exception.
-        // This is useful when testing the rendering in ADT to identify static native
-        // methods that are ignored -- layoutlib_create makes them returns 0/false/null
-        // which is generally OK yet might be a problem, so this is how you'd find out.
-        //
-        // Currently layoutlib_create only overrides static native method.
-        // Static non-natives are not overridden and thus do not get here.
-        final String debug = System.getenv("DEBUG_LAYOUT");
-        if (debug != null && !debug.equals("0") && !debug.equals("false")) {
-
-            OverrideMethod.setDefaultListener(new MethodAdapter() {
-                @Override
-                public void onInvokeV(String signature, boolean isNative, Object caller) {
-                    sDefaultLog.error(null, "Missing Stub: " + signature +
-                            (isNative ? " (native)" : ""), null /*data*/);
-
-                    if (debug.equalsIgnoreCase("throw")) {
-                        // Throwing this exception doesn't seem that useful. It breaks
-                        // the layout editor yet doesn't display anything meaningful to the
-                        // user. Having the error in the console is just as useful. We'll
-                        // throw it only if the environment variable is "throw" or "THROW".
-                        throw new StaticMethodNotImplementedException(signature);
-                    }
-                }
-            });
-        }
-
-        // load the fonts.
-        FontLoader fontLoader = FontLoader.create(fontLocation.getAbsolutePath());
-        if (fontLoader != null) {
-            Typeface_Delegate.init(fontLoader);
-        } else {
-            log.error(LayoutLog.TAG_BROKEN,
-                    "Failed create FontLoader in layout lib.", null);
-            return false;
-        }
-
-        // now parse com.android.internal.R (and only this one as android.R is a subset of
-        // the internal version), and put the content in the maps.
-        try {
-            Class<?> r = com.android.internal.R.class;
-
-            for (Class<?> inner : r.getDeclaredClasses()) {
-                String resTypeName = inner.getSimpleName();
-                ResourceType resType = ResourceType.getEnum(resTypeName);
-                if (resType != null) {
-                    Map<String, Integer> fullMap = new HashMap<String, Integer>();
-                    sRevRMap.put(resType, fullMap);
-
-                    for (Field f : inner.getDeclaredFields()) {
-                        // only process static final fields. Since the final attribute may have
-                        // been altered by layoutlib_create, we only check static
-                        int modifiers = f.getModifiers();
-                        if (Modifier.isStatic(modifiers)) {
-                            Class<?> type = f.getType();
-                            if (type.isArray() && type.getComponentType() == int.class) {
-                                // if the object is an int[] we put it in sRArrayMap using an IntArray
-                                // wrapper that properly implements equals and hashcode for the array
-                                // objects, as required by the map contract.
-                                sRArrayMap.put(new IntArray((int[]) f.get(null)), f.getName());
-                            } else if (type == int.class) {
-                                Integer value = (Integer) f.get(null);
-                                sRMap.put(value, Pair.of(resType, f.getName()));
-                                fullMap.put(f.getName(), value);
-                            } else {
-                                assert false;
-                            }
-                        }
-                    }
-                }
-            }
-        } catch (Throwable throwable) {
-            if (log != null) {
-                log.error(LayoutLog.TAG_BROKEN,
-                        "Failed to load com.android.internal.R from the layout library jar",
-                        throwable);
-            }
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean dispose() {
-        BridgeAssetManager.clearSystem();
-
-        // dispose of the default typeface.
-        Typeface_Accessor.resetDefaults();
-
-        return true;
-    }
-
-    /**
-     * Starts a layout session by inflating and rendering it. The method returns a
-     * {@link RenderSession} on which further actions can be taken.
-     *
-     * @param params the {@link SessionParams} object with all the information necessary to create
-     *           the scene.
-     * @return a new {@link RenderSession} object that contains the result of the layout.
-     * @since 5
-     */
-    @Override
-    public RenderSession createSession(SessionParams params) {
-        try {
-            Result lastResult = SUCCESS.createResult();
-            RenderSessionImpl scene = new RenderSessionImpl(params);
-            try {
-                prepareThread();
-                lastResult = scene.init(params.getTimeout());
-                if (lastResult.isSuccess()) {
-                    lastResult = scene.inflate();
-                    if (lastResult.isSuccess()) {
-                        lastResult = scene.render(true /*freshRender*/);
-                    }
-                }
-            } finally {
-                scene.release();
-                cleanupThread();
-            }
-
-            return new BridgeRenderSession(scene, lastResult);
-        } catch (Throwable t) {
-            // get the real cause of the exception.
-            Throwable t2 = t;
-            while (t2.getCause() != null) {
-                t2 = t.getCause();
-            }
-            return new BridgeRenderSession(null,
-                    ERROR_UNKNOWN.createResult(t2.getMessage(), t));
-        }
-    }
-
-    @Override
-    public Result renderDrawable(DrawableParams params) {
-        try {
-            Result lastResult = SUCCESS.createResult();
-            RenderDrawable action = new RenderDrawable(params);
-            try {
-                prepareThread();
-                lastResult = action.init(params.getTimeout());
-                if (lastResult.isSuccess()) {
-                    lastResult = action.render();
-                }
-            } finally {
-                action.release();
-                cleanupThread();
-            }
-
-            return lastResult;
-        } catch (Throwable t) {
-            // get the real cause of the exception.
-            Throwable t2 = t;
-            while (t2.getCause() != null) {
-                t2 = t.getCause();
-            }
-            return ERROR_UNKNOWN.createResult(t2.getMessage(), t);
-        }
-    }
-
-    @Override
-    public void clearCaches(Object projectKey) {
-        if (projectKey != null) {
-            sProjectBitmapCache.remove(projectKey);
-            sProject9PatchCache.remove(projectKey);
-        }
-    }
-
-    @Override
-    public Result getViewParent(Object viewObject) {
-        if (viewObject instanceof View) {
-            return Status.SUCCESS.createResult(((View)viewObject).getParent());
-        }
-
-        throw new IllegalArgumentException("viewObject is not a View");
-    }
-
-    @Override
-    public Result getViewIndex(Object viewObject) {
-        if (viewObject instanceof View) {
-            View view = (View) viewObject;
-            ViewParent parentView = view.getParent();
-
-            if (parentView instanceof ViewGroup) {
-                Status.SUCCESS.createResult(((ViewGroup) parentView).indexOfChild(view));
-            }
-
-            return Status.SUCCESS.createResult();
-        }
-
-        throw new IllegalArgumentException("viewObject is not a View");
-    }
-
-    @Override
-    public boolean isRtl(String locale) {
-        return isLocaleRtl(locale);
-    }
-
-    public static boolean isLocaleRtl(String locale) {
-        if (locale == null) {
-            locale = "";
-        }
-        ULocale uLocale = new ULocale(locale);
-        return uLocale.getCharacterOrientation().equals(ICU_LOCALE_DIRECTION_RTL) ?
-                true : false;
-    }
-
-    /**
-     * Returns the lock for the bridge
-     */
-    public static ReentrantLock getLock() {
-        return sLock;
-    }
-
-    /**
-     * Prepares the current thread for rendering.
-     *
-     * Note that while this can be called several time, the first call to {@link #cleanupThread()}
-     * will do the clean-up, and make the thread unable to do further scene actions.
-     */
-    public static void prepareThread() {
-        // we need to make sure the Looper has been initialized for this thread.
-        // this is required for View that creates Handler objects.
-        if (Looper.myLooper() == null) {
-            Looper.prepareMainLooper();
-        }
-    }
-
-    /**
-     * Cleans up thread-specific data. After this, the thread cannot be used for scene actions.
-     * <p>
-     * Note that it doesn't matter how many times {@link #prepareThread()} was called, a single
-     * call to this will prevent the thread from doing further scene actions
-     */
-    public static void cleanupThread() {
-        // clean up the looper
-        Looper_Accessor.cleanupThread();
-    }
-
-    public static LayoutLog getLog() {
-        return sCurrentLog;
-    }
-
-    public static void setLog(LayoutLog log) {
-        // check only the thread currently owning the lock can do this.
-        if (sLock.isHeldByCurrentThread() == false) {
-            throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
-        }
-
-        if (log != null) {
-            sCurrentLog = log;
-        } else {
-            sCurrentLog = sDefaultLog;
-        }
-    }
-
-    /**
-     * Returns details of a framework resource from its integer value.
-     * @param value the integer value
-     * @return a Pair containing the resource type and name, or null if the id
-     *     does not match any resource.
-     */
-    public static Pair<ResourceType, String> resolveResourceId(int value) {
-        Pair<ResourceType, String> pair = sRMap.get(value);
-        if (pair == null) {
-            pair = sDynamicIds.resolveId(value);
-            if (pair == null) {
-                //System.out.println(String.format("Missing id: %1$08X (%1$d)", value));
-            }
-        }
-        return pair;
-    }
-
-    /**
-     * Returns the name of a framework resource whose value is an int array.
-     * @param array
-     */
-    public static String resolveResourceId(int[] array) {
-        sIntArrayWrapper.set(array);
-        return sRArrayMap.get(sIntArrayWrapper);
-    }
-
-    /**
-     * Returns the integer id of a framework resource, from a given resource type and resource name.
-     * @param type the type of the resource
-     * @param name the name of the resource.
-     * @return an {@link Integer} containing the resource id, or null if no resource were found.
-     */
-    public static Integer getResourceId(ResourceType type, String name) {
-        Map<String, Integer> map = sRevRMap.get(type);
-        Integer value = null;
-        if (map != null) {
-            value = map.get(name);
-        }
-
-        if (value == null) {
-            value = sDynamicIds.getId(type, name);
-        }
-
-        return value;
-    }
-
-    /**
-     * Returns the list of possible enums for a given attribute name.
-     */
-    public static Map<String, Integer> getEnumValues(String attributeName) {
-        if (sEnumValueMap != null) {
-            return sEnumValueMap.get(attributeName);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the platform build properties.
-     */
-    public static Map<String, String> getPlatformProperties() {
-        return sPlatformProperties;
-    }
-
-    /**
-     * Returns the bitmap for a specific path, from a specific project cache, or from the
-     * framework cache.
-     * @param value the path of the bitmap
-     * @param projectKey the key of the project, or null to query the framework cache.
-     * @return the cached Bitmap or null if not found.
-     */
-    public static Bitmap getCachedBitmap(String value, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
-            if (map != null) {
-                SoftReference<Bitmap> ref = map.get(value);
-                if (ref != null) {
-                    return ref.get();
-                }
-            }
-        } else {
-            SoftReference<Bitmap> ref = sFrameworkBitmapCache.get(value);
-            if (ref != null) {
-                return ref.get();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Sets a bitmap in a project cache or in the framework cache.
-     * @param value the path of the bitmap
-     * @param bmp the Bitmap object
-     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
-     */
-    public static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
-
-            if (map == null) {
-                map = new HashMap<String, SoftReference<Bitmap>>();
-                sProjectBitmapCache.put(projectKey, map);
-            }
-
-            map.put(value, new SoftReference<Bitmap>(bmp));
-        } else {
-            sFrameworkBitmapCache.put(value, new SoftReference<Bitmap>(bmp));
-        }
-    }
-
-    /**
-     * Returns the 9 patch chunk for a specific path, from a specific project cache, or from the
-     * framework cache.
-     * @param value the path of the 9 patch
-     * @param projectKey the key of the project, or null to query the framework cache.
-     * @return the cached 9 patch or null if not found.
-     */
-    public static NinePatchChunk getCached9Patch(String value, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
-
-            if (map != null) {
-                SoftReference<NinePatchChunk> ref = map.get(value);
-                if (ref != null) {
-                    return ref.get();
-                }
-            }
-        } else {
-            SoftReference<NinePatchChunk> ref = sFramework9PatchCache.get(value);
-            if (ref != null) {
-                return ref.get();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Sets a 9 patch chunk in a project cache or in the framework cache.
-     * @param value the path of the 9 patch
-     * @param ninePatch the 9 patch object
-     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
-     */
-    public static void setCached9Patch(String value, NinePatchChunk ninePatch, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
-
-            if (map == null) {
-                map = new HashMap<String, SoftReference<NinePatchChunk>>();
-                sProject9PatchCache.put(projectKey, map);
-            }
-
-            map.put(value, new SoftReference<NinePatchChunk>(ninePatch));
-        } else {
-            sFramework9PatchCache.put(value, new SoftReference<NinePatchChunk>(ninePatch));
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
deleted file mode 100644
index eb9e7f1..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
+++ /dev/null
@@ -1,51 +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 com.android.layoutlib.bridge;
-
-/**
- * Constant definition class.<br>
- * <br>
- * Most constants have a prefix defining the content.
- * <ul>
- * <li><code>WS_</code> Workspace path constant. Those are absolute paths,
- * from the project root.</li>
- * <li><code>OS_</code> OS path constant. These paths are different depending on the platform.</li>
- * <li><code>FN_</code> File name constant.</li>
- * <li><code>FD_</code> Folder name constant.</li>
- * <li><code>EXT_</code> File extension constant. This does NOT include a dot.</li>
- * <li><code>DOT_</code> File extension constant. This start with a dot.</li>
- * <li><code>RE_</code> Regexp constant.</li>
- * <li><code>NS_</code> Namespace constant.</li>
- * <li><code>CLASS_</code> Fully qualified class name.</li>
- * </ul>
- *
- */
-public class BridgeConstants {
-
-    /** Namespace for the resource XML */
-    public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android";
-
-    /** App auto namespace */
-    public final static String NS_APP_RES_AUTO = "http://schemas.android.com/apk/res-auto";
-
-    public final static String R = "com.android.internal.R";
-
-
-    public final static String MATCH_PARENT = "match_parent";
-    public final static String FILL_PARENT = "fill_parent";
-    public final static String WRAP_CONTENT = "wrap_content";
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
deleted file mode 100644
index f9f4b3a..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.awt.image.BufferedImage;
-import java.util.List;
-import java.util.Map;
-
-/**
- * An implementation of {@link RenderSession}.
- *
- * This is a pretty basic class that does almost nothing. All of the work is done in
- * {@link RenderSessionImpl}.
- *
- */
-public class BridgeRenderSession extends RenderSession {
-
-    private final RenderSessionImpl mSession;
-    private Result mLastResult;
-
-    @Override
-    public Result getResult() {
-        return mLastResult;
-    }
-
-    @Override
-    public BufferedImage getImage() {
-        return mSession.getImage();
-    }
-
-    @Override
-    public boolean isAlphaChannelImage() {
-        return mSession.isAlphaChannelImage();
-    }
-
-    @Override
-    public List<ViewInfo> getRootViews() {
-        return mSession.getViewInfos();
-    }
-
-    @Override
-    public Map<String, String> getDefaultProperties(Object viewObject) {
-        return mSession.getDefaultProperties(viewObject);
-    }
-
-    @Override
-    public Result getProperty(Object objectView, String propertyName) {
-        // pass
-        return super.getProperty(objectView, propertyName);
-    }
-
-    @Override
-    public Result setProperty(Object objectView, String propertyName, String propertyValue) {
-        // pass
-        return super.setProperty(objectView, propertyName, propertyValue);
-    }
-
-    @Override
-    public Result render(long timeout) {
-        try {
-            Bridge.prepareThread();
-            mLastResult = mSession.acquire(timeout);
-            if (mLastResult.isSuccess()) {
-                mLastResult = mSession.render(false /*freshRender*/);
-            }
-        } finally {
-            mSession.release();
-            Bridge.cleanupThread();
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result animate(Object targetObject, String animationName,
-            boolean isFrameworkAnimation, IAnimationListener listener) {
-        try {
-            Bridge.prepareThread();
-            mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-            if (mLastResult.isSuccess()) {
-                mLastResult = mSession.animate(targetObject, animationName, isFrameworkAnimation,
-                        listener);
-            }
-        } finally {
-            mSession.release();
-            Bridge.cleanupThread();
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result insertChild(Object parentView, ILayoutPullParser childXml, int index,
-            IAnimationListener listener) {
-        if (parentView instanceof ViewGroup == false) {
-            throw new IllegalArgumentException("parentView is not a ViewGroup");
-        }
-
-        try {
-            Bridge.prepareThread();
-            mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-            if (mLastResult.isSuccess()) {
-                mLastResult = mSession.insertChild((ViewGroup) parentView, childXml, index,
-                        listener);
-            }
-        } finally {
-            mSession.release();
-            Bridge.cleanupThread();
-        }
-
-        return mLastResult;
-    }
-
-
-    @Override
-    public Result moveChild(Object parentView, Object childView, int index,
-            Map<String, String> layoutParams, IAnimationListener listener) {
-        if (parentView instanceof ViewGroup == false) {
-            throw new IllegalArgumentException("parentView is not a ViewGroup");
-        }
-        if (childView instanceof View == false) {
-            throw new IllegalArgumentException("childView is not a View");
-        }
-
-        try {
-            Bridge.prepareThread();
-            mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-            if (mLastResult.isSuccess()) {
-                mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index,
-                        layoutParams, listener);
-            }
-        } finally {
-            mSession.release();
-            Bridge.cleanupThread();
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result removeChild(Object childView, IAnimationListener listener) {
-        if (childView instanceof View == false) {
-            throw new IllegalArgumentException("childView is not a View");
-        }
-
-        try {
-            Bridge.prepareThread();
-            mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-            if (mLastResult.isSuccess()) {
-                mLastResult = mSession.removeChild((View) childView, listener);
-            }
-        } finally {
-            mSession.release();
-            Bridge.cleanupThread();
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public void dispose() {
-    }
-
-    /*package*/ BridgeRenderSession(RenderSessionImpl scene, Result lastResult) {
-        mSession = scene;
-        if (scene != null) {
-            mSession.setScene(this);
-        }
-        mLastResult = lastResult;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
deleted file mode 100644
index 3d50b2a..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
+++ /dev/null
@@ -1,47 +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 com.android.layoutlib.bridge;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.widget.TextView;
-
-/**
- * Base class for mocked views.
- *
- * TODO: implement onDraw and draw a rectangle in a random color with the name of the class
- * (or better the id of the view).
- */
-public class MockView extends TextView {
-
-    public MockView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        setText(this.getClass().getSimpleName());
-        setTextColor(0xFF000000);
-        setGravity(Gravity.CENTER);
-    }
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        canvas.drawARGB(0xFF, 0x7F, 0x7F, 0x7F);
-
-        super.onDraw(canvas);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
deleted file mode 100644
index 01740b1..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
-import android.content.ContentValues;
-import android.content.IContentProvider;
-import android.content.OperationApplicationException;
-import android.content.res.AssetFileDescriptor;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.ICancellationSignal;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-
-/**
- * Mock implementation of {@link IContentProvider}.
- *
- * TODO: never return null when the method is not supposed to. Return fake data instead.
- */
-public final class BridgeContentProvider implements IContentProvider {
-    @Override
-    public ContentProviderResult[] applyBatch(String callingPackage,
-            ArrayList<ContentProviderOperation> arg0)
-            throws RemoteException, OperationApplicationException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int bulkInsert(String callingPackage, Uri arg0, ContentValues[] arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public Bundle call(String callingPackage, String arg0, String arg1, Bundle arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int delete(String callingPackage, Uri arg0, String arg1, String[] arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public String getType(Uri arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Uri insert(String callingPackage, Uri arg0, ContentValues arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AssetFileDescriptor openAssetFile(
-            String callingPackage, Uri arg0, String arg1, ICancellationSignal signal)
-            throws RemoteException, FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ParcelFileDescriptor openFile(
-            String callingPackage, Uri arg0, String arg1, ICancellationSignal signal)
-            throws RemoteException, FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Cursor query(String callingPackage, Uri arg0, String[] arg1, String arg2, String[] arg3,
-            String arg4, ICancellationSignal arg5) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int update(String callingPackage, Uri arg0, ContentValues arg1, String arg2,
-            String[] arg3) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String[] getStreamTypes(Uri arg0, String arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AssetFileDescriptor openTypedAssetFile(String callingPackage, Uri arg0, String arg1,
-            Bundle arg2, ICancellationSignal signal) throws RemoteException, FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ICancellationSignal createCancellationSignal() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException {
-        return null;
-    }
-
-    @Override
-    public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
deleted file mode 100644
index 8d259d7..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.IContentProvider;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Bundle;
-
-/**
- * A mock content resolver for the LayoutLib Bridge.
- * <p/>
- * It won't serve any actual data but it's good enough for all
- * the widgets which expect to have a content resolver available via
- * {@link BridgeContext#getContentResolver()}.
- */
-public class BridgeContentResolver extends ContentResolver {
-
-    private BridgeContentProvider mProvider = null;
-
-    public BridgeContentResolver(Context context) {
-        super(context);
-    }
-
-    @Override
-    public IContentProvider acquireProvider(Context c, String name) {
-        if (mProvider == null) {
-            mProvider = new BridgeContentProvider();
-        }
-
-        return mProvider;
-    }
-
-    @Override
-    public IContentProvider acquireExistingProvider(Context c, String name) {
-        if (mProvider == null) {
-            mProvider = new BridgeContentProvider();
-        }
-
-        return mProvider;
-    }
-
-    @Override
-    public boolean releaseProvider(IContentProvider icp) {
-        // ignore
-        return false;
-    }
-
-    @Override
-    protected IContentProvider acquireUnstableProvider(Context c, String name) {
-        return acquireProvider(c, name);
-    }
-
-    @Override
-    public boolean releaseUnstableProvider(IContentProvider icp) {
-        return releaseProvider(icp);
-    }
-
-    /** @hide */
-    @Override
-    public void unstableProviderDied(IContentProvider icp) {
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void registerContentObserver(Uri uri, boolean notifyForDescendents,
-            ContentObserver observer) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void unregisterContentObserver(ContentObserver observer) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void startSync(Uri uri, Bundle extras) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void cancelSync(Uri uri) {
-        // pass
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
deleted file mode 100644
index b9294ab..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ /dev/null
@@ -1,1437 +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 com.android.layoutlib.bridge.android;
-
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.IProjectCallback;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.view.WindowManagerImpl;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.Stack;
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
-import android.content.res.BridgeResources;
-import android.content.res.BridgeTypedArray;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.Resources.Theme;
-import android.content.res.TypedArray;
-import android.database.DatabaseErrorHandler;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.PowerManager;
-import android.os.UserHandle;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.BridgeInflater;
-import android.view.Display;
-import android.view.DisplayAdjustments;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.textservice.TextServicesManager;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Custom implementation of Context/Activity to handle non compiled resources.
- */
-public final class BridgeContext extends Context {
-
-    private Resources mSystemResources;
-    private final HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>();
-    private final Object mProjectKey;
-    private final DisplayMetrics mMetrics;
-    private final RenderResources mRenderResources;
-    private final Configuration mConfig;
-    private final ApplicationInfo mApplicationInfo;
-    private final IProjectCallback mProjectCallback;
-    private final WindowManager mWindowManager;
-
-    private Resources.Theme mTheme;
-
-    private final Map<Object, Map<String, String>> mDefaultPropMaps =
-        new IdentityHashMap<Object, Map<String,String>>();
-
-    // maps for dynamically generated id representing style objects (StyleResourceValue)
-    private Map<Integer, StyleResourceValue> mDynamicIdToStyleMap;
-    private Map<StyleResourceValue, Integer> mStyleToDynamicIdMap;
-    private int mDynamicIdGenerator = 0x01030000; // Base id for framework R.style
-
-    // cache for TypedArray generated from IStyleResourceValue object
-    private Map<int[], Map<Integer, TypedArray>> mTypedArrayCache;
-    private BridgeInflater mBridgeInflater;
-
-    private BridgeContentResolver mContentResolver;
-
-    private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<BridgeXmlBlockParser>();
-
-    /**
-     * @param projectKey An Object identifying the project. This is used for the cache mechanism.
-     * @param metrics the {@link DisplayMetrics}.
-     * @param renderResources the configured resources (both framework and projects) for this
-     * render.
-     * @param projectCallback
-     * @param config the Configuration object for this render.
-     * @param targetSdkVersion the targetSdkVersion of the application.
-     */
-    public BridgeContext(Object projectKey, DisplayMetrics metrics,
-            RenderResources renderResources,
-            IProjectCallback projectCallback,
-            Configuration config,
-            int targetSdkVersion,
-            boolean hasRtlSupport) {
-        mProjectKey = projectKey;
-        mMetrics = metrics;
-        mProjectCallback = projectCallback;
-
-        mRenderResources = renderResources;
-        mConfig = config;
-
-        mApplicationInfo = new ApplicationInfo();
-        mApplicationInfo.targetSdkVersion = targetSdkVersion;
-        if (hasRtlSupport) {
-            mApplicationInfo.flags = mApplicationInfo.flags | ApplicationInfo.FLAG_SUPPORTS_RTL;
-        }
-
-        mWindowManager = new WindowManagerImpl(mMetrics);
-    }
-
-    /**
-     * Initializes the {@link Resources} singleton to be linked to this {@link Context}, its
-     * {@link DisplayMetrics}, {@link Configuration}, and {@link IProjectCallback}.
-     *
-     * @see #disposeResources()
-     */
-    public void initResources() {
-        AssetManager assetManager = AssetManager.getSystem();
-
-        mSystemResources = BridgeResources.initSystem(
-                this,
-                assetManager,
-                mMetrics,
-                mConfig,
-                mProjectCallback);
-        mTheme = mSystemResources.newTheme();
-    }
-
-    /**
-     * Disposes the {@link Resources} singleton.
-     */
-    public void disposeResources() {
-        BridgeResources.disposeSystem();
-    }
-
-    public void setBridgeInflater(BridgeInflater inflater) {
-        mBridgeInflater = inflater;
-    }
-
-    public void addViewKey(View view, Object viewKey) {
-        mViewKeyMap.put(view, viewKey);
-    }
-
-    public Object getViewKey(View view) {
-        return mViewKeyMap.get(view);
-    }
-
-    public Object getProjectKey() {
-        return mProjectKey;
-    }
-
-    public DisplayMetrics getMetrics() {
-        return mMetrics;
-    }
-
-    public IProjectCallback getProjectCallback() {
-        return mProjectCallback;
-    }
-
-    public RenderResources getRenderResources() {
-        return mRenderResources;
-    }
-
-    public Map<String, String> getDefaultPropMap(Object key) {
-        return mDefaultPropMaps.get(key);
-    }
-
-    public Configuration getConfiguration() {
-        return mConfig;
-    }
-
-    /**
-     * Adds a parser to the stack.
-     * @param parser the parser to add.
-     */
-    public void pushParser(BridgeXmlBlockParser parser) {
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("PUSH " + parser.getParser().toString());
-        }
-        mParserStack.push(parser);
-    }
-
-    /**
-     * Removes the parser at the top of the stack
-     */
-    public void popParser() {
-        BridgeXmlBlockParser parser = mParserStack.pop();
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("POPD " + parser.getParser().toString());
-        }
-    }
-
-    /**
-     * Returns the current parser at the top the of the stack.
-     * @return a parser or null.
-     */
-    public BridgeXmlBlockParser getCurrentParser() {
-        return mParserStack.peek();
-    }
-
-    /**
-     * Returns the previous parser.
-     * @return a parser or null if there isn't any previous parser
-     */
-    public BridgeXmlBlockParser getPreviousParser() {
-        if (mParserStack.size() < 2) {
-            return null;
-        }
-        return mParserStack.get(mParserStack.size() - 2);
-    }
-
-    public boolean resolveThemeAttribute(int resid, TypedValue outValue, boolean resolveRefs) {
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resid);
-        boolean isFrameworkRes = true;
-        if (resourceInfo == null) {
-            resourceInfo = mProjectCallback.resolveResourceId(resid);
-            isFrameworkRes = false;
-        }
-
-        if (resourceInfo == null) {
-            return false;
-        }
-
-        ResourceValue value = mRenderResources.findItemInTheme(resourceInfo.getSecond(),
-                isFrameworkRes);
-        if (resolveRefs) {
-            value = mRenderResources.resolveResValue(value);
-        }
-
-        // check if this is a style resource
-        if (value instanceof StyleResourceValue) {
-            // get the id that will represent this style.
-            outValue.resourceId = getDynamicIdByStyle((StyleResourceValue)value);
-            return true;
-        }
-
-
-        int a;
-        // if this is a framework value.
-        if (value.isFramework()) {
-            // look for idName in the android R classes.
-            // use 0 a default res value as it's not a valid id value.
-            a = getFrameworkResourceValue(value.getResourceType(), value.getName(), 0 /*defValue*/);
-        } else {
-            // look for idName in the project R class.
-            // use 0 a default res value as it's not a valid id value.
-            a = getProjectResourceValue(value.getResourceType(), value.getName(), 0 /*defValue*/);
-        }
-
-        if (a != 0) {
-            outValue.resourceId = a;
-            return true;
-        }
-
-        return false;
-    }
-
-
-    public ResourceReference resolveId(int id) {
-        // first get the String related to this id in the framework
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
-
-        if (resourceInfo != null) {
-            return new ResourceReference(resourceInfo.getSecond(), true);
-        }
-
-        // didn't find a match in the framework? look in the project.
-        if (mProjectCallback != null) {
-            resourceInfo = mProjectCallback.resolveResourceId(id);
-
-            if (resourceInfo != null) {
-                return new ResourceReference(resourceInfo.getSecond(), false);
-            }
-        }
-
-        return null;
-    }
-
-    public Pair<View, Boolean> inflateView(ResourceReference resource, ViewGroup parent,
-            boolean attachToRoot, boolean skipCallbackParser) {
-        boolean isPlatformLayout = resource.isFramework();
-
-        if (isPlatformLayout == false && skipCallbackParser == false) {
-            // check if the project callback can provide us with a custom parser.
-            ILayoutPullParser parser = getParser(resource);
-
-            if (parser != null) {
-                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
-                        this, resource.isFramework());
-                try {
-                    pushParser(blockParser);
-                    return Pair.of(
-                            mBridgeInflater.inflate(blockParser, parent, attachToRoot),
-                            true);
-                } finally {
-                    popParser();
-                }
-            }
-        }
-
-        ResourceValue resValue;
-        if (resource instanceof ResourceValue) {
-            resValue = (ResourceValue) resource;
-        } else {
-            if (isPlatformLayout) {
-                resValue = mRenderResources.getFrameworkResource(ResourceType.LAYOUT,
-                        resource.getName());
-            } else {
-                resValue = mRenderResources.getProjectResource(ResourceType.LAYOUT,
-                        resource.getName());
-            }
-        }
-
-        if (resValue != null) {
-
-            File xml = new File(resValue.getValue());
-            if (xml.isFile()) {
-                // we need to create a pull parser around the layout XML file, and then
-                // give that to our XmlBlockParser
-                try {
-                    XmlPullParser parser = ParserFactory.create(xml);
-
-                    // set the resource ref to have correct view cookies
-                    mBridgeInflater.setResourceReference(resource);
-
-                    BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
-                            this, resource.isFramework());
-                    try {
-                        pushParser(blockParser);
-                        return Pair.of(
-                                mBridgeInflater.inflate(blockParser, parent, attachToRoot),
-                                false);
-                    } finally {
-                        popParser();
-                    }
-                } catch (XmlPullParserException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                            "Failed to configure parser for " + xml, e, null /*data*/);
-                    // we'll return null below.
-                } catch (FileNotFoundException e) {
-                    // this shouldn't happen since we check above.
-                } finally {
-                    mBridgeInflater.setResourceReference(null);
-                }
-            } else {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        String.format("File %s is missing!", xml), null);
-            }
-        } else {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    String.format("Layout %s%s does not exist.", isPlatformLayout ? "android:" : "",
-                            resource.getName()), null);
-        }
-
-        return Pair.of(null, false);
-    }
-
-    @SuppressWarnings("deprecation")
-    private ILayoutPullParser getParser(ResourceReference resource) {
-        ILayoutPullParser parser;
-        if (resource instanceof ResourceValue) {
-            parser = mProjectCallback.getParser((ResourceValue) resource);
-        } else {
-            parser = mProjectCallback.getParser(resource.getName());
-        }
-        return parser;
-    }
-
-    // ------------ Context methods
-
-    @Override
-    public Resources getResources() {
-        return mSystemResources;
-    }
-
-    @Override
-    public Theme getTheme() {
-        return mTheme;
-    }
-
-    @Override
-    public ClassLoader getClassLoader() {
-        return this.getClass().getClassLoader();
-    }
-
-    @Override
-    public Object getSystemService(String service) {
-        if (LAYOUT_INFLATER_SERVICE.equals(service)) {
-            return mBridgeInflater;
-        }
-
-        if (TEXT_SERVICES_MANAGER_SERVICE.equals(service)) {
-            // we need to return a valid service to avoid NPE
-            return TextServicesManager.getInstance();
-        }
-
-        if (WINDOW_SERVICE.equals(service)) {
-            return mWindowManager;
-        }
-
-        // needed by SearchView
-        if (INPUT_METHOD_SERVICE.equals(service)) {
-            return null;
-        }
-
-        if (POWER_SERVICE.equals(service)) {
-            return new PowerManager(this, new BridgePowerManager(), new Handler());
-        }
-
-        throw new UnsupportedOperationException("Unsupported Service: " + service);
-    }
-
-
-    @Override
-    public final TypedArray obtainStyledAttributes(int[] attrs) {
-        return createStyleBasedTypedArray(mRenderResources.getCurrentTheme(), attrs);
-    }
-
-    @Override
-    public final TypedArray obtainStyledAttributes(int resid, int[] attrs)
-            throws Resources.NotFoundException {
-        // get the StyleResourceValue based on the resId;
-        StyleResourceValue style = getStyleByDynamicId(resid);
-
-        if (style == null) {
-            throw new Resources.NotFoundException();
-        }
-
-        if (mTypedArrayCache == null) {
-            mTypedArrayCache = new HashMap<int[], Map<Integer,TypedArray>>();
-
-            Map<Integer, TypedArray> map = new HashMap<Integer, TypedArray>();
-            mTypedArrayCache.put(attrs, map);
-
-            BridgeTypedArray ta = createStyleBasedTypedArray(style, attrs);
-            map.put(resid, ta);
-
-            return ta;
-        }
-
-        // get the 2nd map
-        Map<Integer, TypedArray> map = mTypedArrayCache.get(attrs);
-        if (map == null) {
-            map = new HashMap<Integer, TypedArray>();
-            mTypedArrayCache.put(attrs, map);
-        }
-
-        // get the array from the 2nd map
-        TypedArray ta = map.get(resid);
-
-        if (ta == null) {
-            ta = createStyleBasedTypedArray(style, attrs);
-            map.put(resid, ta);
-        }
-
-        return ta;
-    }
-
-    @Override
-    public final TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) {
-        return obtainStyledAttributes(set, attrs, 0, 0);
-    }
-
-    @Override
-    public TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs,
-            int defStyleAttr, int defStyleRes) {
-
-        Map<String, String> defaultPropMap = null;
-        boolean isPlatformFile = true;
-
-        // Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java
-        if (set instanceof BridgeXmlBlockParser) {
-            BridgeXmlBlockParser parser = null;
-            parser = (BridgeXmlBlockParser)set;
-
-            isPlatformFile = parser.isPlatformFile();
-
-            Object key = parser.getViewCookie();
-            if (key != null) {
-                defaultPropMap = mDefaultPropMaps.get(key);
-                if (defaultPropMap == null) {
-                    defaultPropMap = new HashMap<String, String>();
-                    mDefaultPropMaps.put(key, defaultPropMap);
-                }
-            }
-
-        } else if (set instanceof BridgeLayoutParamsMapAttributes) {
-            // this is only for temp layout params generated dynamically, so this is never
-            // platform content.
-            isPlatformFile = false;
-        } else if (set != null) { // null parser is ok
-            // really this should not be happening since its instantiated in Bridge
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Parser is not a BridgeXmlBlockParser!", null /*data*/);
-            return null;
-        }
-
-        List<Pair<String, Boolean>> attributeList = searchAttrs(attrs);
-
-        BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length,
-                isPlatformFile);
-
-        // look for a custom style.
-        String customStyle = null;
-        if (set != null) {
-            customStyle = set.getAttributeValue(null /* namespace*/, "style");
-        }
-
-        StyleResourceValue customStyleValues = null;
-        if (customStyle != null) {
-            ResourceValue item = mRenderResources.findResValue(customStyle,
-                    false /*forceFrameworkOnly*/);
-
-            // resolve it in case it links to something else
-            item = mRenderResources.resolveResValue(item);
-
-            if (item instanceof StyleResourceValue) {
-                customStyleValues = (StyleResourceValue)item;
-            }
-        }
-
-        // resolve the defStyleAttr value into a IStyleResourceValue
-        StyleResourceValue defStyleValues = null;
-
-        if (defStyleAttr != 0) {
-            // get the name from the int.
-            Pair<String, Boolean> defStyleAttribute = searchAttr(defStyleAttr);
-
-            if (defaultPropMap != null) {
-                String defStyleName = defStyleAttribute.getFirst();
-                if (defStyleAttribute.getSecond()) {
-                    defStyleName = "android:" + defStyleName;
-                }
-                defaultPropMap.put("style", defStyleName);
-            }
-
-            // look for the style in the current theme, and its parent:
-            ResourceValue item = mRenderResources.findItemInTheme(defStyleAttribute.getFirst(),
-                    defStyleAttribute.getSecond());
-
-            if (item != null) {
-                // item is a reference to a style entry. Search for it.
-                item = mRenderResources.findResValue(item.getValue(),
-                        false /*forceFrameworkOnly*/);
-
-                if (item instanceof StyleResourceValue) {
-                    defStyleValues = (StyleResourceValue)item;
-                }
-            } else {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
-                        String.format(
-                                "Failed to find style '%s' in current theme",
-                                defStyleAttribute.getFirst()),
-                        null /*data*/);
-            }
-        } else if (defStyleRes != 0) {
-            boolean isFrameworkRes = true;
-            Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
-            if (value == null) {
-                value = mProjectCallback.resolveResourceId(defStyleRes);
-                isFrameworkRes = false;
-            }
-
-            if (value != null) {
-                if (value.getFirst() == ResourceType.STYLE) {
-                    // look for the style in the current theme, and its parent:
-                    ResourceValue item = mRenderResources.findItemInTheme(value.getSecond(),
-                            isFrameworkRes);
-                    if (item != null) {
-                        if (item instanceof StyleResourceValue) {
-                            if (defaultPropMap != null) {
-                                defaultPropMap.put("style", item.getName());
-                            }
-
-                            defStyleValues = (StyleResourceValue)item;
-                        }
-                    } else {
-                        Bridge.getLog().error(null,
-                                String.format(
-                                        "Style with id 0x%x (resolved to '%s') does not exist.",
-                                        defStyleRes, value.getSecond()),
-                                null /*data*/);
-                    }
-                } else {
-                    Bridge.getLog().error(null,
-                            String.format(
-                                    "Resouce id 0x%x is not of type STYLE (instead %s)",
-                                    defStyleRes, value.getFirst().toString()),
-                            null /*data*/);
-                }
-            } else {
-                Bridge.getLog().error(null,
-                        String.format(
-                                "Failed to find style with id 0x%x in current theme",
-                                defStyleRes),
-                        null /*data*/);
-            }
-        }
-
-        String appNamespace = mProjectCallback.getNamespace();
-
-        if (attributeList != null) {
-            for (int index = 0 ; index < attributeList.size() ; index++) {
-                Pair<String, Boolean> attribute = attributeList.get(index);
-
-                if (attribute == null) {
-                    continue;
-                }
-
-                String attrName = attribute.getFirst();
-                boolean frameworkAttr = attribute.getSecond().booleanValue();
-                String value = null;
-                if (set != null) {
-                    value = set.getAttributeValue(
-                            frameworkAttr ? BridgeConstants.NS_RESOURCES : appNamespace,
-                                    attrName);
-
-                    // if this is an app attribute, and the first get fails, try with the
-                    // new res-auto namespace as well
-                    if (frameworkAttr == false && value == null) {
-                        value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, attrName);
-                    }
-                }
-
-                // if there's no direct value for this attribute in the XML, we look for default
-                // values in the widget defStyle, and then in the theme.
-                if (value == null) {
-                    ResourceValue resValue = null;
-
-                    // look for the value in the custom style first (and its parent if needed)
-                    if (customStyleValues != null) {
-                        resValue = mRenderResources.findItemInStyle(customStyleValues,
-                                attrName, frameworkAttr);
-                    }
-
-                    // then look for the value in the default Style (and its parent if needed)
-                    if (resValue == null && defStyleValues != null) {
-                        resValue = mRenderResources.findItemInStyle(defStyleValues,
-                                attrName, frameworkAttr);
-                    }
-
-                    // if the item is not present in the defStyle, we look in the main theme (and
-                    // its parent themes)
-                    if (resValue == null) {
-                        resValue = mRenderResources.findItemInTheme(attrName, frameworkAttr);
-                    }
-
-                    // if we found a value, we make sure this doesn't reference another value.
-                    // So we resolve it.
-                    if (resValue != null) {
-                        // put the first default value, before the resolution.
-                        if (defaultPropMap != null) {
-                            defaultPropMap.put(attrName, resValue.getValue());
-                        }
-
-                        resValue = mRenderResources.resolveResValue(resValue);
-                    }
-
-                    ta.bridgeSetValue(index, attrName, frameworkAttr, resValue);
-                } else {
-                    // there is a value in the XML, but we need to resolve it in case it's
-                    // referencing another resource or a theme value.
-                    ta.bridgeSetValue(index, attrName, frameworkAttr,
-                            mRenderResources.resolveValue(null, attrName, value, isPlatformFile));
-                }
-            }
-        }
-
-        ta.sealArray();
-
-        return ta;
-    }
-
-    @Override
-    public Looper getMainLooper() {
-        return Looper.myLooper();
-    }
-
-
-    // ------------- private new methods
-
-    /**
-     * Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the
-     * values found in the given style.
-     * @see #obtainStyledAttributes(int, int[])
-     */
-    private BridgeTypedArray createStyleBasedTypedArray(StyleResourceValue style, int[] attrs)
-            throws Resources.NotFoundException {
-
-        List<Pair<String, Boolean>> attributes = searchAttrs(attrs);
-
-        BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length,
-                false);
-
-        // for each attribute, get its name so that we can search it in the style
-        for (int i = 0 ; i < attrs.length ; i++) {
-            Pair<String, Boolean> attribute = attributes.get(i);
-
-            if (attribute != null) {
-                // look for the value in the given style
-                ResourceValue resValue = mRenderResources.findItemInStyle(style,
-                        attribute.getFirst(), attribute.getSecond());
-
-                if (resValue != null) {
-                    // resolve it to make sure there are no references left.
-                    ta.bridgeSetValue(i, attribute.getFirst(), attribute.getSecond(),
-                            mRenderResources.resolveResValue(resValue));
-                }
-            }
-        }
-
-        ta.sealArray();
-
-        return ta;
-    }
-
-
-    /**
-     * The input int[] attrs is a list of attributes. The returns a list of information about
-     * each attributes. The information is (name, isFramework)
-     * <p/>
-     *
-     * @param attrs An attribute array reference given to obtainStyledAttributes.
-     * @return List of attribute information.
-     */
-    private List<Pair<String, Boolean>> searchAttrs(int[] attrs) {
-        List<Pair<String, Boolean>> results = new ArrayList<Pair<String, Boolean>>(attrs.length);
-
-        // for each attribute, get its name so that we can search it in the style
-        for (int i = 0 ; i < attrs.length ; i++) {
-            Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attrs[i]);
-            boolean isFramework = false;
-            if (resolvedResource != null) {
-                isFramework = true;
-            } else {
-                resolvedResource = mProjectCallback.resolveResourceId(attrs[i]);
-            }
-
-            if (resolvedResource != null) {
-                results.add(Pair.of(resolvedResource.getSecond(), isFramework));
-            } else {
-                results.add(null);
-            }
-        }
-
-        return results;
-    }
-
-    /**
-     * Searches for the attribute referenced by its internal id.
-     *
-     * @param attr An attribute reference given to obtainStyledAttributes such as defStyle.
-     * @return A (name, isFramework) pair describing the attribute if found. Returns null
-     *         if nothing is found.
-     */
-    public Pair<String, Boolean> searchAttr(int attr) {
-        Pair<ResourceType, String> info = Bridge.resolveResourceId(attr);
-        if (info != null) {
-            return Pair.of(info.getSecond(), Boolean.TRUE);
-        }
-
-        info = mProjectCallback.resolveResourceId(attr);
-        if (info != null) {
-            return Pair.of(info.getSecond(), Boolean.FALSE);
-        }
-
-        return null;
-    }
-
-    public int getDynamicIdByStyle(StyleResourceValue resValue) {
-        if (mDynamicIdToStyleMap == null) {
-            // create the maps.
-            mDynamicIdToStyleMap = new HashMap<Integer, StyleResourceValue>();
-            mStyleToDynamicIdMap = new HashMap<StyleResourceValue, Integer>();
-        }
-
-        // look for an existing id
-        Integer id = mStyleToDynamicIdMap.get(resValue);
-
-        if (id == null) {
-            // generate a new id
-            id = Integer.valueOf(++mDynamicIdGenerator);
-
-            // and add it to the maps.
-            mDynamicIdToStyleMap.put(id, resValue);
-            mStyleToDynamicIdMap.put(resValue, id);
-        }
-
-        return id;
-    }
-
-    private StyleResourceValue getStyleByDynamicId(int i) {
-        if (mDynamicIdToStyleMap != null) {
-            return mDynamicIdToStyleMap.get(i);
-        }
-
-        return null;
-    }
-
-    public int getFrameworkResourceValue(ResourceType resType, String resName, int defValue) {
-        Integer value = Bridge.getResourceId(resType, resName);
-        if (value != null) {
-            return value.intValue();
-        }
-
-        return defValue;
-    }
-
-    public int getProjectResourceValue(ResourceType resType, String resName, int defValue) {
-        if (mProjectCallback != null) {
-            Integer value = mProjectCallback.getResourceId(resType, resName);
-            if (value != null) {
-                return value.intValue();
-            }
-        }
-
-        return defValue;
-    }
-
-    //------------ NOT OVERRIDEN --------------------
-
-    @Override
-    public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public int checkCallingOrSelfPermission(String arg0) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkCallingPermission(String arg0) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkCallingUriPermission(Uri arg0, int arg1) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkPermission(String arg0, int arg1, int arg2) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3,
-            int arg4, int arg5) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public void clearWallpaper() {
-        // pass
-
-    }
-
-    @Override
-    public Context createPackageContext(String arg0, int arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createPackageContextAsUser(String arg0, int arg1, UserHandle user) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createConfigurationContext(Configuration overrideConfiguration) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createDisplayContext(Display display) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String[] databaseList() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public boolean deleteDatabase(String arg0) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public boolean deleteFile(String arg0) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public void enforceCallingOrSelfPermission(String arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1,
-            String arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceCallingPermission(String arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void enforcePermission(String arg0, int arg1, int arg2, String arg3) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3,
-            String arg4) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceUriPermission(Uri arg0, String arg1, String arg2,
-            int arg3, int arg4, int arg5, String arg6) {
-        // pass
-
-    }
-
-    @Override
-    public String[] fileList() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public AssetManager getAssets() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getCacheDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getExternalCacheDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ContentResolver getContentResolver() {
-        if (mContentResolver == null) {
-            mContentResolver = new BridgeContentResolver(this);
-        }
-        return mContentResolver;
-    }
-
-    @Override
-    public File getDatabasePath(String arg0) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getDir(String arg0, int arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getFileStreamPath(String arg0) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getFilesDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getExternalFilesDir(String type) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getPackageCodePath() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public PackageManager getPackageManager() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getPackageName() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getBasePackageName() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getOpPackageName() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfo() {
-        return mApplicationInfo;
-    }
-
-    @Override
-    public String getPackageResourcePath() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getSharedPrefsFile(String name) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public SharedPreferences getSharedPreferences(String arg0, int arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Drawable getWallpaper() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public int getWallpaperDesiredMinimumWidth() {
-        return -1;
-    }
-
-    @Override
-    public int getWallpaperDesiredMinimumHeight() {
-        return -1;
-    }
-
-    @Override
-    public void grantUriPermission(String arg0, Uri arg1, int arg2) {
-        // pass
-
-    }
-
-    @Override
-    public FileInputStream openFileInput(String arg0) throws FileNotFoundException {
-        // pass
-        return null;
-    }
-
-    @Override
-    public FileOutputStream openFileOutput(String arg0, int arg1) throws FileNotFoundException {
-        // pass
-        return null;
-    }
-
-    @Override
-    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1,
-            CursorFactory arg2, DatabaseErrorHandler arg3) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Drawable peekWallpaper() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
-            String arg2, Handler arg3) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiverAsUser(BroadcastReceiver arg0, UserHandle arg0p5,
-            IntentFilter arg1, String arg2, Handler arg3) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void removeStickyBroadcast(Intent arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void revokeUriPermission(Uri arg0, int arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1,
-            BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
-            Bundle arg6) {
-        // pass
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
-            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
-            String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendBroadcastAsUser(Intent intent, UserHandle user) {
-        // pass
-    }
-
-    @Override
-    public void sendBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
-            int initialCode, String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyBroadcast(Intent arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void sendStickyOrderedBroadcast(Intent intent,
-            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
-           Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyOrderedBroadcastAsUser(Intent intent,
-            UserHandle user, BroadcastReceiver resultReceiver,
-            Handler scheduler, int initialCode, String initialData,
-            Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
-        // pass
-    }
-
-    @Override
-    public void setTheme(int arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void setWallpaper(Bitmap arg0) throws IOException {
-        // pass
-
-    }
-
-    @Override
-    public void setWallpaper(InputStream arg0) throws IOException {
-        // pass
-
-    }
-
-    @Override
-    public void startActivity(Intent arg0) {
-        // pass
-    }
-
-    @Override
-    public void startActivity(Intent arg0, Bundle arg1) {
-        // pass
-    }
-
-    @Override
-    public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
-            throws IntentSender.SendIntentException {
-        // pass
-    }
-
-    @Override
-    public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
-            Bundle options) throws IntentSender.SendIntentException {
-        // pass
-    }
-
-    @Override
-    public boolean startInstrumentation(ComponentName arg0, String arg1,
-            Bundle arg2) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public ComponentName startService(Intent arg0) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public boolean stopService(Intent arg0) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public ComponentName startServiceAsUser(Intent arg0, UserHandle arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public boolean stopServiceAsUser(Intent arg0, UserHandle arg1) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public void unbindService(ServiceConnection arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void unregisterReceiver(BroadcastReceiver arg0) {
-        // pass
-
-    }
-
-    @Override
-    public Context getApplicationContext() {
-        return this;
-    }
-
-    @Override
-    public void startActivities(Intent[] arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void startActivities(Intent[] arg0, Bundle arg1) {
-        // pass
-
-    }
-
-    @Override
-    public boolean isRestricted() {
-        return false;
-    }
-
-    @Override
-    public File getObbDir() {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "OBB not supported", null);
-        return null;
-    }
-
-    @Override
-    public DisplayAdjustments getDisplayAdjustments(int displayId) {
-        // pass
-        return null;
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public int getUserId() {
-        return 0; // not used
-    }
-
-    @Override
-    public File[] getExternalFilesDirs(String type) {
-        // pass
-        return new File[0];
-    }
-
-    @Override
-    public File[] getObbDirs() {
-        // pass
-        return new File[0];
-    }
-
-    @Override
-    public File[] getExternalCacheDirs() {
-        // pass
-        return new File[0];
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
deleted file mode 100644
index 3cf5ed5..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
+++ /dev/null
@@ -1,230 +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.layoutlib.bridge.android;
-
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-import com.android.internal.view.IInputMethodManager;
-import com.android.internal.view.InputBindResult;
-
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.text.style.SuggestionSpan;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodSubtype;
-
-import java.util.List;
-
-/**
- * Basic implementation of IInputMethodManager that does nothing.
- *
- */
-public class BridgeIInputMethodManager implements IInputMethodManager {
-
-    @Override
-    public void addClient(IInputMethodClient arg0, IInputContext arg1, int arg2, int arg3)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void finishInput(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public InputMethodSubtype getCurrentInputMethodSubtype() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<InputMethodInfo> getEnabledInputMethodList() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String arg0,
-            boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<InputMethodInfo> getInputMethodList() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public InputMethodSubtype getLastInputMethodSubtype() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List getShortcutInputMethodsAndSubtypes() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void hideMySoftInput(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean hideSoftInput(IInputMethodClient arg0, int arg1, ResultReceiver arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean notifySuggestionPicked(SuggestionSpan arg0, String arg1, int arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void registerSuggestionSpansForNotification(SuggestionSpan[] arg0)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void removeClient(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setAdditionalInputMethodSubtypes(String arg0, InputMethodSubtype[] arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean setCurrentInputMethodSubtype(InputMethodSubtype arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void setImeWindowStatus(IBinder arg0, int arg1, int arg2) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setInputMethod(IBinder arg0, String arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setInputMethodAndSubtype(IBinder arg0, String arg1, InputMethodSubtype arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean setInputMethodEnabled(String arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void showInputMethodAndSubtypeEnablerFromClient(IInputMethodClient arg0, String arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void showInputMethodPickerFromClient(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void showMySoftInput(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean showSoftInput(IInputMethodClient arg0, int arg1, ResultReceiver arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public InputBindResult startInput(IInputMethodClient client, IInputContext inputContext,
-            EditorInfo attribute, int controlFlags) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean switchToLastInputMethod(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-        public boolean switchToNextInputMethod(IBinder arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-        public boolean shouldOfferSwitchingToNextInputMethod(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void updateStatusIcon(IBinder arg0, String arg1, int arg2) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public InputBindResult windowGainedFocus(IInputMethodClient client, IBinder windowToken,
-            int controlFlags, int softInputMode, int windowFlags, EditorInfo attribute,
-            IInputContext inputContext) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java
deleted file mode 100644
index f5912e7..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.layoutlib.bridge.BridgeConstants;
-
-import android.util.AttributeSet;
-
-import java.util.Map;
-
-/**
- * An implementation of the {@link AttributeSet} interface on top of a map of attribute in the form
- * of (name, value).
- *
- * This is meant to be called only from {@link BridgeContext#obtainStyledAttributes(AttributeSet, int[], int, int)}
- * in the case of LayoutParams and therefore isn't a full implementation.
- */
-public class BridgeLayoutParamsMapAttributes implements AttributeSet {
-
-    private final Map<String, String> mAttributes;
-
-    public BridgeLayoutParamsMapAttributes(Map<String, String> attributes) {
-        mAttributes = attributes;
-    }
-
-    @Override
-    public String getAttributeValue(String namespace, String name) {
-        if (BridgeConstants.NS_RESOURCES.equals(namespace)) {
-            return mAttributes.get(name);
-        }
-
-        return null;
-    }
-
-    // ---- the following methods are not called from
-    // BridgeContext#obtainStyledAttributes(AttributeSet, int[], int, int)
-    // Should they ever be called, we'll just implement them on a need basis.
-
-    @Override
-    public int getAttributeCount() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getAttributeName(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getAttributeValue(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getPositionDescription() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeNameResource(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeListValue(String namespace, String attribute,
-            String[] options, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(String namespace, String attribute,
-            boolean defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeResourceValue(String namespace, String attribute,
-            int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeIntValue(String namespace, String attribute,
-            int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(String namespace, String attribute,
-            int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public float getAttributeFloatValue(String namespace, String attribute,
-            float defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeListValue(int index,
-            String[] options, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeResourceValue(int index, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeIntValue(int index, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public float getAttributeFloatValue(int index, float defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getIdAttribute() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getClassAttribute() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getIdAttributeResourceValue(int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getStyleAttribute() {
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
deleted file mode 100644
index 281337c..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ /dev/null
@@ -1,133 +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.layoutlib.bridge.android;
-
-import android.os.IBinder;
-import android.os.IPowerManager;
-import android.os.RemoteException;
-import android.os.WorkSource;
-
-/**
- * Fake implementation of IPowerManager.
- *
- */
-public class BridgePowerManager implements IPowerManager {
-
-    @Override
-    public boolean isScreenOn() throws RemoteException {
-        return true;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void acquireWakeLockWithUid(IBinder arg0, int arg1, String arg2, String arg2_5, int arg3)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void crash(String arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void goToSleep(long arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void nap(long arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void reboot(boolean confirm, String reason, boolean wait) {
-        // pass for now.
-    }
-
-    @Override
-    public void shutdown(boolean confirm, boolean wait) {
-        // pass for now.
-    }
-
-    @Override
-    public void releaseWakeLock(IBinder arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void updateWakeLockUids(IBinder arg0, int[] arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setAttentionLight(boolean arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setTemporaryScreenBrightnessSettingOverride(int arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setMaximumScreenOffTimeoutFromDeviceAdmin(int arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setStayOnSetting(int arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void updateWakeLockWorkSource(IBinder arg0, WorkSource arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public boolean isWakeLockLevelSupported(int level) throws RemoteException {
-        // pass for now.
-        return true;
-    }
-
-    @Override
-    public void userActivity(long time, int event, int flags) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void wakeUp(long time) throws RemoteException {
-        // pass for now.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
deleted file mode 100644
index df576d2..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.view.DragEvent;
-import android.view.IWindow;
-
-/**
- * Implementation of {@link IWindow} to pass to the AttachInfo.
- */
-public final class BridgeWindow implements IWindow {
-
-    @Override
-    public void dispatchAppVisibility(boolean arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchGetNewSurface() throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void resized(Rect arg1, Rect arg1p5, Rect arg2, Rect arg3,
-            boolean arg4, Configuration arg5) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void moved(int arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchScreenState(boolean on) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
-            boolean sync) {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchWallpaperCommand(String action, int x, int y,
-            int z, Bundle extras, boolean sync) {
-        // pass for now.
-    }
-
-    @Override
-    public void closeSystemDialogs(String reason) {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchDragEvent(DragEvent event) {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchSystemUiVisibilityChanged(int seq, int globalUi,
-            int localValue, int localChanges) {
-        // pass for now.
-    }
-
-    @Override
-    public void doneAnimating() {
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // pass for now.
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
deleted file mode 100644
index 09e6878..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.content.ClipData;
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.view.IWindow;
-import android.view.IWindowId;
-import android.view.IWindowSession;
-import android.view.InputChannel;
-import android.view.Surface;
-import android.view.SurfaceView;
-import android.view.WindowManager.LayoutParams;
-
-/**
- * Implementation of {@link IWindowSession} so that mSession is not null in
- * the {@link SurfaceView}.
- */
-public final class BridgeWindowSession implements IWindowSession {
-
-    @Override
-    public int add(IWindow arg0, int seq, LayoutParams arg1, int arg2, Rect arg3,
-            InputChannel outInputchannel)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public int addToDisplay(IWindow arg0, int seq, LayoutParams arg1, int arg2, int displayId,
-                            Rect arg3, InputChannel outInputchannel)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public int addWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2,
-                                      Rect arg3)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public int addToDisplayWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2,
-                                               int displayId, Rect arg3)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public void finishDrawing(IWindow arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public boolean getInTouchMode() throws RemoteException {
-        // pass for now.
-        return false;
-    }
-
-    @Override
-    public boolean performHapticFeedback(IWindow window, int effectId, boolean always) {
-        // pass for now.
-        return false;
-    }
-    @Override
-    public int relayout(IWindow arg0, int seq, LayoutParams arg1, int arg2, int arg3, int arg4,
-            int arg4_5, Rect arg5Z, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b,
-            Surface arg8) throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public void performDeferredDestroy(IWindow window) {
-        // pass for now.
-    }
-
-    @Override
-    public boolean outOfMemory(IWindow window) throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
-        // pass for now.
-    }
-
-    @Override
-    public void remove(IWindow arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setInTouchMode(boolean arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setInsets(IWindow window, int touchable, Rect contentInsets,
-            Rect visibleInsets, Region touchableRegion) {
-        // pass for now.
-    }
-
-    @Override
-    public IBinder prepareDrag(IWindow window, int flags,
-            int thumbnailWidth, int thumbnailHeight, Surface outSurface)
-            throws RemoteException {
-        // pass for now
-        return null;
-    }
-
-    @Override
-    public boolean performDrag(IWindow window, IBinder dragToken,
-            float touchX, float touchY, float thumbCenterX, float thumbCenterY,
-            ClipData data)
-            throws RemoteException {
-        // pass for now
-        return false;
-    }
-
-    @Override
-    public void reportDropResult(IWindow window, boolean consumed) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void dragRecipientEntered(IWindow window) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void dragRecipientExited(IWindow window) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void setWallpaperPosition(IBinder window, float x, float y,
-        float xStep, float yStep) {
-        // pass for now.
-    }
-
-    @Override
-    public void wallpaperOffsetsComplete(IBinder window) {
-        // pass for now.
-    }
-
-    @Override
-    public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
-            int z, Bundle extras, boolean sync) {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void wallpaperCommandComplete(IBinder window, Bundle result) {
-        // pass for now.
-    }
-
-    @Override
-    public void setUniverseTransform(IBinder window, float alpha, float offx, float offy,
-            float dsdx, float dtdx, float dsdy, float dtdy) {
-        // pass for now.
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void onRectangleOnScreenRequested(IBinder window, Rect rectangle, boolean immediate) {
-        // pass for now.
-    }
-
-    @Override
-    public IWindowId getWindowId(IBinder window) throws RemoteException {
-        // pass for now.
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
deleted file mode 100644
index ac8712e..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
+++ /dev/null
@@ -1,494 +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 com.android.layoutlib.bridge.android;
-
-
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.res.XmlResourceParser;
-import android.util.AttributeSet;
-import android.util.BridgeXmlPullAttributes;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-
-/**
- * {@link BridgeXmlBlockParser} reimplements most of android.xml.XmlBlock.Parser.
- * It delegates to both an instance of {@link XmlPullParser} and an instance of
- * XmlPullAttributes (for the {@link AttributeSet} part).
- */
-public class BridgeXmlBlockParser implements XmlResourceParser {
-
-    private final XmlPullParser mParser;
-    private final BridgeXmlPullAttributes mAttrib;
-    private final BridgeContext mContext;
-    private final boolean mPlatformFile;
-
-    private boolean mStarted = false;
-    private int mEventType = START_DOCUMENT;
-
-    private boolean mPopped = true; // default to true in case it's not pushed.
-
-    /**
-     * Builds a {@link BridgeXmlBlockParser}.
-     * @param parser The XmlPullParser to get the content from.
-     * @param context the Context.
-     * @param platformFile Indicates whether the the file is a platform file or not.
-     */
-    public BridgeXmlBlockParser(XmlPullParser parser, BridgeContext context, boolean platformFile) {
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("CRTE " + parser.toString());
-        }
-
-        mParser = parser;
-        mContext = context;
-        mPlatformFile = platformFile;
-        mAttrib = new BridgeXmlPullAttributes(parser, context, mPlatformFile);
-
-        if (mContext != null) {
-            mContext.pushParser(this);
-            mPopped = false;
-        }
-    }
-
-    public XmlPullParser getParser() {
-        return mParser;
-    }
-
-    public boolean isPlatformFile() {
-        return mPlatformFile;
-    }
-
-    public Object getViewCookie() {
-        if (mParser instanceof ILayoutPullParser) {
-            return ((ILayoutPullParser)mParser).getViewCookie();
-        }
-
-        return null;
-    }
-
-    public void ensurePopped() {
-        if (mContext != null && mPopped == false) {
-            mContext.popParser();
-            mPopped = true;
-        }
-    }
-
-    // ------- XmlResourceParser implementation
-
-    @Override
-    public void setFeature(String name, boolean state)
-            throws XmlPullParserException {
-        if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
-            return;
-        }
-        if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name) && state) {
-            return;
-        }
-        throw new XmlPullParserException("Unsupported feature: " + name);
-    }
-
-    @Override
-    public boolean getFeature(String name) {
-        if (FEATURE_PROCESS_NAMESPACES.equals(name)) {
-            return true;
-        }
-        if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void setProperty(String name, Object value) throws XmlPullParserException {
-        throw new XmlPullParserException("setProperty() not supported");
-    }
-
-    @Override
-    public Object getProperty(String name) {
-        return null;
-    }
-
-    @Override
-    public void setInput(Reader in) throws XmlPullParserException {
-        mParser.setInput(in);
-    }
-
-    @Override
-    public void setInput(InputStream inputStream, String inputEncoding)
-            throws XmlPullParserException {
-        mParser.setInput(inputStream, inputEncoding);
-    }
-
-    @Override
-    public void defineEntityReplacementText(String entityName,
-            String replacementText) throws XmlPullParserException {
-        throw new XmlPullParserException(
-                "defineEntityReplacementText() not supported");
-    }
-
-    @Override
-    public String getNamespacePrefix(int pos) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespacePrefix() not supported");
-    }
-
-    @Override
-    public String getInputEncoding() {
-        return null;
-    }
-
-    @Override
-    public String getNamespace(String prefix) {
-        throw new RuntimeException("getNamespace() not supported");
-    }
-
-    @Override
-    public int getNamespaceCount(int depth) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespaceCount() not supported");
-    }
-
-    @Override
-    public String getPositionDescription() {
-        return "Binary XML file line #" + getLineNumber();
-    }
-
-    @Override
-    public String getNamespaceUri(int pos) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespaceUri() not supported");
-    }
-
-    @Override
-    public int getColumnNumber() {
-        return -1;
-    }
-
-    @Override
-    public int getDepth() {
-        return mParser.getDepth();
-    }
-
-    @Override
-    public String getText() {
-        return mParser.getText();
-    }
-
-    @Override
-    public int getLineNumber() {
-        return mParser.getLineNumber();
-    }
-
-    @Override
-    public int getEventType() {
-        return mEventType;
-    }
-
-    @Override
-    public boolean isWhitespace() throws XmlPullParserException {
-        // Original comment: whitespace was stripped by aapt.
-        return mParser.isWhitespace();
-    }
-
-    @Override
-    public String getPrefix() {
-        throw new RuntimeException("getPrefix not supported");
-    }
-
-    @Override
-    public char[] getTextCharacters(int[] holderForStartAndLength) {
-        String txt = getText();
-        char[] chars = null;
-        if (txt != null) {
-            holderForStartAndLength[0] = 0;
-            holderForStartAndLength[1] = txt.length();
-            chars = new char[txt.length()];
-            txt.getChars(0, txt.length(), chars, 0);
-        }
-        return chars;
-    }
-
-    @Override
-    public String getNamespace() {
-        return mParser.getNamespace();
-    }
-
-    @Override
-    public String getName() {
-        return mParser.getName();
-    }
-
-    @Override
-    public String getAttributeNamespace(int index) {
-        return mParser.getAttributeNamespace(index);
-    }
-
-    @Override
-    public String getAttributeName(int index) {
-        return mParser.getAttributeName(index);
-    }
-
-    @Override
-    public String getAttributePrefix(int index) {
-        throw new RuntimeException("getAttributePrefix not supported");
-    }
-
-    @Override
-    public boolean isEmptyElementTag() {
-        // XXX Need to detect this.
-        return false;
-    }
-
-    @Override
-    public int getAttributeCount() {
-        return mParser.getAttributeCount();
-    }
-
-    @Override
-    public String getAttributeValue(int index) {
-        return mParser.getAttributeValue(index);
-    }
-
-    @Override
-    public String getAttributeType(int index) {
-        return "CDATA";
-    }
-
-    @Override
-    public boolean isAttributeDefault(int index) {
-        return false;
-    }
-
-    @Override
-    public int nextToken() throws XmlPullParserException, IOException {
-        return next();
-    }
-
-    @Override
-    public String getAttributeValue(String namespace, String name) {
-        return mParser.getAttributeValue(namespace, name);
-    }
-
-    @Override
-    public int next() throws XmlPullParserException, IOException {
-        if (!mStarted) {
-            mStarted = true;
-
-            if (ParserFactory.LOG_PARSER) {
-                System.out.println("STRT " + mParser.toString());
-            }
-
-            return START_DOCUMENT;
-        }
-
-        int ev = mParser.next();
-
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("NEXT " + mParser.toString() + " " +
-                    eventTypeToString(mEventType) + " -> " + eventTypeToString(ev));
-        }
-
-        if (ev == END_TAG && mParser.getDepth() == 1) {
-            // done with parser remove it from the context stack.
-            ensurePopped();
-
-            if (ParserFactory.LOG_PARSER) {
-                System.out.println("");
-            }
-        }
-
-        mEventType = ev;
-        return ev;
-    }
-
-    public static String eventTypeToString(int eventType) {
-        switch (eventType) {
-            case START_DOCUMENT:
-                return "START_DOC";
-            case END_DOCUMENT:
-                return "END_DOC";
-            case START_TAG:
-                return "START_TAG";
-            case END_TAG:
-                return "END_TAG";
-            case TEXT:
-                return "TEXT";
-            case CDSECT:
-                return "CDSECT";
-            case ENTITY_REF:
-                return "ENTITY_REF";
-            case IGNORABLE_WHITESPACE:
-                return "IGNORABLE_WHITESPACE";
-            case PROCESSING_INSTRUCTION:
-                return "PROCESSING_INSTRUCTION";
-            case COMMENT:
-                return "COMMENT";
-            case DOCDECL:
-                return "DOCDECL";
-        }
-
-        return "????";
-    }
-
-    @Override
-    public void require(int type, String namespace, String name)
-            throws XmlPullParserException {
-        if (type != getEventType()
-                || (namespace != null && !namespace.equals(getNamespace()))
-                || (name != null && !name.equals(getName())))
-            throw new XmlPullParserException("expected " + TYPES[type]
-                    + getPositionDescription());
-    }
-
-    @Override
-    public String nextText() throws XmlPullParserException, IOException {
-        if (getEventType() != START_TAG) {
-            throw new XmlPullParserException(getPositionDescription()
-                    + ": parser must be on START_TAG to read next text", this,
-                    null);
-        }
-        int eventType = next();
-        if (eventType == TEXT) {
-            String result = getText();
-            eventType = next();
-            if (eventType != END_TAG) {
-                throw new XmlPullParserException(
-                        getPositionDescription()
-                                + ": event TEXT it must be immediately followed by END_TAG",
-                        this, null);
-            }
-            return result;
-        } else if (eventType == END_TAG) {
-            return "";
-        } else {
-            throw new XmlPullParserException(getPositionDescription()
-                    + ": parser must be on START_TAG or TEXT to read text",
-                    this, null);
-        }
-    }
-
-    @Override
-    public int nextTag() throws XmlPullParserException, IOException {
-        int eventType = next();
-        if (eventType == TEXT && isWhitespace()) { // skip whitespace
-            eventType = next();
-        }
-        if (eventType != START_TAG && eventType != END_TAG) {
-            throw new XmlPullParserException(getPositionDescription()
-                    + ": expected start or end tag", this, null);
-        }
-        return eventType;
-    }
-
-    // AttributeSet implementation
-
-
-    @Override
-    public void close() {
-        // pass
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
-        return mAttrib.getAttributeBooleanValue(index, defaultValue);
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(String namespace, String attribute,
-            boolean defaultValue) {
-        return mAttrib.getAttributeBooleanValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public float getAttributeFloatValue(int index, float defaultValue) {
-        return mAttrib.getAttributeFloatValue(index, defaultValue);
-    }
-
-    @Override
-    public float getAttributeFloatValue(String namespace, String attribute, float defaultValue) {
-        return mAttrib.getAttributeFloatValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(int index, int defaultValue) {
-        return mAttrib.getAttributeIntValue(index, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
-        return mAttrib.getAttributeIntValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public int getAttributeListValue(int index, String[] options, int defaultValue) {
-        return mAttrib.getAttributeListValue(index, options, defaultValue);
-    }
-
-    @Override
-    public int getAttributeListValue(String namespace, String attribute,
-            String[] options, int defaultValue) {
-        return mAttrib.getAttributeListValue(namespace, attribute, options, defaultValue);
-    }
-
-    @Override
-    public int getAttributeNameResource(int index) {
-        return mAttrib.getAttributeNameResource(index);
-    }
-
-    @Override
-    public int getAttributeResourceValue(int index, int defaultValue) {
-        return mAttrib.getAttributeResourceValue(index, defaultValue);
-    }
-
-    @Override
-    public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
-        return mAttrib.getAttributeResourceValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
-        return mAttrib.getAttributeUnsignedIntValue(index, defaultValue);
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue) {
-        return mAttrib.getAttributeUnsignedIntValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public String getClassAttribute() {
-        return mAttrib.getClassAttribute();
-    }
-
-    @Override
-    public String getIdAttribute() {
-        return mAttrib.getIdAttribute();
-    }
-
-    @Override
-    public int getIdAttributeResourceValue(int defaultValue) {
-        return mAttrib.getIdAttributeResourceValue(defaultValue);
-    }
-
-    @Override
-    public int getStyleAttribute() {
-        return mAttrib.getStyleAttribute();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
deleted file mode 100644
index 7e5ae8d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
+++ /dev/null
@@ -1,66 +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.layoutlib.bridge.android.view;
-
-import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.DisplayAdjustments;
-import android.view.DisplayInfo;
-import android.view.View;
-import android.view.WindowManager;
-
-public class WindowManagerImpl implements WindowManager {
-
-    private final DisplayMetrics mMetrics;
-    private final Display mDisplay;
-
-    public WindowManagerImpl(DisplayMetrics metrics) {
-        mMetrics = metrics;
-
-        DisplayInfo info = new DisplayInfo();
-        info.logicalHeight = mMetrics.heightPixels;
-        info.logicalWidth = mMetrics.widthPixels;
-        mDisplay = new Display(null, Display.DEFAULT_DISPLAY, info,
-                DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
-    }
-
-    @Override
-    public Display getDefaultDisplay() {
-        return mDisplay;
-    }
-
-
-    @Override
-    public void addView(View arg0, android.view.ViewGroup.LayoutParams arg1) {
-        // pass
-    }
-
-    @Override
-    public void removeView(View arg0) {
-        // pass
-    }
-
-    @Override
-    public void updateViewLayout(View arg0, android.view.ViewGroup.LayoutParams arg1) {
-        // pass
-    }
-
-
-    @Override
-    public void removeViewImmediate(View arg0) {
-        // pass
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
deleted file mode 100644
index bcd08eb4..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ /dev/null
@@ -1,323 +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.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.Density;
-import com.android.resources.LayoutDirection;
-import com.android.resources.ResourceType;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Base "bar" class for the window decor around the the edited layout.
- * This is basically an horizontal layout that loads a given layout on creation (it is read
- * through {@link Class#getResourceAsStream(String)}).
- *
- * The given layout should be a merge layout so that all the children belong to this class directly.
- *
- * It also provides a few utility methods to configure the content of the layout.
- */
-abstract class CustomBar extends LinearLayout {
-
-    protected abstract TextView getStyleableTextView();
-
-    protected CustomBar(Context context, Density density, int orientation, String layoutPath,
-            String name) throws XmlPullParserException {
-        super(context);
-        setOrientation(orientation);
-        if (orientation == LinearLayout.HORIZONTAL) {
-            setGravity(Gravity.CENTER_VERTICAL);
-        } else {
-            setGravity(Gravity.CENTER_HORIZONTAL);
-        }
-
-        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
-                Context.LAYOUT_INFLATER_SERVICE);
-
-        XmlPullParser parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath),
-                name);
-
-        BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
-                parser, (BridgeContext) context, false /*platformFile*/);
-
-        try {
-            inflater.inflate(bridgeParser, this, true);
-        } finally {
-            bridgeParser.ensurePopped();
-        }
-    }
-
-    private InputStream getIcon(String iconName, Density[] densityInOut, LayoutDirection direction, 
-            String[] pathOut, boolean tryOtherDensities) {
-        // current density
-        Density density = densityInOut[0];
-
-        // bitmap url relative to this class
-        if (direction != null) {
-            pathOut[0] = "/bars/" + direction.getResourceValue() + "-" + density.getResourceValue()
-                    + "/" + iconName;
-        } else {
-            pathOut[0] = "/bars/" + density.getResourceValue() + "/" + iconName;
-        }
-
-        InputStream stream = getClass().getResourceAsStream(pathOut[0]);
-        if (stream == null && tryOtherDensities) {
-            for (Density d : Density.values()) {
-                if (d != density) {
-                    densityInOut[0] = d;
-                    stream = getIcon(iconName, densityInOut, direction, pathOut,
-                            false /*tryOtherDensities*/);
-                    if (stream != null) {
-                        return stream;
-                    }
-                }
-            }
-            // couldn't find resource with direction qualifier. try without.
-            if (direction != null) {
-                return getIcon(iconName, densityInOut, null, pathOut, true);
-            }
-        }
-
-        return stream;
-    }
-
-    protected void loadIcon(int index, String iconName, Density density) {
-        loadIcon(index, iconName, density, false);
-    }
-
-    protected void loadIcon(int index, String iconName, Density density, boolean isRtl) {
-        View child = getChildAt(index);
-        if (child instanceof ImageView) {
-            ImageView imageView = (ImageView) child;
-
-            String[] pathOut = new String[1];
-            Density[] densityInOut = new Density[] { density };
-            LayoutDirection dir = isRtl ? LayoutDirection.RTL : LayoutDirection.LTR;
-            InputStream stream = getIcon(iconName, densityInOut, dir, pathOut,
-                    true /*tryOtherDensities*/);
-            density = densityInOut[0];
-
-            if (stream != null) {
-                // look for a cached bitmap
-                Bitmap bitmap = Bridge.getCachedBitmap(pathOut[0], true /*isFramework*/);
-                if (bitmap == null) {
-                    try {
-                        bitmap = Bitmap_Delegate.createBitmap(stream, false /*isMutable*/, density);
-                        Bridge.setCachedBitmap(pathOut[0], bitmap, true /*isFramework*/);
-                    } catch (IOException e) {
-                        return;
-                    }
-                }
-
-                if (bitmap != null) {
-                    BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(),
-                            bitmap);
-                    imageView.setImageDrawable(drawable);
-                }
-            }
-        }
-    }
-
-    protected void loadIcon(int index, String iconReference) {
-        ResourceValue value = getResourceValue(iconReference);
-        if (value != null) {
-            loadIcon(index, value);
-        }
-    }
-
-    protected void loadIconById(int id, String iconReference) {
-        ResourceValue value = getResourceValue(iconReference);
-        if (value != null) {
-            loadIconById(id, value);
-        }
-    }
-
-
-    protected Drawable loadIcon(int index, ResourceType type, String name) {
-        BridgeContext bridgeContext = (BridgeContext) mContext;
-        RenderResources res = bridgeContext.getRenderResources();
-
-        // find the resource
-        ResourceValue value = res.getFrameworkResource(type, name);
-
-        // resolve it if needed
-        value = res.resolveResValue(value);
-        return loadIcon(index, value);
-    }
-
-    private Drawable loadIcon(int index, ResourceValue value) {
-        View child = getChildAt(index);
-        if (child instanceof ImageView) {
-            ImageView imageView = (ImageView) child;
-
-            return loadIcon(imageView, value);
-        }
-
-        return null;
-    }
-
-    private Drawable loadIconById(int id, ResourceValue value) {
-        View child = findViewById(id);
-        if (child instanceof ImageView) {
-            ImageView imageView = (ImageView) child;
-
-            return loadIcon(imageView, value);
-        }
-
-        return null;
-    }
-
-
-    private Drawable loadIcon(ImageView imageView, ResourceValue value) {
-        Drawable drawable = ResourceHelper.getDrawable(value, (BridgeContext) mContext);
-        if (drawable != null) {
-            imageView.setImageDrawable(drawable);
-        }
-
-        return drawable;
-    }
-
-    protected TextView setText(int index, String stringReference) {
-        View child = getChildAt(index);
-        if (child instanceof TextView) {
-            TextView textView = (TextView) child;
-            setText(textView, stringReference);
-            return textView;
-        }
-
-        return null;
-    }
-
-    protected TextView setTextById(int id, String stringReference) {
-        View child = findViewById(id);
-        if (child instanceof TextView) {
-            TextView textView = (TextView) child;
-            setText(textView, stringReference);
-            return textView;
-        }
-
-        return null;
-    }
-
-    private void setText(TextView textView, String stringReference) {
-        ResourceValue value = getResourceValue(stringReference);
-        if (value != null) {
-            textView.setText(value.getValue());
-        } else {
-            textView.setText(stringReference);
-        }
-    }
-
-    protected void setStyle(String themeEntryName) {
-
-        BridgeContext bridgeContext = (BridgeContext) mContext;
-        RenderResources res = bridgeContext.getRenderResources();
-
-        ResourceValue value = res.findItemInTheme(themeEntryName, true /*isFrameworkAttr*/);
-        value = res.resolveResValue(value);
-
-        if (value instanceof StyleResourceValue == false) {
-            return;
-        }
-
-        StyleResourceValue style = (StyleResourceValue) value;
-
-        // get the background
-        ResourceValue backgroundValue = res.findItemInStyle(style, "background",
-                true /*isFrameworkAttr*/);
-        backgroundValue = res.resolveResValue(backgroundValue);
-        if (backgroundValue != null) {
-            Drawable d = ResourceHelper.getDrawable(backgroundValue, bridgeContext);
-            if (d != null) {
-                setBackground(d);
-            }
-        }
-
-        TextView textView = getStyleableTextView();
-        if (textView != null) {
-            // get the text style
-            ResourceValue textStyleValue = res.findItemInStyle(style, "titleTextStyle",
-                    true /*isFrameworkAttr*/);
-            textStyleValue = res.resolveResValue(textStyleValue);
-            if (textStyleValue instanceof StyleResourceValue) {
-                StyleResourceValue textStyle = (StyleResourceValue) textStyleValue;
-
-                ResourceValue textSize = res.findItemInStyle(textStyle, "textSize",
-                        true /*isFrameworkAttr*/);
-                textSize = res.resolveResValue(textSize);
-
-                if (textSize != null) {
-                    TypedValue out = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute("textSize", textSize.getValue(), out,
-                            true /*requireUnit*/)) {
-                        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
-                                out.getDimension(bridgeContext.getResources().getDisplayMetrics()));
-                    }
-                }
-
-
-                ResourceValue textColor = res.findItemInStyle(textStyle, "textColor",
-                        true /*isFrameworkAttr*/);
-                textColor = res.resolveResValue(textColor);
-                if (textColor != null) {
-                    ColorStateList stateList = ResourceHelper.getColorStateList(
-                            textColor, bridgeContext);
-                    if (stateList != null) {
-                        textView.setTextColor(stateList);
-                    }
-                }
-            }
-        }
-    }
-
-    private ResourceValue getResourceValue(String reference) {
-        BridgeContext bridgeContext = (BridgeContext) mContext;
-        RenderResources res = bridgeContext.getRenderResources();
-
-        // find the resource
-        ResourceValue value = res.findResValue(reference, false /*isFramework*/);
-
-        // resolve it if needed
-        return res.resolveResValue(value);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java
deleted file mode 100644
index 226649d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.resources.Density;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-public class FakeActionBar extends CustomBar {
-
-    private TextView mTextView;
-
-    public FakeActionBar(Context context, Density density, String label, String icon)
-            throws XmlPullParserException {
-        super(context, density, LinearLayout.HORIZONTAL, "/bars/action_bar.xml", "action_bar.xml");
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        loadIconById(android.R.id.home, icon);
-        mTextView = setText(1, label);
-
-        setStyle("actionBarStyle");
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return mTextView;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
deleted file mode 100644
index 84e676e..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
+++ /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.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.resources.Density;
-import com.android.layoutlib.bridge.Bridge;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-public class NavigationBar extends CustomBar {
-
-    public NavigationBar(Context context, Density density, int orientation, boolean isRtl,
-            boolean rtlEnabled) throws XmlPullParserException {
-        super(context, density, orientation, "/bars/navigation_bar.xml", "navigation_bar.xml");
-
-        setBackgroundColor(0xFF000000);
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        // 0 is a spacer.
-        int back = 1;
-        int recent = 3;
-        if (orientation == LinearLayout.VERTICAL || (isRtl && !rtlEnabled)) {
-            // If RTL is enabled, then layoutlib mirrors the layout for us.
-            back = 3;
-            recent = 1;
-        }
-
-        loadIcon(back,   "ic_sysbar_back.png",   density, isRtl);
-        loadIcon(2,      "ic_sysbar_home.png",   density, isRtl);
-        loadIcon(recent, "ic_sysbar_recent.png", density, isRtl);
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
deleted file mode 100644
index 3692d96..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ /dev/null
@@ -1,55 +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.layoutlib.bridge.bars;
-
-import com.android.resources.Density;
-import com.android.resources.ResourceType;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LevelListDrawable;
-import android.view.Gravity;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-public class StatusBar extends CustomBar {
-
-    public StatusBar(Context context, Density density, int direction, boolean RtlEnabled)
-            throws XmlPullParserException {
-        // FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar.
-
-        super(context, density, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml");
-
-        // FIXME: use FILL_H?
-        setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT);
-        setBackgroundColor(0xFF000000);
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        // 0 is the spacer
-        loadIcon(1, "stat_sys_wifi_signal_4_fully.png", density);
-        loadIcon(2, "stat_sys_battery_charge_anim100.png", density);
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
deleted file mode 100644
index c27859f..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
+++ /dev/null
@@ -1,47 +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.layoutlib.bridge.bars;
-
-import com.android.resources.Density;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-public class TitleBar extends CustomBar {
-
-    private TextView mTextView;
-
-    public TitleBar(Context context, Density density, String label)
-            throws XmlPullParserException {
-        super(context, density, LinearLayout.HORIZONTAL, "/bars/title_bar.xml", "title_bar.xml");
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        mTextView = setText(0, label);
-
-        setStyle("windowTitleBackgroundStyle");
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return mTextView;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
deleted file mode 100644
index ae1217d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.layoutlib.bridge.util.Debug;
-import com.android.layoutlib.bridge.util.SparseWeakArray;
-
-import android.util.SparseArray;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Manages native delegates.
- *
- * This is used in conjunction with layoublib_create: certain Android java classes are mere
- * wrappers around a heavily native based implementation, and we need a way to run these classes
- * in our Eclipse rendering framework without bringing all the native code from the Android
- * platform.
- *
- * Thus we instruct layoutlib_create to modify the bytecode of these classes to replace their
- * native methods by "delegate calls".
- *
- * For example, a native method android.graphics.Matrix.init(...) will actually become
- * a call to android.graphics.Matrix_Delegate.init(...).
- *
- * The Android java classes that use native code uses an int (Java side) to reference native
- * objects. This int is generally directly the pointer to the C structure counterpart.
- * Typically a creation method will return such an int, and then this int will be passed later
- * to a Java method to identify the C object to manipulate.
- *
- * Since we cannot use the Java object reference as the int directly, DelegateManager manages the
- * int -> Delegate class link.
- *
- * Native methods usually always have the int as parameters. The first thing the delegate method
- * will do is call {@link #getDelegate(int)} to get the Java object matching the int.
- *
- * Typical native init methods are returning a new int back to the Java class, so
- * {@link #addNewDelegate(Object)} does the same.
- *
- * The JNI references are counted, so we do the same through a {@link WeakReference}. Because
- * the Java object needs to count as a reference (even though it only holds an int), we use the
- * following mechanism:
- *
- * - {@link #addNewDelegate(Object)} and {@link #removeJavaReferenceFor(int)} adds and removes
- *   the delegate to/from a list. This list hold the reference and prevents the GC from reclaiming
- *   the delegate.
- *
- * - {@link #addNewDelegate(Object)} also adds the delegate to a {@link SparseArray} that holds a
- *   {@link WeakReference} to the delegate. This allows the delegate to be deleted automatically
- *   when nothing references it. This means that any class that holds a delegate (except for the
- *   Java main class) must not use the int but the Delegate class instead. The integers must
- *   only be used in the API between the main Java class and the Delegate.
- *
- * @param <T> the delegate class to manage
- */
-public final class DelegateManager<T> {
-    private final Class<T> mClass;
-    private final SparseWeakArray<T> mDelegates = new SparseWeakArray<T>();
-    /** list used to store delegates when their main object holds a reference to them.
-     * This is to ensure that the WeakReference in the SparseWeakArray doesn't get GC'ed
-     * @see #addNewDelegate(Object)
-     * @see #removeJavaReferenceFor(int)
-     */
-    private final List<T> mJavaReferences = new ArrayList<T>();
-    private int mDelegateCounter = 0;
-
-    public DelegateManager(Class<T> theClass) {
-        mClass = theClass;
-    }
-
-    /**
-     * Returns the delegate from the given native int.
-     * <p>
-     * If the int is zero, then this will always return null.
-     * <p>
-     * If the int is non zero and the delegate is not found, this will throw an assert.
-     *
-     * @param native_object the native int.
-     * @return the delegate or null if not found.
-     */
-    public T getDelegate(int native_object) {
-        if (native_object > 0) {
-            T delegate =  mDelegates.get(native_object);
-
-            if (Debug.DEBUG) {
-                if (delegate == null) {
-                    System.out.println("Unknown " + mClass.getSimpleName() + " with int " +
-                            native_object);
-                }
-            }
-
-            assert delegate != null;
-            return delegate;
-        }
-        return null;
-    }
-
-    /**
-     * Adds a delegate to the manager and returns the native int used to identify it.
-     * @param newDelegate the delegate to add
-     * @return a unique native int to identify the delegate
-     */
-    public int addNewDelegate(T newDelegate) {
-        int native_object = ++mDelegateCounter;
-        mDelegates.put(native_object, newDelegate);
-        assert !mJavaReferences.contains(newDelegate);
-        mJavaReferences.add(newDelegate);
-
-        if (Debug.DEBUG) {
-            System.out.println("New " + mClass.getSimpleName() + " with int " + native_object);
-        }
-
-        return native_object;
-    }
-
-    /**
-     * Removes the main reference on the given delegate.
-     * @param native_object the native integer representing the delegate.
-     */
-    public void removeJavaReferenceFor(int native_object) {
-        T delegate = getDelegate(native_object);
-
-        if (Debug.DEBUG) {
-            System.out.println("Removing main Java ref on " + mClass.getSimpleName() +
-                    " with int " + native_object);
-        }
-
-        mJavaReferences.remove(delegate);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
deleted file mode 100644
index 108b651..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
+++ /dev/null
@@ -1,396 +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 com.android.layoutlib.bridge.impl;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import android.graphics.Typeface;
-
-import java.awt.Font;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Provides {@link Font} object to the layout lib.
- * <p/>
- * The fonts are loaded from the SDK directory. Family/style mapping is done by parsing the
- * fonts.xml file located alongside the ttf files.
- */
-public final class FontLoader {
-    private static final String FONTS_SYSTEM = "system_fonts.xml";
-    private static final String FONTS_VENDOR = "vendor_fonts.xml";
-    private static final String FONTS_FALLBACK = "fallback_fonts.xml";
-
-    private static final String NODE_FAMILYSET = "familyset";
-    private static final String NODE_FAMILY = "family";
-    private static final String NODE_NAME = "name";
-    private static final String NODE_FILE = "file";
-
-    private static final String ATTRIBUTE_VARIANT = "variant";
-    private static final String ATTRIBUTE_VALUE_ELEGANT = "elegant";
-    private static final String FONT_SUFFIX_NONE = ".ttf";
-    private static final String FONT_SUFFIX_REGULAR = "-Regular.ttf";
-    private static final String FONT_SUFFIX_BOLD = "-Bold.ttf";
-    private static final String FONT_SUFFIX_ITALIC = "-Italic.ttf";
-    private static final String FONT_SUFFIX_BOLDITALIC = "-BoldItalic.ttf";
-
-    // This must match the values of Typeface styles so that we can use them for indices in this
-    // array.
-    private static final int[] AWT_STYLES = new int[] {
-        Font.PLAIN,
-        Font.BOLD,
-        Font.ITALIC,
-        Font.BOLD | Font.ITALIC
-    };
-    private static int[] DERIVE_BOLD_ITALIC = new int[] {
-        Typeface.ITALIC, Typeface.BOLD, Typeface.NORMAL
-    };
-    private static int[] DERIVE_ITALIC = new int[] { Typeface.NORMAL };
-    private static int[] DERIVE_BOLD = new int[] { Typeface.NORMAL };
-
-    private static final List<FontInfo> mMainFonts = new ArrayList<FontInfo>();
-    private static final List<FontInfo> mFallbackFonts = new ArrayList<FontInfo>();
-
-    private final String mOsFontsLocation;
-
-    public static FontLoader create(String fontOsLocation) {
-        try {
-            SAXParserFactory parserFactory = SAXParserFactory.newInstance();
-                parserFactory.setNamespaceAware(true);
-
-            // parse the system fonts
-            FontHandler handler = parseFontFile(parserFactory, fontOsLocation, FONTS_SYSTEM);
-            List<FontInfo> systemFonts = handler.getFontList();
-
-
-            // parse the fallback fonts
-            handler = parseFontFile(parserFactory, fontOsLocation, FONTS_FALLBACK);
-            List<FontInfo> fallbackFonts = handler.getFontList();
-
-            return new FontLoader(fontOsLocation, systemFonts, fallbackFonts);
-        } catch (ParserConfigurationException e) {
-            // return null below
-        } catch (SAXException e) {
-            // return null below
-        } catch (FileNotFoundException e) {
-            // return null below
-        } catch (IOException e) {
-            // return null below
-        }
-
-        return null;
-    }
-
-    private static FontHandler parseFontFile(SAXParserFactory parserFactory,
-            String fontOsLocation, String fontFileName)
-            throws ParserConfigurationException, SAXException, IOException, FileNotFoundException {
-
-        SAXParser parser = parserFactory.newSAXParser();
-        File f = new File(fontOsLocation, fontFileName);
-
-        FontHandler definitionParser = new FontHandler(
-                fontOsLocation + File.separator);
-        parser.parse(new FileInputStream(f), definitionParser);
-        return definitionParser;
-    }
-
-    private FontLoader(String fontOsLocation,
-            List<FontInfo> fontList, List<FontInfo> fallBackList) {
-        mOsFontsLocation = fontOsLocation;
-        mMainFonts.addAll(fontList);
-        mFallbackFonts.addAll(fallBackList);
-    }
-
-
-    public String getOsFontsLocation() {
-        return mOsFontsLocation;
-    }
-
-    /**
-     * Returns a {@link Font} object given a family name and a style value (constant in
-     * {@link Typeface}).
-     * @param family the family name
-     * @param style a 1-item array containing the requested style. Based on the font being read
-     *              the actual style may be different. The array contains the actual style after
-     *              the method returns.
-     * @return the font object or null if no match could be found.
-     */
-    public synchronized List<Font> getFont(String family, int style) {
-        List<Font> result = new ArrayList<Font>();
-
-        if (family == null) {
-            return result;
-        }
-
-
-        // get the font objects from the main list based on family.
-        for (FontInfo info : mMainFonts) {
-            if (info.families.contains(family)) {
-                result.add(info.font[style]);
-                break;
-            }
-        }
-
-        // add all the fallback fonts for the given style
-        for (FontInfo info : mFallbackFonts) {
-            result.add(info.font[style]);
-        }
-
-        return result;
-    }
-
-
-    public synchronized List<Font> getFallbackFonts(int style) {
-        List<Font> result = new ArrayList<Font>();
-        // add all the fallback fonts
-        for (FontInfo info : mFallbackFonts) {
-            result.add(info.font[style]);
-        }
-        return result;
-    }
-
-
-    private final static class FontInfo {
-        final Font[] font = new Font[4]; // Matches the 4 type-face styles.
-        final Set<String> families;
-
-        FontInfo() {
-            families = new HashSet<String>();
-        }
-    }
-
-    private final static class FontHandler extends DefaultHandler {
-        private final String mOsFontsLocation;
-
-        private FontInfo mFontInfo = null;
-        private final StringBuilder mBuilder = new StringBuilder();
-        private List<FontInfo> mFontList = new ArrayList<FontInfo>();
-        private boolean isCompactFont = true;
-
-        private FontHandler(String osFontsLocation) {
-            super();
-            mOsFontsLocation = osFontsLocation;
-        }
-
-        public List<FontInfo> getFontList() {
-            return mFontList;
-        }
-
-        /* (non-Javadoc)
-         * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
-         */
-        @Override
-        public void startElement(String uri, String localName, String name, Attributes attributes)
-                throws SAXException {
-            if (NODE_FAMILYSET.equals(localName)) {
-                mFontList = new ArrayList<FontInfo>();
-            } else if (NODE_FAMILY.equals(localName)) {
-                if (mFontList != null) {
-                    mFontInfo = null;
-                }
-            } else if (NODE_NAME.equals(localName)) {
-                if (mFontList != null && mFontInfo == null) {
-                    mFontInfo = new FontInfo();
-                }
-            } else if (NODE_FILE.equals(localName)) {
-                if (mFontList != null && mFontInfo == null) {
-                    mFontInfo = new FontInfo();
-                }
-                if (ATTRIBUTE_VALUE_ELEGANT.equals(attributes.getValue(ATTRIBUTE_VARIANT))) {
-                    isCompactFont = false;
-                } else {
-                    isCompactFont = true;
-                }
-            }
-
-            mBuilder.setLength(0);
-
-            super.startElement(uri, localName, name, attributes);
-        }
-
-        /* (non-Javadoc)
-         * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
-         */
-        @Override
-        public void characters(char[] ch, int start, int length) throws SAXException {
-            if (isCompactFont) {
-              mBuilder.append(ch, start, length);
-            }
-        }
-
-        /* (non-Javadoc)
-         * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
-         */
-        @Override
-        public void endElement(String uri, String localName, String name) throws SAXException {
-            if (NODE_FAMILY.equals(localName)) {
-                if (mFontInfo != null) {
-                    // if has a normal font file, add to the list
-                    if (mFontInfo.font[Typeface.NORMAL] != null) {
-                        mFontList.add(mFontInfo);
-
-                        // create missing font styles, order is important.
-                        if (mFontInfo.font[Typeface.BOLD_ITALIC] == null) {
-                            computeDerivedFont(Typeface.BOLD_ITALIC, DERIVE_BOLD_ITALIC);
-                        }
-                        if (mFontInfo.font[Typeface.ITALIC] == null) {
-                            computeDerivedFont(Typeface.ITALIC, DERIVE_ITALIC);
-                        }
-                        if (mFontInfo.font[Typeface.BOLD] == null) {
-                            computeDerivedFont(Typeface.BOLD, DERIVE_BOLD);
-                        }
-                    }
-
-                    mFontInfo = null;
-                }
-            } else if (NODE_NAME.equals(localName)) {
-                // handle a new name for an existing Font Info
-                if (mFontInfo != null) {
-                    String family = trimXmlWhitespaces(mBuilder.toString());
-                    mFontInfo.families.add(family);
-                }
-            } else if (NODE_FILE.equals(localName)) {
-                // handle a new file for an existing Font Info
-                if (isCompactFont && mFontInfo != null) {
-                    String fileName = trimXmlWhitespaces(mBuilder.toString());
-                    Font font = getFont(fileName);
-                    if (font != null) {
-                        if (fileName.endsWith(FONT_SUFFIX_REGULAR)) {
-                            mFontInfo.font[Typeface.NORMAL] = font;
-                        } else if (fileName.endsWith(FONT_SUFFIX_BOLD)) {
-                            mFontInfo.font[Typeface.BOLD] = font;
-                        } else if (fileName.endsWith(FONT_SUFFIX_ITALIC)) {
-                            mFontInfo.font[Typeface.ITALIC] = font;
-                        } else if (fileName.endsWith(FONT_SUFFIX_BOLDITALIC)) {
-                            mFontInfo.font[Typeface.BOLD_ITALIC] = font;
-                        } else if (fileName.endsWith(FONT_SUFFIX_NONE)) {
-                            mFontInfo.font[Typeface.NORMAL] = font;
-                        }
-                    }
-                }
-            }
-        }
-
-        private Font getFont(String fileName) {
-            try {
-                File file = new File(mOsFontsLocation, fileName);
-                if (file.exists()) {
-                    return Font.createFont(Font.TRUETYPE_FONT, file);
-                }
-            } catch (Exception e) {
-
-            }
-
-            return null;
-        }
-
-        private void computeDerivedFont( int toCompute, int[] basedOnList) {
-            for (int basedOn : basedOnList) {
-                if (mFontInfo.font[basedOn] != null) {
-                    mFontInfo.font[toCompute] =
-                        mFontInfo.font[basedOn].deriveFont(AWT_STYLES[toCompute]);
-                    return;
-                }
-            }
-
-            // we really shouldn't stop there. This means we don't have a NORMAL font...
-            assert false;
-        }
-
-        private String trimXmlWhitespaces(String value) {
-            if (value == null) {
-                return null;
-            }
-
-            // look for carriage return and replace all whitespace around it by just 1 space.
-            int index;
-
-            while ((index = value.indexOf('\n')) != -1) {
-                // look for whitespace on each side
-                int left = index - 1;
-                while (left >= 0) {
-                    if (Character.isWhitespace(value.charAt(left))) {
-                        left--;
-                    } else {
-                        break;
-                    }
-                }
-
-                int right = index + 1;
-                int count = value.length();
-                while (right < count) {
-                    if (Character.isWhitespace(value.charAt(right))) {
-                        right++;
-                    } else {
-                        break;
-                    }
-                }
-
-                // remove all between left and right (non inclusive) and replace by a single space.
-                String leftString = null;
-                if (left >= 0) {
-                    leftString = value.substring(0, left + 1);
-                }
-                String rightString = null;
-                if (right < count) {
-                    rightString = value.substring(right);
-                }
-
-                if (leftString != null) {
-                    value = leftString;
-                    if (rightString != null) {
-                        value += " " + rightString;
-                    }
-                } else {
-                    value = rightString != null ? rightString : "";
-                }
-            }
-
-            // now we un-escape the string
-            int length = value.length();
-            char[] buffer = value.toCharArray();
-
-            for (int i = 0 ; i < length ; i++) {
-                if (buffer[i] == '\\') {
-                    if (buffer[i+1] == 'n') {
-                        // replace the char with \n
-                        buffer[i+1] = '\n';
-                    }
-
-                    // offset the rest of the buffer since we go from 2 to 1 char
-                    System.arraycopy(buffer, i+1, buffer, i, length - i - 1);
-                    length--;
-                }
-            }
-
-            return new String(buffer, 0, length);
-        }
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
deleted file mode 100644
index 21d6b1a..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
+++ /dev/null
@@ -1,803 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Paint_Delegate;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.graphics.Region_Delegate;
-import android.graphics.Shader_Delegate;
-import android.graphics.Xfermode_Delegate;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Area;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-
-/**
- * Class representing a graphics context snapshot, as well as a context stack as a linked list.
- * <p>
- * This is based on top of {@link Graphics2D} but can operate independently if none are available
- * yet when setting transforms and clip information.
- * <p>
- * This allows for drawing through {@link #draw(Drawable, Paint_Delegate)} and
- * {@link #draw(Drawable, Paint_Delegate)}
- *
- * Handling of layers (created with {@link Canvas#saveLayer(RectF, Paint, int)}) is handled through
- * a list of Graphics2D for each layers. The class actually maintains a list of {@link Layer}
- * for each layer. Doing a save() will duplicate this list so that each graphics2D object
- * ({@link Layer#getGraphics()}) is configured only for the new snapshot.
- */
-public class GcSnapshot {
-
-    private final GcSnapshot mPrevious;
-    private final int mFlags;
-
-    /** list of layers. The first item in the list is always the  */
-    private final ArrayList<Layer> mLayers = new ArrayList<Layer>();
-
-    /** temp transform in case transformation are set before a Graphics2D exists */
-    private AffineTransform mTransform = null;
-    /** temp clip in case clipping is set before a Graphics2D exists */
-    private Area mClip = null;
-
-    // local layer data
-    /** a local layer created with {@link Canvas#saveLayer(RectF, Paint, int)}.
-     * If this is null, this does not mean there's no layer, just that the snapshot is not the
-     * one that created the layer.
-     * @see #getLayerSnapshot()
-     */
-    private final Layer mLocalLayer;
-    private final Paint_Delegate mLocalLayerPaint;
-    private final Rect mLayerBounds;
-
-    public interface Drawable {
-        void draw(Graphics2D graphics, Paint_Delegate paint);
-    }
-
-    /**
-     * Class containing information about a layer.
-     *
-     * This contains graphics, bitmap and layer information.
-     */
-    private static class Layer {
-        private final Graphics2D mGraphics;
-        private final Bitmap_Delegate mBitmap;
-        private final BufferedImage mImage;
-        /** the flags that were used to configure the layer. This is never changed, and passed
-         * as is when {@link #makeCopy()} is called */
-        private final int mFlags;
-        /** the original content of the layer when the next object was created. This is not
-         * passed in {@link #makeCopy()} and instead is recreated when a new layer is added
-         * (depending on its flags) */
-        private BufferedImage mOriginalCopy;
-
-        /**
-         * Creates a layer with a graphics and a bitmap. This is only used to create
-         * the base layer.
-         *
-         * @param graphics the graphics
-         * @param bitmap the bitmap
-         */
-        Layer(Graphics2D graphics, Bitmap_Delegate bitmap) {
-            mGraphics = graphics;
-            mBitmap = bitmap;
-            mImage = mBitmap.getImage();
-            mFlags = 0;
-        }
-
-        /**
-         * Creates a layer with a graphics and an image. If the image belongs to a
-         * {@link Bitmap_Delegate} (case of the base layer), then
-         * {@link Layer#Layer(Graphics2D, Bitmap_Delegate)} should be used.
-         *
-         * @param graphics the graphics the new graphics for this layer
-         * @param image the image the image from which the graphics came
-         * @param flags the flags that were used to save this layer
-         */
-        Layer(Graphics2D graphics, BufferedImage image, int flags) {
-            mGraphics = graphics;
-            mBitmap = null;
-            mImage = image;
-            mFlags = flags;
-        }
-
-        /** The Graphics2D, guaranteed to be non null */
-        Graphics2D getGraphics() {
-            return mGraphics;
-        }
-
-        /** The BufferedImage, guaranteed to be non null */
-        BufferedImage getImage() {
-            return mImage;
-        }
-
-        /** Returns the layer save flags. This is only valid for additional layers.
-         * For the base layer this will always return 0;
-         * For a given layer, all further copies of this {@link Layer} object in new snapshots
-         * will always return the same value.
-         */
-        int getFlags() {
-            return mFlags;
-        }
-
-        Layer makeCopy() {
-            if (mBitmap != null) {
-                return new Layer((Graphics2D) mGraphics.create(), mBitmap);
-            }
-
-            return new Layer((Graphics2D) mGraphics.create(), mImage, mFlags);
-        }
-
-        /** sets an optional copy of the original content to be used during restore */
-        void setOriginalCopy(BufferedImage image) {
-            mOriginalCopy = image;
-        }
-
-        BufferedImage getOriginalCopy() {
-            return mOriginalCopy;
-        }
-
-        void change() {
-            if (mBitmap != null) {
-                mBitmap.change();
-            }
-        }
-
-        /**
-         * Sets the clip for the graphics2D object associated with the layer.
-         * This should be used over the normal Graphics2D setClip method.
-         *
-         * @param clipShape the shape to use a the clip shape.
-         */
-        void setClip(Shape clipShape) {
-            // because setClip is only guaranteed to work with rectangle shape,
-            // first reset the clip to max and then intersect the current (empty)
-            // clip with the shap.
-            mGraphics.setClip(null);
-            mGraphics.clip(clipShape);
-        }
-
-        /**
-         * Clips the layer with the given shape. This performs an intersect between the current
-         * clip shape and the given shape.
-         * @param shape the new clip shape.
-         */
-        public void clip(Shape shape) {
-            mGraphics.clip(shape);
-        }
-    }
-
-    /**
-     * Creates the root snapshot associating it with a given bitmap.
-     * <p>
-     * If <var>bitmap</var> is null, then {@link GcSnapshot#setBitmap(Bitmap_Delegate)} must be
-     * called before the snapshot can be used to draw. Transform and clip operations are permitted
-     * before.
-     *
-     * @param image the image to associate to the snapshot or null.
-     * @return the root snapshot
-     */
-    public static GcSnapshot createDefaultSnapshot(Bitmap_Delegate bitmap) {
-        GcSnapshot snapshot = new GcSnapshot();
-        if (bitmap != null) {
-            snapshot.setBitmap(bitmap);
-        }
-
-        return snapshot;
-    }
-
-    /**
-     * Saves the current state according to the given flags and returns the new current snapshot.
-     * <p/>
-     * This is the equivalent of {@link Canvas#save(int)}
-     *
-     * @param flags the save flags.
-     * @return the new snapshot
-     *
-     * @see Canvas#save(int)
-     */
-    public GcSnapshot save(int flags) {
-        return new GcSnapshot(this, null /*layerbounds*/, null /*paint*/, flags);
-    }
-
-    /**
-     * Saves the current state and creates a new layer, and returns the new current snapshot.
-     * <p/>
-     * This is the equivalent of {@link Canvas#saveLayer(RectF, Paint, int)}
-     *
-     * @param layerBounds the layer bounds
-     * @param paint the Paint information used to blit the layer back into the layers underneath
-     *          upon restore
-     * @param flags the save flags.
-     * @return the new snapshot
-     *
-     * @see Canvas#saveLayer(RectF, Paint, int)
-     */
-    public GcSnapshot saveLayer(RectF layerBounds, Paint_Delegate paint, int flags) {
-        return new GcSnapshot(this, layerBounds, paint, flags);
-    }
-
-    /**
-     * Creates the root snapshot.
-     * {@link #setGraphics2D(Graphics2D)} will have to be called on it when possible.
-     */
-    private GcSnapshot() {
-        mPrevious = null;
-        mFlags = 0;
-        mLocalLayer = null;
-        mLocalLayerPaint = null;
-        mLayerBounds = null;
-    }
-
-    /**
-     * Creates a new {@link GcSnapshot} on top of another one, with a layer data to be restored
-     * into the main graphics when {@link #restore()} is called.
-     *
-     * @param previous the previous snapshot head.
-     * @param layerBounds the region of the layer. Optional, if null, this is a normal save()
-     * @param paint the Paint information used to blit the layer back into the layers underneath
-     *          upon restore
-     * @param flags the flags regarding what should be saved.
-     */
-    private GcSnapshot(GcSnapshot previous, RectF layerBounds, Paint_Delegate paint, int flags) {
-        assert previous != null;
-        mPrevious = previous;
-        mFlags = flags;
-
-        // make a copy of the current layers before adding the new one.
-        // This keeps the same BufferedImage reference but creates new Graphics2D for this
-        // snapshot.
-        // It does not copy whatever original copy the layers have, as they will be done
-        // only if the new layer doesn't clip drawing to itself.
-        for (Layer layer : mPrevious.mLayers) {
-            mLayers.add(layer.makeCopy());
-        }
-
-        if (layerBounds != null) {
-            // get the current transform
-            AffineTransform matrix = mLayers.get(0).getGraphics().getTransform();
-
-            // transform the layerBounds with the current transform and stores it into a int rect
-            RectF rect2 = new RectF();
-            mapRect(matrix, rect2, layerBounds);
-            mLayerBounds = new Rect();
-            rect2.round(mLayerBounds);
-
-            // get the base layer (always at index 0)
-            Layer baseLayer = mLayers.get(0);
-
-            // create the image for the layer
-            BufferedImage layerImage = new BufferedImage(
-                    baseLayer.getImage().getWidth(),
-                    baseLayer.getImage().getHeight(),
-                    (mFlags & Canvas.HAS_ALPHA_LAYER_SAVE_FLAG) != 0 ?
-                            BufferedImage.TYPE_INT_ARGB :
-                                BufferedImage.TYPE_INT_RGB);
-
-            // create a graphics for it so that drawing can be done.
-            Graphics2D layerGraphics = layerImage.createGraphics();
-
-            // because this layer inherits the current context for transform and clip,
-            // set them to one from the base layer.
-            AffineTransform currentMtx = baseLayer.getGraphics().getTransform();
-            layerGraphics.setTransform(currentMtx);
-
-            // create a new layer for this new layer and add it to the list at the end.
-            mLayers.add(mLocalLayer = new Layer(layerGraphics, layerImage, flags));
-
-            // set the clip on it.
-            Shape currentClip = baseLayer.getGraphics().getClip();
-            mLocalLayer.setClip(currentClip);
-
-            // if the drawing is not clipped to the local layer only, we save the current content
-            // of all other layers. We are only interested in the part that will actually
-            // be drawn, so we create as small bitmaps as we can.
-            // This is so that we can erase the drawing that goes in the layers below that will
-            // be coming from the layer itself.
-            if ((mFlags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0) {
-                int w = mLayerBounds.width();
-                int h = mLayerBounds.height();
-                for (int i = 0 ; i < mLayers.size() - 1 ; i++) {
-                    Layer layer = mLayers.get(i);
-                    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
-                    Graphics2D graphics = image.createGraphics();
-                    graphics.drawImage(layer.getImage(),
-                            0, 0, w, h,
-                            mLayerBounds.left, mLayerBounds.top,
-                                    mLayerBounds.right, mLayerBounds.bottom,
-                            null);
-                    graphics.dispose();
-                    layer.setOriginalCopy(image);
-                }
-            }
-        } else {
-            mLocalLayer = null;
-            mLayerBounds = null;
-        }
-
-        mLocalLayerPaint  = paint;
-    }
-
-    public void dispose() {
-        for (Layer layer : mLayers) {
-            layer.getGraphics().dispose();
-        }
-
-        if (mPrevious != null) {
-            mPrevious.dispose();
-        }
-    }
-
-    /**
-     * Restores the top {@link GcSnapshot}, and returns the next one.
-     */
-    public GcSnapshot restore() {
-        return doRestore();
-    }
-
-    /**
-     * Restores the {@link GcSnapshot} to <var>saveCount</var>.
-     * @param saveCount the saveCount or -1 to only restore 1.
-     *
-     * @return the new head of the Gc snapshot stack.
-     */
-    public GcSnapshot restoreTo(int saveCount) {
-        return doRestoreTo(size(), saveCount);
-    }
-
-    public int size() {
-        if (mPrevious != null) {
-            return mPrevious.size() + 1;
-        }
-
-        return 1;
-    }
-
-    /**
-     * Link the snapshot to a Bitmap_Delegate.
-     * <p/>
-     * This is only for the case where the snapshot was created with a null image when calling
-     * {@link #createDefaultSnapshot(Bitmap_Delegate)}, and is therefore not yet linked to
-     * a previous snapshot.
-     * <p/>
-     * If any transform or clip information was set before, they are put into the Graphics object.
-     * @param bitmap the bitmap to link to.
-     */
-    public void setBitmap(Bitmap_Delegate bitmap) {
-        // create a new Layer for the bitmap. This will be the base layer.
-        Graphics2D graphics2D = bitmap.getImage().createGraphics();
-        Layer baseLayer = new Layer(graphics2D, bitmap);
-
-        // Set the current transform and clip which can either come from mTransform/mClip if they
-        // were set when there was no bitmap/layers or from the current base layers if there is
-        // one already.
-
-        graphics2D.setTransform(getTransform());
-        // reset mTransform in case there was one.
-        mTransform = null;
-
-        baseLayer.setClip(getClip());
-        // reset mClip in case there was one.
-        mClip = null;
-
-        // replace whatever current layers we have with this.
-        mLayers.clear();
-        mLayers.add(baseLayer);
-
-    }
-
-    public void translate(float dx, float dy) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().translate(dx, dy);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.translate(dx, dy);
-        }
-    }
-
-    public void rotate(double radians) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().rotate(radians);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.rotate(radians);
-        }
-    }
-
-    public void scale(float sx, float sy) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().scale(sx, sy);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.scale(sx, sy);
-        }
-    }
-
-    public AffineTransform getTransform() {
-        if (mLayers.size() > 0) {
-            // all graphics2D in the list have the same transform
-            return mLayers.get(0).getGraphics().getTransform();
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            return mTransform;
-        }
-    }
-
-    public void setTransform(AffineTransform transform) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().setTransform(transform);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.setTransform(transform);
-        }
-    }
-
-    public boolean clip(Shape shape, int regionOp) {
-        // Simple case of intersect with existing layers.
-        // Because Graphics2D#setClip works a bit peculiarly, we optimize
-        // the case of clipping by intersection, as it's supported natively.
-        if (regionOp == Region.Op.INTERSECT.nativeInt && mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.clip(shape);
-            }
-
-            Shape currentClip = getClip();
-            return currentClip != null && currentClip.getBounds().isEmpty() == false;
-        }
-
-        Area area = null;
-
-        if (regionOp == Region.Op.REPLACE.nativeInt) {
-            area = new Area(shape);
-        } else {
-            area = Region_Delegate.combineShapes(getClip(), shape, regionOp);
-        }
-
-        assert area != null;
-
-        if (mLayers.size() > 0) {
-            if (area != null) {
-                for (Layer layer : mLayers) {
-                    layer.setClip(area);
-                }
-            }
-
-            Shape currentClip = getClip();
-            return currentClip != null && currentClip.getBounds().isEmpty() == false;
-        } else {
-            if (area != null) {
-                mClip = area;
-            } else {
-                mClip = new Area();
-            }
-
-            return mClip.getBounds().isEmpty() == false;
-        }
-    }
-
-    public boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
-        return clip(new Rectangle2D.Float(left, top, right - left, bottom - top), regionOp);
-    }
-
-    /**
-     * Returns the current clip, or null if none have been setup.
-     */
-    public Shape getClip() {
-        if (mLayers.size() > 0) {
-            // they all have the same clip
-            return mLayers.get(0).getGraphics().getClip();
-        } else {
-            return mClip;
-        }
-    }
-
-    private GcSnapshot doRestoreTo(int size, int saveCount) {
-        if (size <= saveCount) {
-            return this;
-        }
-
-        // restore the current one first.
-        GcSnapshot previous = doRestore();
-
-        if (size == saveCount + 1) { // this was the only one that needed restore.
-            return previous;
-        } else {
-            return previous.doRestoreTo(size - 1, saveCount);
-        }
-    }
-
-    /**
-     * Executes the Drawable's draw method, with a null paint delegate.
-     * <p/>
-     * Note that the method can be called several times if there are more than one active layer.
-     * @param drawable
-     */
-    public void draw(Drawable drawable) {
-        draw(drawable, null, false /*compositeOnly*/, false /*forceSrcMode*/);
-    }
-
-    /**
-     * Executes the Drawable's draw method.
-     * <p/>
-     * Note that the method can be called several times if there are more than one active layer.
-     * @param drawable
-     * @param paint
-     * @param compositeOnly whether the paint is used for composite only. This is typically
-     *          the case for bitmaps.
-     * @param forceSrcMode if true, this overrides the composite to be SRC
-     */
-    public void draw(Drawable drawable, Paint_Delegate paint, boolean compositeOnly,
-            boolean forceSrcMode) {
-        // the current snapshot may not have a mLocalLayer (ie it was created on save() instead
-        // of saveLayer(), but that doesn't mean there's no layer.
-        // mLayers however saves all the information we need (flags).
-        if (mLayers.size() == 1) {
-            // no layer, only base layer. easy case.
-            drawInLayer(mLayers.get(0), drawable, paint, compositeOnly, forceSrcMode);
-        } else {
-            // draw in all the layers until the layer save flags tells us to stop (ie drawing
-            // in that layer is limited to the layer itself.
-            int flags;
-            int i = mLayers.size() - 1;
-
-            do {
-                Layer layer = mLayers.get(i);
-
-                drawInLayer(layer, drawable, paint, compositeOnly, forceSrcMode);
-
-                // then go to previous layer, only if there are any left, and its flags
-                // doesn't restrict drawing to the layer itself.
-                i--;
-                flags = layer.getFlags();
-            } while (i >= 0 && (flags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0);
-        }
-    }
-
-    private void drawInLayer(Layer layer, Drawable drawable, Paint_Delegate paint,
-            boolean compositeOnly, boolean forceSrcMode) {
-        Graphics2D originalGraphics = layer.getGraphics();
-        // get a Graphics2D object configured with the drawing parameters.
-        Graphics2D configuredGraphics2D =
-            paint != null ?
-                    createCustomGraphics(originalGraphics, paint, compositeOnly, forceSrcMode) :
-                        (Graphics2D) originalGraphics.create();
-
-        try {
-            drawable.draw(configuredGraphics2D, paint);
-            layer.change();
-        } finally {
-            // dispose Graphics2D object
-            configuredGraphics2D.dispose();
-        }
-    }
-
-    private GcSnapshot doRestore() {
-        if (mPrevious != null) {
-            if (mLocalLayer != null) {
-                // prepare to blit the layers in which we have draw, in the layer beneath
-                // them, starting with the top one (which is the current local layer).
-                int i = mLayers.size() - 1;
-                int flags;
-                do {
-                    Layer dstLayer = mLayers.get(i - 1);
-
-                    restoreLayer(dstLayer);
-
-                    flags = dstLayer.getFlags();
-                    i--;
-                } while (i > 0 && (flags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0);
-            }
-
-            // if this snapshot does not save everything, then set the previous snapshot
-            // to this snapshot content
-
-            // didn't save the matrix? set the current matrix on the previous snapshot
-            if ((mFlags & Canvas.MATRIX_SAVE_FLAG) == 0) {
-                AffineTransform mtx = getTransform();
-                for (Layer layer : mPrevious.mLayers) {
-                    layer.getGraphics().setTransform(mtx);
-                }
-            }
-
-            // didn't save the clip? set the current clip on the previous snapshot
-            if ((mFlags & Canvas.CLIP_SAVE_FLAG) == 0) {
-                Shape clip = getClip();
-                for (Layer layer : mPrevious.mLayers) {
-                    layer.setClip(clip);
-                }
-            }
-        }
-
-        for (Layer layer : mLayers) {
-            layer.getGraphics().dispose();
-        }
-
-        return mPrevious;
-    }
-
-    private void restoreLayer(Layer dstLayer) {
-
-        Graphics2D baseGfx = dstLayer.getImage().createGraphics();
-
-        // if the layer contains an original copy this means the flags
-        // didn't restrict drawing to the local layer and we need to make sure the
-        // layer bounds in the layer beneath didn't receive any drawing.
-        // so we use the originalCopy to erase the new drawings in there.
-        BufferedImage originalCopy = dstLayer.getOriginalCopy();
-        if (originalCopy != null) {
-            Graphics2D g = (Graphics2D) baseGfx.create();
-            g.setComposite(AlphaComposite.Src);
-
-            g.drawImage(originalCopy,
-                    mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
-                    0, 0, mLayerBounds.width(), mLayerBounds.height(),
-                    null);
-            g.dispose();
-        }
-
-        // now draw put the content of the local layer onto the layer,
-        // using the paint information
-        Graphics2D g = createCustomGraphics(baseGfx, mLocalLayerPaint,
-                true /*alphaOnly*/, false /*forceSrcMode*/);
-
-        g.drawImage(mLocalLayer.getImage(),
-                mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
-                mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
-                null);
-        g.dispose();
-
-        baseGfx.dispose();
-    }
-
-    /**
-     * Creates a new {@link Graphics2D} based on the {@link Paint} parameters.
-     * <p/>The object must be disposed ({@link Graphics2D#dispose()}) after being used.
-     */
-    private Graphics2D createCustomGraphics(Graphics2D original, Paint_Delegate paint,
-            boolean compositeOnly, boolean forceSrcMode) {
-        // make new one graphics
-        Graphics2D g = (Graphics2D) original.create();
-
-        // configure it
-
-        if (paint.isAntiAliased()) {
-            g.setRenderingHint(
-                    RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-            g.setRenderingHint(
-                    RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-        }
-
-        boolean customShader = false;
-
-        // get the shader first, as it'll replace the color if it can be used it.
-        if (compositeOnly == false) {
-            Shader_Delegate shaderDelegate = paint.getShader();
-            if (shaderDelegate != null) {
-                if (shaderDelegate.isSupported()) {
-                    java.awt.Paint shaderPaint = shaderDelegate.getJavaPaint();
-                    assert shaderPaint != null;
-                    if (shaderPaint != null) {
-                        g.setPaint(shaderPaint);
-                        customShader = true;
-                    }
-                } else {
-                    Bridge.getLog().fidelityWarning(LayoutLog.TAG_SHADER,
-                            shaderDelegate.getSupportMessage(),
-                            null /*throwable*/, null /*data*/);
-                }
-            }
-
-            // if no shader, use the paint color
-            if (customShader == false) {
-                g.setColor(new Color(paint.getColor(), true /*hasAlpha*/));
-            }
-
-            // set the stroke
-            g.setStroke(paint.getJavaStroke());
-        }
-
-        // the alpha for the composite. Always opaque if the normal paint color is used since
-        // it contains the alpha
-        int alpha = (compositeOnly || customShader) ? paint.getAlpha() : 0xFF;
-
-        if (forceSrcMode) {
-            g.setComposite(AlphaComposite.getInstance(
-                    AlphaComposite.SRC, (float) alpha / 255.f));
-        } else {
-            boolean customXfermode = false;
-            Xfermode_Delegate xfermodeDelegate = paint.getXfermode();
-            if (xfermodeDelegate != null) {
-                if (xfermodeDelegate.isSupported()) {
-                    Composite composite = xfermodeDelegate.getComposite(alpha);
-                    assert composite != null;
-                    if (composite != null) {
-                        g.setComposite(composite);
-                        customXfermode = true;
-                    }
-                } else {
-                    Bridge.getLog().fidelityWarning(LayoutLog.TAG_XFERMODE,
-                            xfermodeDelegate.getSupportMessage(),
-                            null /*throwable*/, null /*data*/);
-                }
-            }
-
-            // if there was no custom xfermode, but we have alpha (due to a shader and a non
-            // opaque alpha channel in the paint color), then we create an AlphaComposite anyway
-            // that will handle the alpha.
-            if (customXfermode == false && alpha != 0xFF) {
-                g.setComposite(AlphaComposite.getInstance(
-                        AlphaComposite.SRC_OVER, (float) alpha / 255.f));
-            }
-        }
-
-        return g;
-    }
-
-    private void mapRect(AffineTransform matrix, RectF dst, RectF src) {
-        // array with 4 corners
-        float[] corners = new float[] {
-                src.left, src.top,
-                src.right, src.top,
-                src.right, src.bottom,
-                src.left, src.bottom,
-        };
-
-        // apply the transform to them.
-        matrix.transform(corners, 0, corners, 0, 4);
-
-        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
-        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
-        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));
-
-        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
-        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
deleted file mode 100644
index 803849f..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
+++ /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.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A factory for {@link XmlPullParser}.
- *
- */
-public class ParserFactory {
-
-    private final static String ENCODING = "UTF-8"; //$NON-NLS-1$
-
-    public final static boolean LOG_PARSER = false;
-
-    public static XmlPullParser create(File f)
-            throws XmlPullParserException, FileNotFoundException {
-        InputStream stream = new FileInputStream(f);
-        return create(stream, f.getName(), f.length());
-    }
-
-    public static XmlPullParser create(InputStream stream, String name)
-        throws XmlPullParserException {
-        return create(stream, name, -1);
-    }
-
-    private static XmlPullParser create(InputStream stream, String name, long size)
-            throws XmlPullParserException {
-        KXmlParser parser = instantiateParser(name);
-
-        stream = readAndClose(stream, name, size);
-
-        parser.setInput(stream, ENCODING);
-        return parser;
-    }
-
-    private static KXmlParser instantiateParser(String name) throws XmlPullParserException {
-        KXmlParser parser;
-        if (name != null) {
-            parser = new CustomParser(name);
-        } else {
-            parser = new KXmlParser();
-        }
-        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-        return parser;
-    }
-
-    private static InputStream readAndClose(InputStream stream, String name, long size)
-            throws XmlPullParserException {
-        // just a sanity check. It's doubtful we'll have such big files!
-        if (size > Integer.MAX_VALUE) {
-            throw new XmlPullParserException("File " + name + " is too big to be parsed");
-        }
-        int intSize = (int) size;
-
-        // create a buffered reader to facilitate reading.
-        BufferedInputStream bufferedStream = new BufferedInputStream(stream);
-        try {
-            int avail;
-            if (intSize != -1) {
-                avail = intSize;
-            } else {
-                // get the size to read.
-                avail = bufferedStream.available();
-            }
-
-            // create the initial buffer and read it.
-            byte[] buffer = new byte[avail];
-            int read = stream.read(buffer);
-
-            // this is the easy case.
-            if (read == intSize) {
-                return new ByteArrayInputStream(buffer);
-            }
-
-            // check if there is more to read (read() does not necessarily read all that
-            // available() returned!)
-            while ((avail = bufferedStream.available()) > 0) {
-                if (read + avail > buffer.length) {
-                    // just allocate what is needed. We're mostly reading small files
-                    // so it shouldn't be too problematic.
-                    byte[] moreBuffer = new byte[read + avail];
-                    System.arraycopy(buffer, 0, moreBuffer, 0, read);
-                    buffer = moreBuffer;
-                }
-
-                read += stream.read(buffer, read, avail);
-            }
-
-            // return a new stream encapsulating this buffer.
-            return new ByteArrayInputStream(buffer);
-
-        } catch (IOException e) {
-            throw new XmlPullParserException("Failed to read " + name, null, e);
-        } finally {
-            try {
-                bufferedStream.close();
-            } catch (IOException e) {
-            }
-        }
-    }
-
-    private static class CustomParser extends KXmlParser {
-        private final String mName;
-
-        CustomParser(String name) {
-            super();
-            mName = name;
-        }
-
-        @Override
-        public String toString() {
-            return mName;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java
deleted file mode 100644
index 7b70180..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-
-import android.animation.AnimationThread;
-import android.animation.Animator;
-
-public class PlayAnimationThread extends AnimationThread {
-
-    private final Animator mAnimator;
-
-    public PlayAnimationThread(Animator animator, RenderSessionImpl scene, String animName,
-            IAnimationListener listener) {
-        super(scene, animName, listener);
-        mAnimator = animator;
-    }
-
-    @Override
-    public Result preAnimation() {
-        // start the animation. This will send a message to the handler right away, so
-        // the queue is filled when this method returns.
-        mAnimator.start();
-
-        return Status.SUCCESS.createResult();
-    }
-
-    @Override
-    public void postAnimation() {
-        // nothing to be done.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
deleted file mode 100644
index 60f5331..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider;
-import com.android.ide.common.rendering.api.Result;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.Density;
-import com.android.resources.ResourceType;
-import com.android.resources.ScreenOrientation;
-import com.android.resources.ScreenSize;
-
-import android.content.res.Configuration;
-import android.os.HandlerThread_Delegate;
-import android.os.Looper;
-import android.util.DisplayMetrics;
-import android.view.ViewConfiguration_Accessor;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodManager_Accessor;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * Base class for rendering action.
- *
- * It provides life-cycle methods to init and stop the rendering.
- * The most important methods are:
- * {@link #init(long)} and {@link #acquire(long)} to start a rendering and {@link #release()}
- * after the rendering.
- *
- *
- * @param <T> the {@link RenderParams} implementation
- *
- */
-public abstract class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider {
-
-    /**
-     * The current context being rendered. This is set through {@link #acquire(long)} and
-     * {@link #init(long)}, and unset in {@link #release()}.
-     */
-    private static BridgeContext sCurrentContext = null;
-
-    private final T mParams;
-
-    private BridgeContext mContext;
-
-    /**
-     * Creates a renderAction.
-     * <p>
-     * This <b>must</b> be followed by a call to {@link RenderAction#init()}, which act as a
-     * call to {@link RenderAction#acquire(long)}
-     *
-     * @param params the RenderParams. This must be a copy that the action can keep
-     *
-     */
-    protected RenderAction(T params) {
-        mParams = params;
-    }
-
-    /**
-     * Initializes and acquires the scene, creating various Android objects such as context,
-     * inflater, and parser.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     *
-     * @return whether the scene was prepared
-     *
-     * @see #acquire(long)
-     * @see #release()
-     */
-    public Result init(long timeout) {
-        // acquire the lock. if the result is null, lock was just acquired, otherwise, return
-        // the result.
-        Result result = acquireLock(timeout);
-        if (result != null) {
-            return result;
-        }
-
-        HardwareConfig hardwareConfig = mParams.getHardwareConfig();
-
-        // setup the display Metrics.
-        DisplayMetrics metrics = new DisplayMetrics();
-        metrics.densityDpi = metrics.noncompatDensityDpi =
-                hardwareConfig.getDensity().getDpiValue();
-
-        metrics.density = metrics.noncompatDensity =
-                metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
-
-        metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density;
-
-        metrics.widthPixels = metrics.noncompatWidthPixels = hardwareConfig.getScreenWidth();
-        metrics.heightPixels = metrics.noncompatHeightPixels = hardwareConfig.getScreenHeight();
-        metrics.xdpi = metrics.noncompatXdpi = hardwareConfig.getXdpi();
-        metrics.ydpi = metrics.noncompatYdpi = hardwareConfig.getYdpi();
-
-        RenderResources resources = mParams.getResources();
-
-        // build the context
-        mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
-                mParams.getProjectCallback(), getConfiguration(), mParams.getTargetSdkVersion(),
-                mParams.isRtlSupported());
-
-        setUp();
-
-        return SUCCESS.createResult();
-    }
-
-
-    /**
-     * Prepares the scene for action.
-     * <p>
-     * This call is blocking if another rendering/inflating is currently happening, and will return
-     * whether the preparation worked.
-     *
-     * The preparation can fail if another rendering took too long and the timeout was elapsed.
-     *
-     * More than one call to this from the same thread will have no effect and will return
-     * {@link Result#SUCCESS}.
-     *
-     * After scene actions have taken place, only one call to {@link #release()} must be
-     * done.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     *
-     * @return whether the scene was prepared
-     *
-     * @see #release()
-     *
-     * @throws IllegalStateException if {@link #init(long)} was never called.
-     */
-    public Result acquire(long timeout) {
-        if (mContext == null) {
-            throw new IllegalStateException("After scene creation, #init() must be called");
-        }
-
-        // acquire the lock. if the result is null, lock was just acquired, otherwise, return
-        // the result.
-        Result result = acquireLock(timeout);
-        if (result != null) {
-            return result;
-        }
-
-        setUp();
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Acquire the lock so that the scene can be acted upon.
-     * <p>
-     * This returns null if the lock was just acquired, otherwise it returns
-     * {@link Result#SUCCESS} if the lock already belonged to that thread, or another
-     * instance (see {@link Result#getStatus()}) if an error occurred.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     * @return null if the lock was just acquire or another result depending on the state.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene.
-     */
-    private Result acquireLock(long timeout) {
-        ReentrantLock lock = Bridge.getLock();
-        if (lock.isHeldByCurrentThread() == false) {
-            try {
-                boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS);
-
-                if (acquired == false) {
-                    return ERROR_TIMEOUT.createResult();
-                }
-            } catch (InterruptedException e) {
-                return ERROR_LOCK_INTERRUPTED.createResult();
-            }
-        } else {
-            // This thread holds the lock already. Checks that this wasn't for a different context.
-            // If this is called by init, mContext will be null and so should sCurrentContext
-            // anyway
-            if (mContext != sCurrentContext) {
-                throw new IllegalStateException("Acquiring different scenes from same thread without releases");
-            }
-            return SUCCESS.createResult();
-        }
-
-        return null;
-    }
-
-    /**
-     * Cleans up the scene after an action.
-     */
-    public void release() {
-        ReentrantLock lock = Bridge.getLock();
-
-        // with the use of finally blocks, it is possible to find ourself calling this
-        // without a successful call to prepareScene. This test makes sure that unlock() will
-        // not throw IllegalMonitorStateException.
-        if (lock.isHeldByCurrentThread()) {
-            tearDown();
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Sets up the session for rendering.
-     * <p/>
-     * The counterpart is {@link #tearDown()}.
-     */
-    private void setUp() {
-        // make sure the Resources object references the context (and other objects) for this
-        // scene
-        mContext.initResources();
-        sCurrentContext = mContext;
-
-        // create an InputMethodManager
-        InputMethodManager.getInstance();
-
-        LayoutLog currentLog = mParams.getLog();
-        Bridge.setLog(currentLog);
-        mContext.getRenderResources().setFrameworkResourceIdProvider(this);
-        mContext.getRenderResources().setLogger(currentLog);
-    }
-
-    /**
-     * Tear down the session after rendering.
-     * <p/>
-     * The counterpart is {@link #setUp()}.
-     */
-    private void tearDown() {
-        // The context may be null, if there was an error during init().
-        if (mContext != null) {
-            // Make sure to remove static references, otherwise we could not unload the lib
-            mContext.disposeResources();
-        }
-
-        if (sCurrentContext != null) {
-            // quit HandlerThread created during this session.
-            HandlerThread_Delegate.cleanUp(sCurrentContext);
-        }
-
-        // clear the stored ViewConfiguration since the map is per density and not per context.
-        ViewConfiguration_Accessor.clearConfigurations();
-
-        // remove the InputMethodManager
-        InputMethodManager_Accessor.resetInstance();
-
-        sCurrentContext = null;
-
-        Bridge.setLog(null);
-        if (mContext != null) {
-            mContext.getRenderResources().setFrameworkResourceIdProvider(null);
-            mContext.getRenderResources().setLogger(null);
-        }
-
-    }
-
-    public static BridgeContext getCurrentContext() {
-        return sCurrentContext;
-    }
-
-    protected T getParams() {
-        return mParams;
-    }
-
-    protected BridgeContext getContext() {
-        return mContext;
-    }
-
-    /**
-     * Returns the log associated with the session.
-     * @return the log or null if there are none.
-     */
-    public LayoutLog getLog() {
-        if (mParams != null) {
-            return mParams.getLog();
-        }
-
-        return null;
-    }
-
-    /**
-     * Checks that the lock is owned by the current thread and that the current context is the one
-     * from this scene.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     */
-    protected void checkLock() {
-        ReentrantLock lock = Bridge.getLock();
-        if (lock.isHeldByCurrentThread() == false) {
-            throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
-        }
-        if (sCurrentContext != mContext) {
-            throw new IllegalStateException("Thread acquired a scene but is rendering a different one");
-        }
-    }
-
-    private Configuration getConfiguration() {
-        Configuration config = new Configuration();
-
-        HardwareConfig hardwareConfig = mParams.getHardwareConfig();
-
-        ScreenSize screenSize = hardwareConfig.getScreenSize();
-        if (screenSize != null) {
-            switch (screenSize) {
-                case SMALL:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_SMALL;
-                    break;
-                case NORMAL:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_NORMAL;
-                    break;
-                case LARGE:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_LARGE;
-                    break;
-                case XLARGE:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE;
-                    break;
-            }
-        }
-
-        Density density = hardwareConfig.getDensity();
-        if (density == null) {
-            density = Density.MEDIUM;
-        }
-
-        config.screenWidthDp = hardwareConfig.getScreenWidth() / density.getDpiValue();
-        config.screenHeightDp = hardwareConfig.getScreenHeight() / density.getDpiValue();
-        if (config.screenHeightDp < config.screenWidthDp) {
-            config.smallestScreenWidthDp = config.screenHeightDp;
-        } else {
-            config.smallestScreenWidthDp = config.screenWidthDp;
-        }
-        config.densityDpi = density.getDpiValue();
-
-        // never run in compat mode:
-        config.compatScreenWidthDp = config.screenWidthDp;
-        config.compatScreenHeightDp = config.screenHeightDp;
-
-        ScreenOrientation orientation = hardwareConfig.getOrientation();
-        if (orientation != null) {
-            switch (orientation) {
-            case PORTRAIT:
-                config.orientation = Configuration.ORIENTATION_PORTRAIT;
-                break;
-            case LANDSCAPE:
-                config.orientation = Configuration.ORIENTATION_LANDSCAPE;
-                break;
-            case SQUARE:
-                config.orientation = Configuration.ORIENTATION_SQUARE;
-                break;
-            }
-        } else {
-            config.orientation = Configuration.ORIENTATION_UNDEFINED;
-        }
-
-        // TODO: fill in more config info.
-
-        return config;
-    }
-
-
-    // --- FrameworkResourceIdProvider methods
-
-    @Override
-    public Integer getId(ResourceType resType, String resName) {
-        return Bridge.getResourceId(resType, resName);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
deleted file mode 100644
index b677131..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
+++ /dev/null
@@ -1,133 +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.layoutlib.bridge.impl;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-
-import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.ResourceType;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.view.AttachInfo_Accessor;
-import android.view.View.MeasureSpec;
-import android.widget.FrameLayout;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-
-/**
- * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}.
- *
- * The class only provides a simple {@link #render()} method, but the full life-cycle of the
- * action must be respected.
- *
- * @see RenderAction
- *
- */
-public class RenderDrawable extends RenderAction<DrawableParams> {
-
-    public RenderDrawable(DrawableParams params) {
-        super(new DrawableParams(params));
-    }
-
-    public Result render() {
-        checkLock();
-        try {
-            // get the drawable resource value
-            DrawableParams params = getParams();
-            HardwareConfig hardwareConfig = params.getHardwareConfig();
-            ResourceValue drawableResource = params.getDrawable();
-
-            // resolve it
-            BridgeContext context = getContext();
-            drawableResource = context.getRenderResources().resolveResValue(drawableResource);
-
-            if (drawableResource == null ||
-                    drawableResource.getResourceType() != ResourceType.DRAWABLE) {
-                return Status.ERROR_NOT_A_DRAWABLE.createResult();
-            }
-
-            // create a simple FrameLayout
-            FrameLayout content = new FrameLayout(context);
-
-            // get the actual Drawable object to draw
-            Drawable d = ResourceHelper.getDrawable(drawableResource, context);
-            content.setBackground(d);
-
-            // set the AttachInfo on the root view.
-            AttachInfo_Accessor.setAttachInfo(content);
-
-
-            // measure
-            int w = hardwareConfig.getScreenWidth();
-            int h = hardwareConfig.getScreenHeight();
-            int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
-            int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
-            content.measure(w_spec, h_spec);
-
-            // now do the layout.
-            content.layout(0, 0, w, h);
-
-            // preDraw setup
-            AttachInfo_Accessor.dispatchOnPreDraw(content);
-
-            // draw into a new image
-            BufferedImage image = getImage(w, h);
-
-            // create an Android bitmap around the BufferedImage
-            Bitmap bitmap = Bitmap_Delegate.createBitmap(image,
-                    true /*isMutable*/, hardwareConfig.getDensity());
-
-            // create a Canvas around the Android bitmap
-            Canvas canvas = new Canvas(bitmap);
-            canvas.setDensity(hardwareConfig.getDensity().getDpiValue());
-
-            // and draw
-            content.draw(canvas);
-
-            return Status.SUCCESS.createResult(image);
-        } catch (IOException e) {
-            return ERROR_UNKNOWN.createResult(e.getMessage(), e);
-        }
-    }
-
-    protected BufferedImage getImage(int w, int h) {
-        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
-        Graphics2D gc = image.createGraphics();
-        gc.setComposite(AlphaComposite.Src);
-
-        gc.setColor(new Color(0x00000000, true));
-        gc.fillRect(0, 0, w, h);
-
-        // done
-        gc.dispose();
-
-        return image;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
deleted file mode 100644
index 57771e3..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ /dev/null
@@ -1,1486 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.IProjectCallback;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.bars.FakeActionBar;
-import com.android.layoutlib.bridge.bars.NavigationBar;
-import com.android.layoutlib.bridge.bars.StatusBar;
-import com.android.layoutlib.bridge.bars.TitleBar;
-import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
-import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
-import com.android.resources.ResourceType;
-import com.android.resources.ScreenOrientation;
-import com.android.util.Pair;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.animation.AnimationThread;
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.LayoutTransition;
-import android.animation.LayoutTransition.TransitionListener;
-import android.app.Fragment_Delegate;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.AttachInfo_Accessor;
-import android.view.BridgeInflater;
-import android.view.IWindowManager;
-import android.view.IWindowManagerImpl;
-import android.view.Surface;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewGroup.MarginLayoutParams;
-import android.view.WindowManagerGlobal_Delegate;
-import android.widget.AbsListView;
-import android.widget.AbsSpinner;
-import android.widget.AdapterView;
-import android.widget.ExpandableListView;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.QuickContactBadge;
-import android.widget.TabHost;
-import android.widget.TabHost.TabSpec;
-import android.widget.TabWidget;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Class implementing the render session.
- *
- * A session is a stateful representation of a layout file. It is initialized with data coming
- * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then
- * be done on the layout.
- *
- */
-public class RenderSessionImpl extends RenderAction<SessionParams> {
-
-    private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
-    private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
-
-    // scene state
-    private RenderSession mScene;
-    private BridgeXmlBlockParser mBlockParser;
-    private BridgeInflater mInflater;
-    private ResourceValue mWindowBackground;
-    private ViewGroup mViewRoot;
-    private FrameLayout mContentRoot;
-    private Canvas mCanvas;
-    private int mMeasuredScreenWidth = -1;
-    private int mMeasuredScreenHeight = -1;
-    private boolean mIsAlphaChannelImage;
-    private boolean mWindowIsFloating;
-
-    private int mStatusBarSize;
-    private int mNavigationBarSize;
-    private int mNavigationBarOrientation = LinearLayout.HORIZONTAL;
-    private int mTitleBarSize;
-    private int mActionBarSize;
-
-
-    // information being returned through the API
-    private BufferedImage mImage;
-    private List<ViewInfo> mViewInfoList;
-
-    private static final class PostInflateException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        public PostInflateException(String message) {
-            super(message);
-        }
-    }
-
-    /**
-     * Creates a layout scene with all the information coming from the layout bridge API.
-     * <p>
-     * This <b>must</b> be followed by a call to {@link RenderSessionImpl#init()}, which act as a
-     * call to {@link RenderSessionImpl#acquire(long)}
-     *
-     * @see LayoutBridge#createScene(com.android.layoutlib.api.SceneParams)
-     */
-    public RenderSessionImpl(SessionParams params) {
-        super(new SessionParams(params));
-    }
-
-    /**
-     * Initializes and acquires the scene, creating various Android objects such as context,
-     * inflater, and parser.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     *
-     * @return whether the scene was prepared
-     *
-     * @see #acquire(long)
-     * @see #release()
-     */
-    @Override
-    public Result init(long timeout) {
-        Result result = super.init(timeout);
-        if (result.isSuccess() == false) {
-            return result;
-        }
-
-        SessionParams params = getParams();
-        BridgeContext context = getContext();
-
-        RenderResources resources = getParams().getResources();
-        DisplayMetrics metrics = getContext().getMetrics();
-
-        // use default of true in case it's not found to use alpha by default
-        mIsAlphaChannelImage  = getBooleanThemeValue(resources,
-                "windowIsFloating", true /*defaultValue*/);
-
-        mWindowIsFloating = getBooleanThemeValue(resources, "windowIsFloating",
-                true /*defaultValue*/);
-
-        findBackground(resources);
-        findStatusBar(resources, metrics);
-        findActionBar(resources, metrics);
-        findNavigationBar(resources, metrics);
-
-        // FIXME: find those out, and possibly add them to the render params
-        boolean hasNavigationBar = true;
-        IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(),
-                metrics, Surface.ROTATION_0,
-                hasNavigationBar);
-        WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
-
-        // build the inflater and parser.
-        mInflater = new BridgeInflater(context, params.getProjectCallback());
-        context.setBridgeInflater(mInflater);
-
-        mBlockParser = new BridgeXmlBlockParser(
-                params.getLayoutDescription(), context, false /* platformResourceFlag */);
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Inflates the layout.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #init(long)} was not called.
-     */
-    public Result inflate() {
-        checkLock();
-
-        try {
-
-            SessionParams params = getParams();
-            HardwareConfig hardwareConfig = params.getHardwareConfig();
-            BridgeContext context = getContext();
-            boolean isRtl = Bridge.isLocaleRtl(params.getLocale());
-            int direction = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
-
-            // the view group that receives the window background.
-            ViewGroup backgroundView = null;
-
-            if (mWindowIsFloating || params.isForceNoDecor()) {
-                backgroundView = mViewRoot = mContentRoot = new FrameLayout(context);
-                mViewRoot.setLayoutDirection(direction);
-            } else {
-                if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) {
-                    /*
-                     * This is a special case where the navigation bar is on the right.
-                       +-------------------------------------------------+---+
-                       | Status bar (always)                             |   |
-                       +-------------------------------------------------+   |
-                       | (Layout with background drawable)               |   |
-                       | +---------------------------------------------+ |   |
-                       | | Title/Action bar (optional)                 | |   |
-                       | +---------------------------------------------+ |   |
-                       | | Content, vertical extending                 | |   |
-                       | |                                             | |   |
-                       | +---------------------------------------------+ |   |
-                       +-------------------------------------------------+---+
-
-                       So we create a horizontal layout, with the nav bar on the right,
-                       and the left part is the normal layout below without the nav bar at
-                       the bottom
-                     */
-                    LinearLayout topLayout = new LinearLayout(context);
-                    topLayout.setLayoutDirection(direction);
-                    mViewRoot = topLayout;
-                    topLayout.setOrientation(LinearLayout.HORIZONTAL);
-
-                    try {
-                        NavigationBar navigationBar = new NavigationBar(context,
-                                hardwareConfig.getDensity(), LinearLayout.VERTICAL, isRtl,
-                                params.isRtlSupported());
-                        navigationBar.setLayoutParams(
-                                new LinearLayout.LayoutParams(
-                                        mNavigationBarSize,
-                                        LayoutParams.MATCH_PARENT));
-                        topLayout.addView(navigationBar);
-                    } catch (XmlPullParserException e) {
-
-                    }
-                }
-
-                /*
-                 * we're creating the following layout
-                 *
-                   +-------------------------------------------------+
-                   | Status bar (always)                             |
-                   +-------------------------------------------------+
-                   | (Layout with background drawable)               |
-                   | +---------------------------------------------+ |
-                   | | Title/Action bar (optional)                 | |
-                   | +---------------------------------------------+ |
-                   | | Content, vertical extending                 | |
-                   | |                                             | |
-                   | +---------------------------------------------+ |
-                   +-------------------------------------------------+
-                   | Navigation bar for soft buttons, maybe see above|
-                   +-------------------------------------------------+
-
-                 */
-
-                LinearLayout topLayout = new LinearLayout(context);
-                topLayout.setOrientation(LinearLayout.VERTICAL);
-                topLayout.setLayoutDirection(direction);
-                // if we don't already have a view root this is it
-                if (mViewRoot == null) {
-                    mViewRoot = topLayout;
-                } else {
-                    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
-                            LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
-                    layoutParams.weight = 1;
-                    topLayout.setLayoutParams(layoutParams);
-
-                    // this is the case of soft buttons + vertical bar.
-                    // this top layout is the first layout in the horizontal layout. see above)
-                    if (isRtl && params.isRtlSupported()) {
-                        // If RTL is enabled, layoutlib will mirror the layouts. So, add the
-                        // topLayout to the right of Navigation Bar and layoutlib will draw it
-                        // to the left.
-                        mViewRoot.addView(topLayout);
-                    } else {
-                        // Add the top layout to the left of the Navigation Bar.
-                        mViewRoot.addView(topLayout, 0);
-                    }
-                }
-
-                if (mStatusBarSize > 0) {
-                    // system bar
-                    try {
-                        StatusBar systemBar = new StatusBar(context, hardwareConfig.getDensity(),
-                                direction, params.isRtlSupported());
-                        systemBar.setLayoutParams(
-                                new LinearLayout.LayoutParams(
-                                        LayoutParams.MATCH_PARENT, mStatusBarSize));
-                        topLayout.addView(systemBar);
-                    } catch (XmlPullParserException e) {
-
-                    }
-                }
-
-                LinearLayout backgroundLayout = new LinearLayout(context);
-                backgroundView = backgroundLayout;
-                backgroundLayout.setOrientation(LinearLayout.VERTICAL);
-                LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
-                        LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
-                layoutParams.weight = 1;
-                backgroundLayout.setLayoutParams(layoutParams);
-                topLayout.addView(backgroundLayout);
-
-
-                // if the theme says no title/action bar, then the size will be 0
-                if (mActionBarSize > 0) {
-                    try {
-                        FakeActionBar actionBar = new FakeActionBar(context,
-                                hardwareConfig.getDensity(),
-                                params.getAppLabel(), params.getAppIcon());
-                        actionBar.setLayoutParams(
-                                new LinearLayout.LayoutParams(
-                                        LayoutParams.MATCH_PARENT, mActionBarSize));
-                        backgroundLayout.addView(actionBar);
-                    } catch (XmlPullParserException e) {
-
-                    }
-                } else if (mTitleBarSize > 0) {
-                    try {
-                        TitleBar titleBar = new TitleBar(context,
-                                hardwareConfig.getDensity(), params.getAppLabel());
-                        titleBar.setLayoutParams(
-                                new LinearLayout.LayoutParams(
-                                        LayoutParams.MATCH_PARENT, mTitleBarSize));
-                        backgroundLayout.addView(titleBar);
-                    } catch (XmlPullParserException e) {
-
-                    }
-                }
-
-                // content frame
-                mContentRoot = new FrameLayout(context);
-                layoutParams = new LinearLayout.LayoutParams(
-                        LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
-                layoutParams.weight = 1;
-                mContentRoot.setLayoutParams(layoutParams);
-                backgroundLayout.addView(mContentRoot);
-
-                if (mNavigationBarOrientation == LinearLayout.HORIZONTAL &&
-                        mNavigationBarSize > 0) {
-                    // system bar
-                    try {
-                        NavigationBar navigationBar = new NavigationBar(context,
-                                hardwareConfig.getDensity(), LinearLayout.HORIZONTAL, isRtl,
-                                params.isRtlSupported());
-                        navigationBar.setLayoutParams(
-                                new LinearLayout.LayoutParams(
-                                        LayoutParams.MATCH_PARENT, mNavigationBarSize));
-                        topLayout.addView(navigationBar);
-                    } catch (XmlPullParserException e) {
-
-                    }
-                }
-            }
-
-
-            // Sets the project callback (custom view loader) to the fragment delegate so that
-            // it can instantiate the custom Fragment.
-            Fragment_Delegate.setProjectCallback(params.getProjectCallback());
-
-            View view = mInflater.inflate(mBlockParser, mContentRoot);
-
-            // done with the parser, pop it.
-            context.popParser();
-
-            Fragment_Delegate.setProjectCallback(null);
-
-            // set the AttachInfo on the root view.
-            AttachInfo_Accessor.setAttachInfo(mViewRoot);
-
-            // post-inflate process. For now this supports TabHost/TabWidget
-            postInflateProcess(view, params.getProjectCallback());
-
-            // get the background drawable
-            if (mWindowBackground != null && backgroundView != null) {
-                Drawable d = ResourceHelper.getDrawable(mWindowBackground, context);
-                backgroundView.setBackground(d);
-            }
-
-            return SUCCESS.createResult();
-        } catch (PostInflateException e) {
-            return ERROR_INFLATION.createResult(e.getMessage(), e);
-        } catch (Throwable e) {
-            // get the real cause of the exception.
-            Throwable t = e;
-            while (t.getCause() != null) {
-                t = t.getCause();
-            }
-
-            return ERROR_INFLATION.createResult(t.getMessage(), t);
-        }
-    }
-
-    /**
-     * Renders the scene.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @param freshRender whether the render is a new one and should erase the existing bitmap (in
-     *      the case where bitmaps are reused). This is typically needed when not playing
-     *      animations.)
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderParams#getRenderingMode()
-     * @see RenderSession#render(long)
-     */
-    public Result render(boolean freshRender) {
-        checkLock();
-
-        SessionParams params = getParams();
-
-        try {
-            if (mViewRoot == null) {
-                return ERROR_NOT_INFLATED.createResult();
-            }
-
-            RenderingMode renderingMode = params.getRenderingMode();
-            HardwareConfig hardwareConfig = params.getHardwareConfig();
-
-            // only do the screen measure when needed.
-            boolean newRenderSize = false;
-            if (mMeasuredScreenWidth == -1) {
-                newRenderSize = true;
-                mMeasuredScreenWidth = hardwareConfig.getScreenWidth();
-                mMeasuredScreenHeight = hardwareConfig.getScreenHeight();
-
-                if (renderingMode != RenderingMode.NORMAL) {
-                    int widthMeasureSpecMode = renderingMode.isHorizExpand() ?
-                            MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
-                            : MeasureSpec.EXACTLY;
-                    int heightMeasureSpecMode = renderingMode.isVertExpand() ?
-                            MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
-                            : MeasureSpec.EXACTLY;
-
-                    // We used to compare the measured size of the content to the screen size but
-                    // this does not work anymore due to the 2 following issues:
-                    // - If the content is in a decor (system bar, title/action bar), the root view
-                    //   will not resize even with the UNSPECIFIED because of the embedded layout.
-                    // - If there is no decor, but a dialog frame, then the dialog padding prevents
-                    //   comparing the size of the content to the screen frame (as it would not
-                    //   take into account the dialog padding).
-
-                    // The solution is to first get the content size in a normal rendering, inside
-                    // the decor or the dialog padding.
-                    // Then measure only the content with UNSPECIFIED to see the size difference
-                    // and apply this to the screen size.
-
-                    // first measure the full layout, with EXACTLY to get the size of the
-                    // content as it is inside the decor/dialog
-                    Pair<Integer, Integer> exactMeasure = measureView(
-                            mViewRoot, mContentRoot.getChildAt(0),
-                            mMeasuredScreenWidth, MeasureSpec.EXACTLY,
-                            mMeasuredScreenHeight, MeasureSpec.EXACTLY);
-
-                    // now measure the content only using UNSPECIFIED (where applicable, based on
-                    // the rendering mode). This will give us the size the content needs.
-                    Pair<Integer, Integer> result = measureView(
-                            mContentRoot, mContentRoot.getChildAt(0),
-                            mMeasuredScreenWidth, widthMeasureSpecMode,
-                            mMeasuredScreenHeight, heightMeasureSpecMode);
-
-                    // now look at the difference and add what is needed.
-                    if (renderingMode.isHorizExpand()) {
-                        int measuredWidth = exactMeasure.getFirst();
-                        int neededWidth = result.getFirst();
-                        if (neededWidth > measuredWidth) {
-                            mMeasuredScreenWidth += neededWidth - measuredWidth;
-                        }
-                    }
-
-                    if (renderingMode.isVertExpand()) {
-                        int measuredHeight = exactMeasure.getSecond();
-                        int neededHeight = result.getSecond();
-                        if (neededHeight > measuredHeight) {
-                            mMeasuredScreenHeight += neededHeight - measuredHeight;
-                        }
-                    }
-                }
-            }
-
-            // measure again with the size we need
-            // This must always be done before the call to layout
-            measureView(mViewRoot, null /*measuredView*/,
-                    mMeasuredScreenWidth, MeasureSpec.EXACTLY,
-                    mMeasuredScreenHeight, MeasureSpec.EXACTLY);
-
-            // now do the layout.
-            mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
-
-            if (params.isLayoutOnly()) {
-                // delete the canvas and image to reset them on the next full rendering
-                mImage = null;
-                mCanvas = null;
-            } else {
-                AttachInfo_Accessor.dispatchOnPreDraw(mViewRoot);
-
-                // draw the views
-                // create the BufferedImage into which the layout will be rendered.
-                boolean newImage = false;
-                if (newRenderSize || mCanvas == null) {
-                    if (params.getImageFactory() != null) {
-                        mImage = params.getImageFactory().getImage(
-                                mMeasuredScreenWidth,
-                                mMeasuredScreenHeight);
-                    } else {
-                        mImage = new BufferedImage(
-                                mMeasuredScreenWidth,
-                                mMeasuredScreenHeight,
-                                BufferedImage.TYPE_INT_ARGB);
-                        newImage = true;
-                    }
-
-                    if (params.isBgColorOverridden()) {
-                        // since we override the content, it's the same as if it was a new image.
-                        newImage = true;
-                        Graphics2D gc = mImage.createGraphics();
-                        gc.setColor(new Color(params.getOverrideBgColor(), true));
-                        gc.setComposite(AlphaComposite.Src);
-                        gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
-                        gc.dispose();
-                    }
-
-                    // create an Android bitmap around the BufferedImage
-                    Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
-                            true /*isMutable*/, hardwareConfig.getDensity());
-
-                    // create a Canvas around the Android bitmap
-                    mCanvas = new Canvas(bitmap);
-                    mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue());
-                }
-
-                if (freshRender && newImage == false) {
-                    Graphics2D gc = mImage.createGraphics();
-                    gc.setComposite(AlphaComposite.Src);
-
-                    gc.setColor(new Color(0x00000000, true));
-                    gc.fillRect(0, 0,
-                            mMeasuredScreenWidth, mMeasuredScreenHeight);
-
-                    // done
-                    gc.dispose();
-                }
-
-                mViewRoot.draw(mCanvas);
-            }
-
-            mViewInfoList = startVisitingViews(mViewRoot, 0, params.getExtendedViewInfoMode());
-
-            // success!
-            return SUCCESS.createResult();
-        } catch (Throwable e) {
-            // get the real cause of the exception.
-            Throwable t = e;
-            while (t.getCause() != null) {
-                t = t.getCause();
-            }
-
-            return ERROR_UNKNOWN.createResult(t.getMessage(), t);
-        }
-    }
-
-    /**
-     * Executes {@link View#measure(int, int)} on a given view with the given parameters (used
-     * to create measure specs with {@link MeasureSpec#makeMeasureSpec(int, int)}.
-     *
-     * if <var>measuredView</var> is non null, the method returns a {@link Pair} of (width, height)
-     * for the view (using {@link View#getMeasuredWidth()} and {@link View#getMeasuredHeight()}).
-     *
-     * @param viewToMeasure the view on which to execute measure().
-     * @param measuredView if non null, the view to query for its measured width/height.
-     * @param width the width to use in the MeasureSpec.
-     * @param widthMode the MeasureSpec mode to use for the width.
-     * @param height the height to use in the MeasureSpec.
-     * @param heightMode the MeasureSpec mode to use for the height.
-     * @return the measured width/height if measuredView is non-null, null otherwise.
-     */
-    private Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView,
-            int width, int widthMode, int height, int heightMode) {
-        int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode);
-        int h_spec = MeasureSpec.makeMeasureSpec(height, heightMode);
-        viewToMeasure.measure(w_spec, h_spec);
-
-        if (measuredView != null) {
-            return Pair.of(measuredView.getMeasuredWidth(), measuredView.getMeasuredHeight());
-        }
-
-        return null;
-    }
-
-    /**
-     * Animate an object
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#animate(Object, String, boolean, IAnimationListener)
-     */
-    public Result animate(Object targetObject, String animationName,
-            boolean isFrameworkAnimation, IAnimationListener listener) {
-        checkLock();
-
-        BridgeContext context = getContext();
-
-        // find the animation file.
-        ResourceValue animationResource = null;
-        int animationId = 0;
-        if (isFrameworkAnimation) {
-            animationResource = context.getRenderResources().getFrameworkResource(
-                    ResourceType.ANIMATOR, animationName);
-            if (animationResource != null) {
-                animationId = Bridge.getResourceId(ResourceType.ANIMATOR, animationName);
-            }
-        } else {
-            animationResource = context.getRenderResources().getProjectResource(
-                    ResourceType.ANIMATOR, animationName);
-            if (animationResource != null) {
-                animationId = context.getProjectCallback().getResourceId(
-                        ResourceType.ANIMATOR, animationName);
-            }
-        }
-
-        if (animationResource != null) {
-            try {
-                Animator anim = AnimatorInflater.loadAnimator(context, animationId);
-                if (anim != null) {
-                    anim.setTarget(targetObject);
-
-                    new PlayAnimationThread(anim, this, animationName, listener).start();
-
-                    return SUCCESS.createResult();
-                }
-            } catch (Exception e) {
-                // get the real cause of the exception.
-                Throwable t = e;
-                while (t.getCause() != null) {
-                    t = t.getCause();
-                }
-
-                return ERROR_UNKNOWN.createResult(t.getMessage(), t);
-            }
-        }
-
-        return ERROR_ANIM_NOT_FOUND.createResult();
-    }
-
-    /**
-     * Insert a new child into an existing parent.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#insertChild(Object, ILayoutPullParser, int, IAnimationListener)
-     */
-    public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml,
-            final int index, IAnimationListener listener) {
-        checkLock();
-
-        BridgeContext context = getContext();
-
-        // create a block parser for the XML
-        BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                childXml, context, false /* platformResourceFlag */);
-
-        // inflate the child without adding it to the root since we want to control where it'll
-        // get added. We do pass the parentView however to ensure that the layoutParams will
-        // be created correctly.
-        final View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/);
-        blockParser.ensurePopped();
-
-        invalidateRenderingSize();
-
-        if (listener != null) {
-            new AnimationThread(this, "insertChild", listener) {
-
-                @Override
-                public Result preAnimation() {
-                    parentView.setLayoutTransition(new LayoutTransition());
-                    return addView(parentView, child, index);
-                }
-
-                @Override
-                public void postAnimation() {
-                    parentView.setLayoutTransition(null);
-                }
-            }.start();
-
-            // always return success since the real status will come through the listener.
-            return SUCCESS.createResult(child);
-        }
-
-        // add it to the parentView in the correct location
-        Result result = addView(parentView, child, index);
-        if (result.isSuccess() == false) {
-            return result;
-        }
-
-        result = render(false /*freshRender*/);
-        if (result.isSuccess()) {
-            result = result.getCopyWithData(child);
-        }
-
-        return result;
-    }
-
-    /**
-     * Adds a given view to a given parent at a given index.
-     *
-     * @param parent the parent to receive the view
-     * @param view the view to add to the parent
-     * @param index the index where to do the add.
-     *
-     * @return a Result with {@link Status#SUCCESS} or
-     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
-     *     adding views.
-     */
-    private Result addView(ViewGroup parent, View view, int index) {
-        try {
-            parent.addView(view, index);
-            return SUCCESS.createResult();
-        } catch (UnsupportedOperationException e) {
-            // looks like this is a view class that doesn't support children manipulation!
-            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
-        }
-    }
-
-    /**
-     * Moves a view to a new parent at a given location
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#moveChild(Object, Object, int, Map, IAnimationListener)
-     */
-    public Result moveChild(final ViewGroup newParentView, final View childView, final int index,
-            Map<String, String> layoutParamsMap, final IAnimationListener listener) {
-        checkLock();
-
-        invalidateRenderingSize();
-
-        LayoutParams layoutParams = null;
-        if (layoutParamsMap != null) {
-            // need to create a new LayoutParams object for the new parent.
-            layoutParams = newParentView.generateLayoutParams(
-                    new BridgeLayoutParamsMapAttributes(layoutParamsMap));
-        }
-
-        // get the current parent of the view that needs to be moved.
-        final ViewGroup previousParent = (ViewGroup) childView.getParent();
-
-        if (listener != null) {
-            final LayoutParams params = layoutParams;
-
-            // there is no support for animating views across layouts, so in case the new and old
-            // parent views are different we fake the animation through a no animation thread.
-            if (previousParent != newParentView) {
-                new Thread("not animated moveChild") {
-                    @Override
-                    public void run() {
-                        Result result = moveView(previousParent, newParentView, childView, index,
-                                params);
-                        if (result.isSuccess() == false) {
-                            listener.done(result);
-                        }
-
-                        // ready to do the work, acquire the scene.
-                        result = acquire(250);
-                        if (result.isSuccess() == false) {
-                            listener.done(result);
-                            return;
-                        }
-
-                        try {
-                            result = render(false /*freshRender*/);
-                            if (result.isSuccess()) {
-                                listener.onNewFrame(RenderSessionImpl.this.getSession());
-                            }
-                        } finally {
-                            release();
-                        }
-
-                        listener.done(result);
-                    }
-                }.start();
-            } else {
-                new AnimationThread(this, "moveChild", listener) {
-
-                    @Override
-                    public Result preAnimation() {
-                        // set up the transition for the parent.
-                        LayoutTransition transition = new LayoutTransition();
-                        previousParent.setLayoutTransition(transition);
-
-                        // tweak the animation durations and start delays (to match the duration of
-                        // animation playing just before).
-                        // Note: Cannot user Animation.setDuration() directly. Have to set it
-                        // on the LayoutTransition.
-                        transition.setDuration(LayoutTransition.DISAPPEARING, 100);
-                        // CHANGE_DISAPPEARING plays after DISAPPEARING
-                        transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 100);
-
-                        transition.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 100);
-
-                        transition.setDuration(LayoutTransition.CHANGE_APPEARING, 100);
-                        // CHANGE_APPEARING plays after CHANGE_APPEARING
-                        transition.setStartDelay(LayoutTransition.APPEARING, 100);
-
-                        transition.setDuration(LayoutTransition.APPEARING, 100);
-
-                        return moveView(previousParent, newParentView, childView, index, params);
-                    }
-
-                    @Override
-                    public void postAnimation() {
-                        previousParent.setLayoutTransition(null);
-                        newParentView.setLayoutTransition(null);
-                    }
-                }.start();
-            }
-
-            // always return success since the real status will come through the listener.
-            return SUCCESS.createResult(layoutParams);
-        }
-
-        Result result = moveView(previousParent, newParentView, childView, index, layoutParams);
-        if (result.isSuccess() == false) {
-            return result;
-        }
-
-        result = render(false /*freshRender*/);
-        if (layoutParams != null && result.isSuccess()) {
-            result = result.getCopyWithData(layoutParams);
-        }
-
-        return result;
-    }
-
-    /**
-     * Moves a View from its current parent to a new given parent at a new given location, with
-     * an optional new {@link LayoutParams} instance
-     *
-     * @param previousParent the previous parent, still owning the child at the time of the call.
-     * @param newParent the new parent
-     * @param movedView the view to move
-     * @param index the new location in the new parent
-     * @param params an option (can be null) {@link LayoutParams} instance.
-     *
-     * @return a Result with {@link Status#SUCCESS} or
-     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
-     *     adding views.
-     */
-    private Result moveView(ViewGroup previousParent, final ViewGroup newParent,
-            final View movedView, final int index, final LayoutParams params) {
-        try {
-            // check if there is a transition on the previousParent.
-            LayoutTransition previousTransition = previousParent.getLayoutTransition();
-            if (previousTransition != null) {
-                // in this case there is an animation. This means we have to wait for the child's
-                // parent reference to be null'ed out so that we can add it to the new parent.
-                // It is technically removed right before the DISAPPEARING animation is done (if
-                // the animation of this type is not null, otherwise it's after which is impossible
-                // to handle).
-                // Because there is no move animation, if the new parent is the same as the old
-                // parent, we need to wait until the CHANGE_DISAPPEARING animation is done before
-                // adding the child or the child will appear in its new location before the
-                // other children have made room for it.
-
-                // add a listener to the transition to be notified of the actual removal.
-                previousTransition.addTransitionListener(new TransitionListener() {
-                    private int mChangeDisappearingCount = 0;
-
-                    @Override
-                    public void startTransition(LayoutTransition transition, ViewGroup container,
-                            View view, int transitionType) {
-                        if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) {
-                            mChangeDisappearingCount++;
-                        }
-                    }
-
-                    @Override
-                    public void endTransition(LayoutTransition transition, ViewGroup container,
-                            View view, int transitionType) {
-                        if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) {
-                            mChangeDisappearingCount--;
-                        }
-
-                        if (transitionType == LayoutTransition.CHANGE_DISAPPEARING &&
-                                mChangeDisappearingCount == 0) {
-                            // add it to the parentView in the correct location
-                            if (params != null) {
-                                newParent.addView(movedView, index, params);
-                            } else {
-                                newParent.addView(movedView, index);
-                            }
-                        }
-                    }
-                });
-
-                // remove the view from the current parent.
-                previousParent.removeView(movedView);
-
-                // and return since adding the view to the new parent is done in the listener.
-                return SUCCESS.createResult();
-            } else {
-                // standard code with no animation. pretty simple.
-                previousParent.removeView(movedView);
-
-                // add it to the parentView in the correct location
-                if (params != null) {
-                    newParent.addView(movedView, index, params);
-                } else {
-                    newParent.addView(movedView, index);
-                }
-
-                return SUCCESS.createResult();
-            }
-        } catch (UnsupportedOperationException e) {
-            // looks like this is a view class that doesn't support children manipulation!
-            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
-        }
-    }
-
-    /**
-     * Removes a child from its current parent.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#removeChild(Object, IAnimationListener)
-     */
-    public Result removeChild(final View childView, IAnimationListener listener) {
-        checkLock();
-
-        invalidateRenderingSize();
-
-        final ViewGroup parent = (ViewGroup) childView.getParent();
-
-        if (listener != null) {
-            new AnimationThread(this, "moveChild", listener) {
-
-                @Override
-                public Result preAnimation() {
-                    parent.setLayoutTransition(new LayoutTransition());
-                    return removeView(parent, childView);
-                }
-
-                @Override
-                public void postAnimation() {
-                    parent.setLayoutTransition(null);
-                }
-            }.start();
-
-            // always return success since the real status will come through the listener.
-            return SUCCESS.createResult();
-        }
-
-        Result result = removeView(parent, childView);
-        if (result.isSuccess() == false) {
-            return result;
-        }
-
-        return render(false /*freshRender*/);
-    }
-
-    /**
-     * Removes a given view from its current parent.
-     *
-     * @param view the view to remove from its parent
-     *
-     * @return a Result with {@link Status#SUCCESS} or
-     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
-     *     adding views.
-     */
-    private Result removeView(ViewGroup parent, View view) {
-        try {
-            parent.removeView(view);
-            return SUCCESS.createResult();
-        } catch (UnsupportedOperationException e) {
-            // looks like this is a view class that doesn't support children manipulation!
-            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
-        }
-    }
-
-
-    private void findBackground(RenderResources resources) {
-        if (getParams().isBgColorOverridden() == false) {
-            mWindowBackground = resources.findItemInTheme("windowBackground",
-                    true /*isFrameworkAttr*/);
-            if (mWindowBackground != null) {
-                mWindowBackground = resources.resolveResValue(mWindowBackground);
-            }
-        }
-    }
-
-    private boolean hasSoftwareButtons() {
-        return getParams().getHardwareConfig().hasSoftwareButtons();
-    }
-
-    private void findStatusBar(RenderResources resources, DisplayMetrics metrics) {
-        boolean windowFullscreen = getBooleanThemeValue(resources,
-                "windowFullscreen", false /*defaultValue*/);
-
-        if (windowFullscreen == false && mWindowIsFloating == false) {
-            // default value
-            mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT;
-
-            // get the real value
-            ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
-                    "status_bar_height");
-
-            if (value != null) {
-                TypedValue typedValue = ResourceHelper.getValue("status_bar_height",
-                        value.getValue(), true /*requireUnit*/);
-                if (typedValue != null) {
-                    // compute the pixel value based on the display metrics
-                    mStatusBarSize = (int)typedValue.getDimension(metrics);
-                }
-            }
-        }
-    }
-
-    private void findActionBar(RenderResources resources, DisplayMetrics metrics) {
-        if (mWindowIsFloating) {
-            return;
-        }
-
-        boolean windowActionBar = getBooleanThemeValue(resources,
-                "windowActionBar", true /*defaultValue*/);
-
-        // if there's a value and it's false (default is true)
-        if (windowActionBar) {
-
-            // default size of the window title bar
-            mActionBarSize = DEFAULT_TITLE_BAR_HEIGHT;
-
-            // get value from the theme.
-            ResourceValue value = resources.findItemInTheme("actionBarSize",
-                    true /*isFrameworkAttr*/);
-
-            // resolve it
-            value = resources.resolveResValue(value);
-
-            if (value != null) {
-                // get the numerical value, if available
-                TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(),
-                        true /*requireUnit*/);
-                if (typedValue != null) {
-                    // compute the pixel value based on the display metrics
-                    mActionBarSize = (int)typedValue.getDimension(metrics);
-                }
-            }
-        } else {
-            // action bar overrides title bar so only look for this one if action bar is hidden
-            boolean windowNoTitle = getBooleanThemeValue(resources,
-                    "windowNoTitle", false /*defaultValue*/);
-
-            if (windowNoTitle == false) {
-
-                // default size of the window title bar
-                mTitleBarSize = DEFAULT_TITLE_BAR_HEIGHT;
-
-                // get value from the theme.
-                ResourceValue value = resources.findItemInTheme("windowTitleSize",
-                        true /*isFrameworkAttr*/);
-
-                // resolve it
-                value = resources.resolveResValue(value);
-
-                if (value != null) {
-                    // get the numerical value, if available
-                    TypedValue typedValue = ResourceHelper.getValue("windowTitleSize",
-                            value.getValue(), true /*requireUnit*/);
-                    if (typedValue != null) {
-                        // compute the pixel value based on the display metrics
-                        mTitleBarSize = (int)typedValue.getDimension(metrics);
-                    }
-                }
-            }
-
-        }
-    }
-
-    private void findNavigationBar(RenderResources resources, DisplayMetrics metrics) {
-        if (hasSoftwareButtons() && mWindowIsFloating == false) {
-
-            // default value
-            mNavigationBarSize = 48; // ??
-
-            HardwareConfig hardwareConfig = getParams().getHardwareConfig();
-
-            boolean barOnBottom = true;
-
-            if (hardwareConfig.getOrientation() == ScreenOrientation.LANDSCAPE) {
-                // compute the dp of the screen.
-                int shortSize = hardwareConfig.getScreenHeight();
-
-                // compute in dp
-                int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / hardwareConfig.getDensity().getDpiValue();
-
-                if (shortSizeDp < 600) {
-                    // 0-599dp: "phone" UI with bar on the side
-                    barOnBottom = false;
-                } else {
-                    // 600+dp: "tablet" UI with bar on the bottom
-                    barOnBottom = true;
-                }
-            }
-
-            if (barOnBottom) {
-                mNavigationBarOrientation = LinearLayout.HORIZONTAL;
-            } else {
-                mNavigationBarOrientation = LinearLayout.VERTICAL;
-            }
-
-            // get the real value
-            ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
-                    barOnBottom ? "navigation_bar_height" : "navigation_bar_width");
-
-            if (value != null) {
-                TypedValue typedValue = ResourceHelper.getValue("navigation_bar_height",
-                        value.getValue(), true /*requireUnit*/);
-                if (typedValue != null) {
-                    // compute the pixel value based on the display metrics
-                    mNavigationBarSize = (int)typedValue.getDimension(metrics);
-                }
-            }
-        }
-    }
-
-    /**
-     * Looks for a attribute in the current theme. The attribute is in the android
-     * namespace.
-     *
-     * @param resources the render resources
-     * @param name the name of the attribute
-     * @param defaultValue the default value.
-     * @return the value of the attribute or the default one if not found.
-     */
-    private boolean getBooleanThemeValue(RenderResources resources,
-            String name, boolean defaultValue) {
-
-        // get the title bar flag from the current theme.
-        ResourceValue value = resources.findItemInTheme(name, true /*isFrameworkAttr*/);
-
-        // because it may reference something else, we resolve it.
-        value = resources.resolveResValue(value);
-
-        // if there's no value, return the default.
-        if (value == null || value.getValue() == null) {
-            return defaultValue;
-        }
-
-        return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue);
-    }
-
-    /**
-     * Post process on a view hierachy that was just inflated.
-     * <p/>At the moment this only support TabHost: If {@link TabHost} is detected, look for the
-     * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
-     * based on the content of the {@link FrameLayout}.
-     * @param view the root view to process.
-     * @param projectCallback callback to the project.
-     */
-    private void postInflateProcess(View view, IProjectCallback projectCallback)
-            throws PostInflateException {
-        if (view instanceof TabHost) {
-            setupTabHost((TabHost)view, projectCallback);
-        } else if (view instanceof QuickContactBadge) {
-            QuickContactBadge badge = (QuickContactBadge) view;
-            badge.setImageToDefault();
-        } else if (view instanceof AdapterView<?>) {
-            // get the view ID.
-            int id = view.getId();
-
-            BridgeContext context = getContext();
-
-            // get a ResourceReference from the integer ID.
-            ResourceReference listRef = context.resolveId(id);
-
-            if (listRef != null) {
-                SessionParams params = getParams();
-                AdapterBinding binding = params.getAdapterBindings().get(listRef);
-
-                // if there was no adapter binding, trying to get it from the call back.
-                if (binding == null) {
-                    binding = params.getProjectCallback().getAdapterBinding(listRef,
-                            context.getViewKey(view), view);
-                }
-
-                if (binding != null) {
-
-                    if (view instanceof AbsListView) {
-                        if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) &&
-                                view instanceof ListView) {
-                            ListView list = (ListView) view;
-
-                            boolean skipCallbackParser = false;
-
-                            int count = binding.getHeaderCount();
-                            for (int i = 0 ; i < count ; i++) {
-                                Pair<View, Boolean> pair = context.inflateView(
-                                        binding.getHeaderAt(i),
-                                        list, false /*attachToRoot*/, skipCallbackParser);
-                                if (pair.getFirst() != null) {
-                                    list.addHeaderView(pair.getFirst());
-                                }
-
-                                skipCallbackParser |= pair.getSecond();
-                            }
-
-                            count = binding.getFooterCount();
-                            for (int i = 0 ; i < count ; i++) {
-                                Pair<View, Boolean> pair = context.inflateView(
-                                        binding.getFooterAt(i),
-                                        list, false /*attachToRoot*/, skipCallbackParser);
-                                if (pair.getFirst() != null) {
-                                    list.addFooterView(pair.getFirst());
-                                }
-
-                                skipCallbackParser |= pair.getSecond();
-                            }
-                        }
-
-                        if (view instanceof ExpandableListView) {
-                            ((ExpandableListView) view).setAdapter(
-                                    new FakeExpandableAdapter(
-                                            listRef, binding, params.getProjectCallback()));
-                        } else {
-                            ((AbsListView) view).setAdapter(
-                                    new FakeAdapter(
-                                            listRef, binding, params.getProjectCallback()));
-                        }
-                    } else if (view instanceof AbsSpinner) {
-                        ((AbsSpinner) view).setAdapter(
-                                new FakeAdapter(
-                                        listRef, binding, params.getProjectCallback()));
-                    }
-                }
-            }
-        } else if (view instanceof ViewGroup) {
-            ViewGroup group = (ViewGroup)view;
-            final int count = group.getChildCount();
-            for (int c = 0 ; c < count ; c++) {
-                View child = group.getChildAt(c);
-                postInflateProcess(child, projectCallback);
-            }
-        }
-    }
-
-    /**
-     * Sets up a {@link TabHost} object.
-     * @param tabHost the TabHost to setup.
-     * @param projectCallback The project callback object to access the project R class.
-     * @throws PostInflateException
-     */
-    private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback)
-            throws PostInflateException {
-        // look for the TabWidget, and the FrameLayout. They have their own specific names
-        View v = tabHost.findViewById(android.R.id.tabs);
-
-        if (v == null) {
-            throw new PostInflateException(
-                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n");
-        }
-
-        if ((v instanceof TabWidget) == false) {
-            throw new PostInflateException(String.format(
-                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n" +
-                    "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName()));
-        }
-
-        v = tabHost.findViewById(android.R.id.tabcontent);
-
-        if (v == null) {
-            // TODO: see if we can fake tabs even without the FrameLayout (same below when the framelayout is empty)
-            throw new PostInflateException(
-                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".");
-        }
-
-        if ((v instanceof FrameLayout) == false) {
-            throw new PostInflateException(String.format(
-                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" +
-                    "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName()));
-        }
-
-        FrameLayout content = (FrameLayout)v;
-
-        // now process the content of the framelayout and dynamically create tabs for it.
-        final int count = content.getChildCount();
-
-        // this must be called before addTab() so that the TabHost searches its TabWidget
-        // and FrameLayout.
-        tabHost.setup();
-
-        if (count == 0) {
-            // Create a dummy child to get a single tab
-            TabSpec spec = tabHost.newTabSpec("tag").setIndicator("Tab Label",
-                    tabHost.getResources().getDrawable(android.R.drawable.ic_menu_info_details))
-                    .setContent(new TabHost.TabContentFactory() {
-                        @Override
-                        public View createTabContent(String tag) {
-                            return new LinearLayout(getContext());
-                        }
-                    });
-            tabHost.addTab(spec);
-            return;
-        } else {
-            // for each child of the framelayout, add a new TabSpec
-            for (int i = 0 ; i < count ; i++) {
-                View child = content.getChildAt(i);
-                String tabSpec = String.format("tab_spec%d", i+1);
-                int id = child.getId();
-                Pair<ResourceType, String> resource = projectCallback.resolveResourceId(id);
-                String name;
-                if (resource != null) {
-                    name = resource.getSecond();
-                } else {
-                    name = String.format("Tab %d", i+1); // default name if id is unresolved.
-                }
-                tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
-            }
-        }
-    }
-
-    private List<ViewInfo> startVisitingViews(View view, int offset, boolean setExtendedInfo) {
-        if (view == null) {
-            return null;
-        }
-
-        // adjust the offset to this view.
-        offset += view.getTop();
-
-        if (view == mContentRoot) {
-            return visitAllChildren(mContentRoot, offset, setExtendedInfo);
-        }
-
-        // otherwise, look for mContentRoot in the children
-        if (view instanceof ViewGroup) {
-            ViewGroup group = ((ViewGroup) view);
-
-            for (int i = 0; i < group.getChildCount(); i++) {
-                List<ViewInfo> list = startVisitingViews(group.getChildAt(i), offset,
-                        setExtendedInfo);
-                if (list != null) {
-                    return list;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Visits a View and its children and generate a {@link ViewInfo} containing the
-     * bounds of all the views.
-     * @param view the root View
-     * @param offset an offset for the view bounds.
-     * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object.
-     */
-    private ViewInfo visit(View view, int offset, boolean setExtendedInfo) {
-        if (view == null) {
-            return null;
-        }
-
-        ViewInfo result = new ViewInfo(view.getClass().getName(),
-                getContext().getViewKey(view),
-                view.getLeft(), view.getTop() + offset, view.getRight(), view.getBottom() + offset,
-                view, view.getLayoutParams());
-
-        if (setExtendedInfo) {
-            MarginLayoutParams marginParams = null;
-            LayoutParams params = view.getLayoutParams();
-            if (params instanceof MarginLayoutParams) {
-                marginParams = (MarginLayoutParams) params;
-            }
-            result.setExtendedInfo(view.getBaseline(),
-                    marginParams != null ? marginParams.leftMargin : 0,
-                    marginParams != null ? marginParams.topMargin : 0,
-                    marginParams != null ? marginParams.rightMargin : 0,
-                    marginParams != null ? marginParams.bottomMargin : 0);
-        }
-
-        if (view instanceof ViewGroup) {
-            ViewGroup group = ((ViewGroup) view);
-            result.setChildren(visitAllChildren(group, 0 /*offset*/, setExtendedInfo));
-        }
-
-        return result;
-    }
-
-    /**
-     * Visits all the children of a given ViewGroup generate a list of {@link ViewInfo}
-     * containing the bounds of all the views.
-     * @param view the root View
-     * @param offset an offset for the view bounds.
-     * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object.
-     */
-    private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int offset,
-            boolean setExtendedInfo) {
-        if (viewGroup == null) {
-            return null;
-        }
-
-        List<ViewInfo> children = new ArrayList<ViewInfo>();
-        for (int i = 0; i < viewGroup.getChildCount(); i++) {
-            children.add(visit(viewGroup.getChildAt(i), offset, setExtendedInfo));
-        }
-        return children;
-    }
-
-
-    private void invalidateRenderingSize() {
-        mMeasuredScreenWidth = mMeasuredScreenHeight = -1;
-    }
-
-    public BufferedImage getImage() {
-        return mImage;
-    }
-
-    public boolean isAlphaChannelImage() {
-        return mIsAlphaChannelImage;
-    }
-
-    public List<ViewInfo> getViewInfos() {
-        return mViewInfoList;
-    }
-
-    public Map<String, String> getDefaultProperties(Object viewObject) {
-        return getContext().getDefaultPropMap(viewObject);
-    }
-
-    public void setScene(RenderSession session) {
-        mScene = session;
-    }
-
-    public RenderSession getSession() {
-        return mScene;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
deleted file mode 100644
index 6dcb693..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ /dev/null
@@ -1,493 +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 com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.DensityBasedResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.ninepatch.NinePatch;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.resources.Density;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.res.ColorStateList;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.NinePatch_Delegate;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.NinePatchDrawable;
-import android.util.TypedValue;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Helper class to provide various conversion method used in handling android resources.
- */
-public final class ResourceHelper {
-
-    private final static Pattern sFloatPattern = Pattern.compile("(-?[0-9]+(?:\\.[0-9]+)?)(.*)");
-    private final static float[] sFloatOut = new float[1];
-
-    private final static TypedValue mValue = new TypedValue();
-
-    /**
-     * Returns the color value represented by the given string value
-     * @param value the color value
-     * @return the color as an int
-     * @throw NumberFormatException if the conversion failed.
-     */
-    public static int getColor(String value) {
-        if (value != null) {
-            if (value.startsWith("#") == false) {
-                throw new NumberFormatException(
-                        String.format("Color value '%s' must start with #", value));
-            }
-
-            value = value.substring(1);
-
-            // make sure it's not longer than 32bit
-            if (value.length() > 8) {
-                throw new NumberFormatException(String.format(
-                        "Color value '%s' is too long. Format is either" +
-                        "#AARRGGBB, #RRGGBB, #RGB, or #ARGB",
-                        value));
-            }
-
-            if (value.length() == 3) { // RGB format
-                char[] color = new char[8];
-                color[0] = color[1] = 'F';
-                color[2] = color[3] = value.charAt(0);
-                color[4] = color[5] = value.charAt(1);
-                color[6] = color[7] = value.charAt(2);
-                value = new String(color);
-            } else if (value.length() == 4) { // ARGB format
-                char[] color = new char[8];
-                color[0] = color[1] = value.charAt(0);
-                color[2] = color[3] = value.charAt(1);
-                color[4] = color[5] = value.charAt(2);
-                color[6] = color[7] = value.charAt(3);
-                value = new String(color);
-            } else if (value.length() == 6) {
-                value = "FF" + value;
-            }
-
-            // this is a RRGGBB or AARRGGBB value
-
-            // Integer.parseInt will fail to parse strings like "ff191919", so we use
-            // a Long, but cast the result back into an int, since we know that we're only
-            // dealing with 32 bit values.
-            return (int)Long.parseLong(value, 16);
-        }
-
-        throw new NumberFormatException();
-    }
-
-    public static ColorStateList getColorStateList(ResourceValue resValue, BridgeContext context) {
-        String value = resValue.getValue();
-        if (value != null && RenderResources.REFERENCE_NULL.equals(value) == false) {
-            // first check if the value is a file (xml most likely)
-            File f = new File(value);
-            if (f.isFile()) {
-                try {
-                    // let the framework inflate the ColorStateList from the XML file, by
-                    // providing an XmlPullParser
-                    XmlPullParser parser = ParserFactory.create(f);
-
-                    BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                            parser, context, resValue.isFramework());
-                    try {
-                        return ColorStateList.createFromXml(context.getResources(), blockParser);
-                    } finally {
-                        blockParser.ensurePopped();
-                    }
-                } catch (XmlPullParserException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                            "Failed to configure parser for " + value, e, null /*data*/);
-                    // we'll return null below.
-                } catch (Exception e) {
-                    // this is an error and not warning since the file existence is
-                    // checked before attempting to parse it.
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                            "Failed to parse file " + value, e, null /*data*/);
-
-                    return null;
-                }
-            } else {
-                // try to load the color state list from an int
-                try {
-                    int color = ResourceHelper.getColor(value);
-                    return ColorStateList.valueOf(color);
-                } catch (NumberFormatException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                            "Failed to convert " + value + " into a ColorStateList", e,
-                            null /*data*/);
-                    return null;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a drawable from the given value.
-     * @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
-     * or an hexadecimal color
-     * @param context the current context
-     */
-    public static Drawable getDrawable(ResourceValue value, BridgeContext context) {
-        String stringValue = value.getValue();
-        if (RenderResources.REFERENCE_NULL.equals(stringValue)) {
-            return null;
-        }
-
-        String lowerCaseValue = stringValue.toLowerCase();
-
-        Density density = Density.MEDIUM;
-        if (value instanceof DensityBasedResourceValue) {
-            density =
-                ((DensityBasedResourceValue)value).getResourceDensity();
-        }
-
-
-        if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) {
-            File file = new File(stringValue);
-            if (file.isFile()) {
-                try {
-                    return getNinePatchDrawable(
-                            new FileInputStream(file), density, value.isFramework(),
-                            stringValue, context);
-                } catch (IOException e) {
-                    // failed to read the file, we'll return null below.
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                            "Failed lot load " + file.getAbsolutePath(), e, null /*data*/);
-                }
-            }
-
-            return null;
-        } else if (lowerCaseValue.endsWith(".xml")) {
-            // create a block parser for the file
-            File f = new File(stringValue);
-            if (f.isFile()) {
-                try {
-                    // let the framework inflate the Drawable from the XML file.
-                    XmlPullParser parser = ParserFactory.create(f);
-
-                    BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                            parser, context, value.isFramework());
-                    try {
-                        return Drawable.createFromXml(context.getResources(), blockParser);
-                    } finally {
-                        blockParser.ensurePopped();
-                    }
-                } catch (Exception e) {
-                    // this is an error and not warning since the file existence is checked before
-                    // attempting to parse it.
-                    Bridge.getLog().error(null, "Failed to parse file " + stringValue,
-                            e, null /*data*/);
-                }
-            } else {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        String.format("File %s does not exist (or is not a file)", stringValue),
-                        null /*data*/);
-            }
-
-            return null;
-        } else {
-            File bmpFile = new File(stringValue);
-            if (bmpFile.isFile()) {
-                try {
-                    Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
-                            value.isFramework() ? null : context.getProjectKey());
-
-                    if (bitmap == null) {
-                        bitmap = Bitmap_Delegate.createBitmap(bmpFile, false /*isMutable*/,
-                                density);
-                        Bridge.setCachedBitmap(stringValue, bitmap,
-                                value.isFramework() ? null : context.getProjectKey());
-                    }
-
-                    return new BitmapDrawable(context.getResources(), bitmap);
-                } catch (IOException e) {
-                    // we'll return null below
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                            "Failed lot load " + bmpFile.getAbsolutePath(), e, null /*data*/);
-                }
-            } else {
-                // attempt to get a color from the value
-                try {
-                    int color = getColor(stringValue);
-                    return new ColorDrawable(color);
-                } catch (NumberFormatException e) {
-                    // we'll return null below.
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                            "Failed to convert " + stringValue + " into a drawable", e,
-                            null /*data*/);
-                }
-            }
-        }
-
-        return null;
-    }
-
-    private static Drawable getNinePatchDrawable(InputStream inputStream, Density density,
-            boolean isFramework, String cacheKey, BridgeContext context) throws IOException {
-        // see if we still have both the chunk and the bitmap in the caches
-        NinePatchChunk chunk = Bridge.getCached9Patch(cacheKey,
-                isFramework ? null : context.getProjectKey());
-        Bitmap bitmap = Bridge.getCachedBitmap(cacheKey,
-                isFramework ? null : context.getProjectKey());
-
-        // if either chunk or bitmap is null, then we reload the 9-patch file.
-        if (chunk == null || bitmap == null) {
-            try {
-                NinePatch ninePatch = NinePatch.load(inputStream, true /*is9Patch*/,
-                        false /* convert */);
-                if (ninePatch != null) {
-                    if (chunk == null) {
-                        chunk = ninePatch.getChunk();
-
-                        Bridge.setCached9Patch(cacheKey, chunk,
-                                isFramework ? null : context.getProjectKey());
-                    }
-
-                    if (bitmap == null) {
-                        bitmap = Bitmap_Delegate.createBitmap(ninePatch.getImage(),
-                                false /*isMutable*/,
-                                density);
-
-                        Bridge.setCachedBitmap(cacheKey, bitmap,
-                                isFramework ? null : context.getProjectKey());
-                    }
-                }
-            } catch (MalformedURLException e) {
-                // URL is wrong, we'll return null below
-            }
-        }
-
-        if (chunk != null && bitmap != null) {
-            int[] padding = chunk.getPadding();
-            Rect paddingRect = new Rect(padding[0], padding[1], padding[2], padding[3]);
-
-            return new NinePatchDrawable(context.getResources(), bitmap,
-                    NinePatch_Delegate.serialize(chunk),
-                    paddingRect, null);
-        }
-
-        return null;
-    }
-
-    // ------- TypedValue stuff
-    // This is taken from //device/libs/utils/ResourceTypes.cpp
-
-    private static final class UnitEntry {
-        String name;
-        int type;
-        int unit;
-        float scale;
-
-        UnitEntry(String name, int type, int unit, float scale) {
-            this.name = name;
-            this.type = type;
-            this.unit = unit;
-            this.scale = scale;
-        }
-    }
-
-    private final static UnitEntry[] sUnitNames = new UnitEntry[] {
-        new UnitEntry("px", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PX, 1.0f),
-        new UnitEntry("dip", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f),
-        new UnitEntry("dp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f),
-        new UnitEntry("sp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_SP, 1.0f),
-        new UnitEntry("pt", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PT, 1.0f),
-        new UnitEntry("in", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_IN, 1.0f),
-        new UnitEntry("mm", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_MM, 1.0f),
-        new UnitEntry("%", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION, 1.0f/100),
-        new UnitEntry("%p", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100),
-    };
-
-    /**
-     * Returns the raw value from the given attribute float-type value string.
-     * This object is only valid until the next call on to {@link ResourceHelper}.
-     */
-    public static TypedValue getValue(String attribute, String value, boolean requireUnit) {
-        if (parseFloatAttribute(attribute, value, mValue, requireUnit)) {
-            return mValue;
-        }
-
-        return null;
-    }
-
-    /**
-     * Parse a float attribute and return the parsed value into a given TypedValue.
-     * @param attribute the name of the attribute. Can be null if <var>requireUnit</var> is false.
-     * @param value the string value of the attribute
-     * @param outValue the TypedValue to receive the parsed value
-     * @param requireUnit whether the value is expected to contain a unit.
-     * @return true if success.
-     */
-    public static boolean parseFloatAttribute(String attribute, String value,
-            TypedValue outValue, boolean requireUnit) {
-        assert requireUnit == false || attribute != null;
-
-        // remove the space before and after
-        value = value.trim();
-        int len = value.length();
-
-        if (len <= 0) {
-            return false;
-        }
-
-        // check that there's no non ascii characters.
-        char[] buf = value.toCharArray();
-        for (int i = 0 ; i < len ; i++) {
-            if (buf[i] > 255) {
-                return false;
-            }
-        }
-
-        // check the first character
-        if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.' && buf[0] != '-') {
-            return false;
-        }
-
-        // now look for the string that is after the float...
-        Matcher m = sFloatPattern.matcher(value);
-        if (m.matches()) {
-            String f_str = m.group(1);
-            String end = m.group(2);
-
-            float f;
-            try {
-                f = Float.parseFloat(f_str);
-            } catch (NumberFormatException e) {
-                // this shouldn't happen with the regexp above.
-                return false;
-            }
-
-            if (end.length() > 0 && end.charAt(0) != ' ') {
-                // Might be a unit...
-                if (parseUnit(end, outValue, sFloatOut)) {
-                    computeTypedValue(outValue, f, sFloatOut[0]);
-                    return true;
-                }
-                return false;
-            }
-
-            // make sure it's only spaces at the end.
-            end = end.trim();
-
-            if (end.length() == 0) {
-                if (outValue != null) {
-                    if (requireUnit == false) {
-                        outValue.type = TypedValue.TYPE_FLOAT;
-                        outValue.data = Float.floatToIntBits(f);
-                    } else {
-                        // no unit when required? Use dp and out an error.
-                        applyUnit(sUnitNames[1], outValue, sFloatOut);
-                        computeTypedValue(outValue, f, sFloatOut[0]);
-
-                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                                String.format(
-                                        "Dimension \"%1$s\" in attribute \"%2$s\" is missing unit!",
-                                        value, attribute),
-                                null);
-                    }
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private static void computeTypedValue(TypedValue outValue, float value, float scale) {
-        value *= scale;
-        boolean neg = value < 0;
-        if (neg) {
-            value = -value;
-        }
-        long bits = (long)(value*(1<<23)+.5f);
-        int radix;
-        int shift;
-        if ((bits&0x7fffff) == 0) {
-            // Always use 23p0 if there is no fraction, just to make
-            // things easier to read.
-            radix = TypedValue.COMPLEX_RADIX_23p0;
-            shift = 23;
-        } else if ((bits&0xffffffffff800000L) == 0) {
-            // Magnitude is zero -- can fit in 0 bits of precision.
-            radix = TypedValue.COMPLEX_RADIX_0p23;
-            shift = 0;
-        } else if ((bits&0xffffffff80000000L) == 0) {
-            // Magnitude can fit in 8 bits of precision.
-            radix = TypedValue.COMPLEX_RADIX_8p15;
-            shift = 8;
-        } else if ((bits&0xffffff8000000000L) == 0) {
-            // Magnitude can fit in 16 bits of precision.
-            radix = TypedValue.COMPLEX_RADIX_16p7;
-            shift = 16;
-        } else {
-            // Magnitude needs entire range, so no fractional part.
-            radix = TypedValue.COMPLEX_RADIX_23p0;
-            shift = 23;
-        }
-        int mantissa = (int)(
-            (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK);
-        if (neg) {
-            mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK;
-        }
-        outValue.data |=
-            (radix<<TypedValue.COMPLEX_RADIX_SHIFT)
-            | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT);
-    }
-
-    private static boolean parseUnit(String str, TypedValue outValue, float[] outScale) {
-        str = str.trim();
-
-        for (UnitEntry unit : sUnitNames) {
-            if (unit.name.equals(str)) {
-                applyUnit(unit, outValue, outScale);
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static void applyUnit(UnitEntry unit, TypedValue outValue, float[] outScale) {
-        outValue.type = unit.type;
-        outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT;
-        outScale[0] = unit.scale;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java
deleted file mode 100644
index 9bd0015..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import java.util.ArrayList;
-
-/**
- * Custom Stack implementation on top of an {@link ArrayList} instead of
- * using {@link java.util.Stack} which is on top of a vector.
- *
- * @param <T>
- */
-public class Stack<T> extends ArrayList<T> {
-
-    private static final long serialVersionUID = 1L;
-
-    public Stack() {
-        super();
-    }
-
-    public Stack(int size) {
-        super(size);
-    }
-
-    /**
-     * Pushes the given object to the stack
-     * @param object the object to push
-     */
-    public void push(T object) {
-        add(object);
-    }
-
-    /**
-     * Remove the object at the top of the stack and returns it.
-     * @return the removed object or null if the stack was empty.
-     */
-    public T pop() {
-        if (size() > 0) {
-            return remove(size() - 1);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the object at the top of the stack.
-     * @return the object at the top or null if the stack is empty.
-     */
-    public T peek() {
-        if (size() > 0) {
-            return get(size() - 1);
-        }
-
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
deleted file mode 100644
index 6c998af..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
+++ /dev/null
@@ -1,148 +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.layoutlib.bridge.impl.binding;
-
-import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.IProjectCallback;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.IProjectCallback.ViewAttribute;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.util.Pair;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.Checkable;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-/**
- * A Helper class to do fake data binding in {@link AdapterView} objects.
- */
-@SuppressWarnings("deprecation")
-public class AdapterHelper {
-
-    static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent,
-            IProjectCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
-        // we don't care about recycling here because we never scroll.
-        DataBindingItem dataBindingItem = item.getDataBindingItem();
-
-        BridgeContext context = RenderAction.getCurrentContext();
-
-        Pair<View, Boolean> pair = context.inflateView(dataBindingItem.getViewReference(),
-                parent, false /*attachToRoot*/, skipCallbackParser);
-
-        View view = pair.getFirst();
-        skipCallbackParser |= pair.getSecond();
-
-        if (view != null) {
-            fillView(context, view, item, parentItem, callback, adapterRef);
-        } else {
-            // create a text view to display an error.
-            TextView tv = new TextView(context);
-            tv.setText("Unable to find layout: " + dataBindingItem.getViewReference().getName());
-            view = tv;
-        }
-
-        return Pair.of(view, skipCallbackParser);
-    }
-
-    private static void fillView(BridgeContext context, View view, AdapterItem item,
-            AdapterItem parentItem, IProjectCallback callback, ResourceReference adapterRef) {
-        if (view instanceof ViewGroup) {
-            ViewGroup group = (ViewGroup) view;
-            final int count = group.getChildCount();
-            for (int i = 0 ; i < count ; i++) {
-                fillView(context, group.getChildAt(i), item, parentItem, callback, adapterRef);
-            }
-        } else {
-            int id = view.getId();
-            if (id != 0) {
-                ResourceReference resolvedRef = context.resolveId(id);
-                if (resolvedRef != null) {
-                    int fullPosition = item.getFullPosition();
-                    int positionPerType = item.getPositionPerType();
-                    int fullParentPosition = parentItem != null ? parentItem.getFullPosition() : 0;
-                    int parentPositionPerType = parentItem != null ?
-                            parentItem.getPositionPerType() : 0;
-
-                    if (view instanceof TextView) {
-                        TextView tv = (TextView) view;
-                        Object value = callback.getAdapterItemValue(
-                                adapterRef, context.getViewKey(view),
-                                item.getDataBindingItem().getViewReference(),
-                                fullPosition, positionPerType,
-                                fullParentPosition, parentPositionPerType,
-                                resolvedRef, ViewAttribute.TEXT, tv.getText().toString());
-                        if (value != null) {
-                            if (value.getClass() != ViewAttribute.TEXT.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for TEXT. Expected String, got %s",
-                                        value.getClass().getName()), null);
-                            } else {
-                                tv.setText((String) value);
-                            }
-                        }
-                    }
-
-                    if (view instanceof Checkable) {
-                        Checkable cb = (Checkable) view;
-
-                        Object value = callback.getAdapterItemValue(
-                                adapterRef, context.getViewKey(view),
-                                item.getDataBindingItem().getViewReference(),
-                                fullPosition, positionPerType,
-                                fullParentPosition, parentPositionPerType,
-                                resolvedRef, ViewAttribute.IS_CHECKED, cb.isChecked());
-                        if (value != null) {
-                            if (value.getClass() != ViewAttribute.IS_CHECKED.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for TEXT. Expected Boolean, got %s",
-                                        value.getClass().getName()), null);
-                            } else {
-                                cb.setChecked((Boolean) value);
-                            }
-                        }
-                    }
-
-                    if (view instanceof ImageView) {
-                        ImageView iv = (ImageView) view;
-
-                        Object value = callback.getAdapterItemValue(
-                                adapterRef, context.getViewKey(view),
-                                item.getDataBindingItem().getViewReference(),
-                                fullPosition, positionPerType,
-                                fullParentPosition, parentPositionPerType,
-                                resolvedRef, ViewAttribute.SRC, iv.getDrawable());
-                        if (value != null) {
-                            if (value.getClass() != ViewAttribute.SRC.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for TEXT. Expected Boolean, got %s",
-                                        value.getClass().getName()), null);
-                            } else {
-                                // FIXME
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java
deleted file mode 100644
index 8e28dba..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl.binding;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import com.android.ide.common.rendering.api.DataBindingItem;
-
-/**
- * This is the items provided by the adapter. They are dynamically generated.
- */
-final class AdapterItem {
-    private final DataBindingItem mItem;
-    private final int mType;
-    private final int mFullPosition;
-    private final int mPositionPerType;
-    private List<AdapterItem> mChildren;
-
-    protected AdapterItem(DataBindingItem item, int type, int fullPosition,
-            int positionPerType) {
-        mItem = item;
-        mType = type;
-        mFullPosition = fullPosition;
-        mPositionPerType = positionPerType;
-    }
-
-    void addChild(AdapterItem child) {
-        if (mChildren == null) {
-            mChildren = new ArrayList<AdapterItem>();
-        }
-
-        mChildren.add(child);
-    }
-
-    List<AdapterItem> getChildren() {
-        if (mChildren != null) {
-            return mChildren;
-        }
-
-        return Collections.emptyList();
-    }
-
-    int getType() {
-        return mType;
-    }
-
-    int getFullPosition() {
-        return mFullPosition;
-    }
-
-    int getPositionPerType() {
-        return mPositionPerType;
-    }
-
-    DataBindingItem getDataBindingItem() {
-        return mItem;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
deleted file mode 100644
index 9a13f5a..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
+++ /dev/null
@@ -1,133 +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.layoutlib.bridge.impl.binding;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.IProjectCallback;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.util.Pair;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.ListAdapter;
-import android.widget.SpinnerAdapter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Fake adapter to do fake data binding in {@link AdapterView} objects for {@link ListAdapter}
- * and {@link SpinnerAdapter}.
- *
- */
-@SuppressWarnings("deprecation")
-public class FakeAdapter extends BaseAdapter {
-
-    // don't use a set because the order is important.
-    private final List<ResourceReference> mTypes = new ArrayList<ResourceReference>();
-    private final IProjectCallback mCallback;
-    private final ResourceReference mAdapterRef;
-    private final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
-    private boolean mSkipCallbackParser = false;
-
-    public FakeAdapter(ResourceReference adapterRef, AdapterBinding binding,
-            IProjectCallback callback) {
-        mAdapterRef = adapterRef;
-        mCallback = callback;
-
-        final int repeatCount = binding.getRepeatCount();
-        final int itemCount = binding.getItemCount();
-
-        // Need an array to count for each type.
-        // This is likely too big, but is the max it can be.
-        int[] typeCount = new int[itemCount];
-
-        // We put several repeating sets.
-        for (int r = 0 ; r < repeatCount ; r++) {
-            // loop on the type of list items, and add however many for each type.
-            for (DataBindingItem dataBindingItem : binding) {
-                ResourceReference viewRef = dataBindingItem.getViewReference();
-                int typeIndex = mTypes.indexOf(viewRef);
-                if (typeIndex == -1) {
-                    typeIndex = mTypes.size();
-                    mTypes.add(viewRef);
-                }
-
-                int count = dataBindingItem.getCount();
-
-                int index = typeCount[typeIndex];
-                typeCount[typeIndex] += count;
-
-                for (int k = 0 ; k < count ; k++) {
-                    mItems.add(new AdapterItem(dataBindingItem, typeIndex, mItems.size(), index++));
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean isEnabled(int position) {
-        return true;
-    }
-
-    @Override
-    public int getCount() {
-        return mItems.size();
-    }
-
-    @Override
-    public Object getItem(int position) {
-        return mItems.get(position);
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return position;
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        return mItems.get(position).getType();
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        // we don't care about recycling here because we never scroll.
-        AdapterItem item = mItems.get(position);
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentGroup*/, parent,
-                mCallback, mAdapterRef, mSkipCallbackParser);
-        mSkipCallbackParser = pair.getSecond();
-        return pair.getFirst();
-
-    }
-
-    @Override
-    public int getViewTypeCount() {
-        return mTypes.size();
-    }
-
-    // ---- SpinnerAdapter
-
-    @Override
-    public View getDropDownView(int position, View convertView, ViewGroup parent) {
-        // pass
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
deleted file mode 100644
index e539579..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
+++ /dev/null
@@ -1,236 +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.layoutlib.bridge.impl.binding;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.IProjectCallback;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.util.Pair;
-
-import android.database.DataSetObserver;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ExpandableListAdapter;
-import android.widget.HeterogeneousExpandableList;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@SuppressWarnings("deprecation")
-public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList {
-
-    private final IProjectCallback mCallback;
-    private final ResourceReference mAdapterRef;
-    private boolean mSkipCallbackParser = false;
-
-    protected final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
-
-    // don't use a set because the order is important.
-    private final List<ResourceReference> mGroupTypes = new ArrayList<ResourceReference>();
-    private final List<ResourceReference> mChildrenTypes = new ArrayList<ResourceReference>();
-
-    public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding,
-            IProjectCallback callback) {
-        mAdapterRef = adapterRef;
-        mCallback = callback;
-
-        createItems(binding, binding.getItemCount(), binding.getRepeatCount(), mGroupTypes, 1);
-    }
-
-    private void createItems(Iterable<DataBindingItem> iterable, final int itemCount,
-            final int repeatCount, List<ResourceReference> types, int depth) {
-        // Need an array to count for each type.
-        // This is likely too big, but is the max it can be.
-        int[] typeCount = new int[itemCount];
-
-        // we put several repeating sets.
-        for (int r = 0 ; r < repeatCount ; r++) {
-            // loop on the type of list items, and add however many for each type.
-            for (DataBindingItem dataBindingItem : iterable) {
-                ResourceReference viewRef = dataBindingItem.getViewReference();
-                int typeIndex = types.indexOf(viewRef);
-                if (typeIndex == -1) {
-                    typeIndex = types.size();
-                    types.add(viewRef);
-                }
-
-                List<DataBindingItem> children = dataBindingItem.getChildren();
-                int count = dataBindingItem.getCount();
-
-                // if there are children, we use the count as a repeat count for the children.
-                if (children.size() > 0) {
-                    count = 1;
-                }
-
-                int index = typeCount[typeIndex];
-                typeCount[typeIndex] += count;
-
-                for (int k = 0 ; k < count ; k++) {
-                    AdapterItem item = new AdapterItem(dataBindingItem, typeIndex, mItems.size(),
-                            index++);
-                    mItems.add(item);
-
-                    if (children.size() > 0) {
-                        createItems(dataBindingItem, depth + 1);
-                    }
-                }
-            }
-        }
-    }
-
-    private void createItems(DataBindingItem item, int depth) {
-        if (depth == 2) {
-            createItems(item, item.getChildren().size(), item.getCount(), mChildrenTypes, depth);
-        }
-    }
-
-    private AdapterItem getChildItem(int groupPosition, int childPosition) {
-        AdapterItem item = mItems.get(groupPosition);
-
-        List<AdapterItem> children = item.getChildren();
-        return children.get(childPosition);
-    }
-
-    // ---- ExpandableListAdapter
-
-    @Override
-    public int getGroupCount() {
-        return mItems.size();
-    }
-
-    @Override
-    public int getChildrenCount(int groupPosition) {
-        AdapterItem item = mItems.get(groupPosition);
-        return item.getChildren().size();
-    }
-
-    @Override
-    public Object getGroup(int groupPosition) {
-        return mItems.get(groupPosition);
-    }
-
-    @Override
-    public Object getChild(int groupPosition, int childPosition) {
-        return getChildItem(groupPosition, childPosition);
-    }
-
-    @Override
-    public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
-            ViewGroup parent) {
-        // we don't care about recycling here because we never scroll.
-        AdapterItem item = mItems.get(groupPosition);
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentItem*/, parent,
-                mCallback, mAdapterRef, mSkipCallbackParser);
-        mSkipCallbackParser = pair.getSecond();
-        return pair.getFirst();
-    }
-
-    @Override
-    public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
-            View convertView, ViewGroup parent) {
-        // we don't care about recycling here because we never scroll.
-        AdapterItem parentItem = mItems.get(groupPosition);
-        AdapterItem item = getChildItem(groupPosition, childPosition);
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, parentItem, parent, mCallback,
-                mAdapterRef, mSkipCallbackParser);
-        mSkipCallbackParser = pair.getSecond();
-        return pair.getFirst();
-    }
-
-    @Override
-    public long getGroupId(int groupPosition) {
-        return groupPosition;
-    }
-
-    @Override
-    public long getChildId(int groupPosition, int childPosition) {
-        return childPosition;
-    }
-
-    @Override
-    public long getCombinedGroupId(long groupId) {
-        return groupId << 16 | 0x0000FFFF;
-    }
-
-    @Override
-    public long getCombinedChildId(long groupId, long childId) {
-        return groupId << 16 | childId;
-    }
-
-    @Override
-    public boolean isChildSelectable(int groupPosition, int childPosition) {
-        return true;
-    }
-
-    @Override
-    public void onGroupCollapsed(int groupPosition) {
-        // pass
-    }
-
-    @Override
-    public void onGroupExpanded(int groupPosition) {
-        // pass
-    }
-
-    @Override
-    public void registerDataSetObserver(DataSetObserver observer) {
-        // pass
-    }
-
-    @Override
-    public void unregisterDataSetObserver(DataSetObserver observer) {
-        // pass
-    }
-
-    @Override
-    public boolean hasStableIds() {
-        return true;
-    }
-
-    @Override
-    public boolean areAllItemsEnabled() {
-        return true;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return mItems.isEmpty();
-    }
-
-    // ---- HeterogeneousExpandableList
-
-    @Override
-    public int getChildType(int groupPosition, int childPosition) {
-        return getChildItem(groupPosition, childPosition).getType();
-    }
-
-    @Override
-    public int getChildTypeCount() {
-        return mChildrenTypes.size();
-    }
-
-    @Override
-    public int getGroupType(int groupPosition) {
-        return mItems.get(groupPosition).getType();
-    }
-
-    @Override
-    public int getGroupTypeCount() {
-        return mGroupTypes.size();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java
deleted file mode 100644
index 82eab85..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java
+++ /dev/null
@@ -1,23 +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.layoutlib.bridge.util;
-
-public class Debug {
-
-    public final static boolean DEBUG = false;
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
deleted file mode 100644
index a1fae95..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
+++ /dev/null
@@ -1,76 +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.layoutlib.bridge.util;
-
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-
-import android.util.SparseArray;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class DynamicIdMap {
-
-    private final Map<Pair<ResourceType, String>, Integer> mDynamicIds = new HashMap<Pair<ResourceType, String>, Integer>();
-    private final SparseArray<Pair<ResourceType, String>> mRevDynamicIds = new SparseArray<Pair<ResourceType, String>>();
-    private int mDynamicSeed;
-
-    public DynamicIdMap(int seed) {
-        mDynamicSeed = seed;
-    }
-
-    public void reset(int seed) {
-        mDynamicIds.clear();
-        mRevDynamicIds.clear();
-        mDynamicSeed = seed;
-    }
-
-    /**
-     * Returns a dynamic integer for the given resource type/name, creating it if it doesn't
-     * already exist.
-     *
-     * @param type the type of the resource
-     * @param name the name of the resource
-     * @return an integer.
-     */
-    public Integer getId(ResourceType type, String name) {
-        return getId(Pair.of(type, name));
-    }
-
-    /**
-     * Returns a dynamic integer for the given resource type/name, creating it if it doesn't
-     * already exist.
-     *
-     * @param resource the type/name of the resource
-     * @return an integer.
-     */
-    public Integer getId(Pair<ResourceType, String> resource) {
-        Integer value = mDynamicIds.get(resource);
-        if (value == null) {
-            value = Integer.valueOf(++mDynamicSeed);
-            mDynamicIds.put(resource, value);
-            mRevDynamicIds.put(value, resource);
-        }
-
-        return value;
-    }
-
-    public Pair<ResourceType, String> resolveId(int id) {
-        return mRevDynamicIds.get(id);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
deleted file mode 100644
index 4d0c9ce..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
+++ /dev/null
@@ -1,376 +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.layoutlib.bridge.util;
-
-
-import com.android.internal.util.ArrayUtils;
-
-import android.util.SparseArray;
-
-import java.lang.ref.WeakReference;
-
-/**
- * This is a custom {@link SparseArray} that uses {@link WeakReference} around the objects added
- * to it. When the array is compacted, not only deleted indices but also empty references
- * are removed, making the array efficient at removing references that were reclaimed.
- *
- * The code is taken from {@link SparseArray} directly and adapted to use weak references.
- *
- * Because our usage means that we never actually call {@link #remove(int)} or {@link #delete(int)},
- * we must manually check if there are reclaimed references to trigger an internal compact step
- * (which is normally only triggered when an item is manually removed).
- *
- * SparseArrays map integers to Objects.  Unlike a normal array of Objects,
- * there can be gaps in the indices.  It is intended to be more efficient
- * than using a HashMap to map Integers to Objects.
- */
-@SuppressWarnings("unchecked")
-public class SparseWeakArray<E> {
-
-    private static final Object DELETED_REF = new Object();
-    private static final WeakReference<?> DELETED = new WeakReference(DELETED_REF);
-    private boolean mGarbage = false;
-
-    /**
-     * Creates a new SparseArray containing no mappings.
-     */
-    public SparseWeakArray() {
-        this(10);
-    }
-
-    /**
-     * Creates a new SparseArray containing no mappings that will not
-     * require any additional memory allocation to store the specified
-     * number of mappings.
-     */
-    public SparseWeakArray(int initialCapacity) {
-        initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
-
-        mKeys = new int[initialCapacity];
-        mValues = new WeakReference[initialCapacity];
-        mSize = 0;
-    }
-
-    /**
-     * Gets the Object mapped from the specified key, or <code>null</code>
-     * if no such mapping has been made.
-     */
-    public E get(int key) {
-        return get(key, null);
-    }
-
-    /**
-     * Gets the Object mapped from the specified key, or the specified Object
-     * if no such mapping has been made.
-     */
-    public E get(int key, E valueIfKeyNotFound) {
-        int i = binarySearch(mKeys, 0, mSize, key);
-
-        if (i < 0 || mValues[i] == DELETED || mValues[i].get() == null) {
-            return valueIfKeyNotFound;
-        } else {
-            return (E) mValues[i].get();
-        }
-    }
-
-    /**
-     * Removes the mapping from the specified key, if there was any.
-     */
-    public void delete(int key) {
-        int i = binarySearch(mKeys, 0, mSize, key);
-
-        if (i >= 0) {
-            if (mValues[i] != DELETED) {
-                mValues[i] = DELETED;
-                mGarbage = true;
-            }
-        }
-    }
-
-    /**
-     * Alias for {@link #delete(int)}.
-     */
-    public void remove(int key) {
-        delete(key);
-    }
-
-    /**
-     * Removes the mapping at the specified index.
-     */
-    public void removeAt(int index) {
-        if (mValues[index] != DELETED) {
-            mValues[index] = DELETED;
-            mGarbage = true;
-        }
-    }
-
-    private void gc() {
-        int n = mSize;
-        int o = 0;
-        int[] keys = mKeys;
-        WeakReference<?>[] values = mValues;
-
-        for (int i = 0; i < n; i++) {
-            WeakReference<?> val = values[i];
-
-            // Don't keep any non DELETED values, but only the one that still have a valid
-            // reference.
-            if (val != DELETED && val.get() != null) {
-                if (i != o) {
-                    keys[o] = keys[i];
-                    values[o] = val;
-                }
-
-                o++;
-            }
-        }
-
-        mGarbage = false;
-        mSize = o;
-
-        int newSize = ArrayUtils.idealIntArraySize(mSize);
-        if (newSize < mKeys.length) {
-            int[] nkeys = new int[newSize];
-            WeakReference<?>[] nvalues = new WeakReference[newSize];
-
-            System.arraycopy(mKeys, 0, nkeys, 0, newSize);
-            System.arraycopy(mValues, 0, nvalues, 0, newSize);
-
-            mKeys = nkeys;
-            mValues = nvalues;
-        }
-    }
-
-    /**
-     * Adds a mapping from the specified key to the specified value,
-     * replacing the previous mapping from the specified key if there
-     * was one.
-     */
-    public void put(int key, E value) {
-        int i = binarySearch(mKeys, 0, mSize, key);
-
-        if (i >= 0) {
-            mValues[i] = new WeakReference(value);
-        } else {
-            i = ~i;
-
-            if (i < mSize && (mValues[i] == DELETED || mValues[i].get() == null)) {
-                mKeys[i] = key;
-                mValues[i] = new WeakReference(value);
-                return;
-            }
-
-            if (mSize >= mKeys.length && (mGarbage || hasReclaimedRefs())) {
-                gc();
-
-                // Search again because indices may have changed.
-                i = ~binarySearch(mKeys, 0, mSize, key);
-            }
-
-            if (mSize >= mKeys.length) {
-                int n = ArrayUtils.idealIntArraySize(mSize + 1);
-
-                int[] nkeys = new int[n];
-                WeakReference<?>[] nvalues = new WeakReference[n];
-
-                // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
-                System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
-                System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
-                mKeys = nkeys;
-                mValues = nvalues;
-            }
-
-            if (mSize - i != 0) {
-                // Log.e("SparseArray", "move " + (mSize - i));
-                System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
-                System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
-            }
-
-            mKeys[i] = key;
-            mValues[i] = new WeakReference(value);
-            mSize++;
-        }
-    }
-
-    /**
-     * Returns the number of key-value mappings that this SparseArray
-     * currently stores.
-     */
-    public int size() {
-        if (mGarbage) {
-            gc();
-        }
-
-        return mSize;
-    }
-
-    /**
-     * Given an index in the range <code>0...size()-1</code>, returns
-     * the key from the <code>index</code>th key-value mapping that this
-     * SparseArray stores.
-     */
-    public int keyAt(int index) {
-        if (mGarbage) {
-            gc();
-        }
-
-        return mKeys[index];
-    }
-
-    /**
-     * Given an index in the range <code>0...size()-1</code>, returns
-     * the value from the <code>index</code>th key-value mapping that this
-     * SparseArray stores.
-     */
-    public E valueAt(int index) {
-        if (mGarbage) {
-            gc();
-        }
-
-        return (E) mValues[index].get();
-    }
-
-    /**
-     * Given an index in the range <code>0...size()-1</code>, sets a new
-     * value for the <code>index</code>th key-value mapping that this
-     * SparseArray stores.
-     */
-    public void setValueAt(int index, E value) {
-        if (mGarbage) {
-            gc();
-        }
-
-        mValues[index] = new WeakReference(value);
-    }
-
-    /**
-     * Returns the index for which {@link #keyAt} would return the
-     * specified key, or a negative number if the specified
-     * key is not mapped.
-     */
-    public int indexOfKey(int key) {
-        if (mGarbage) {
-            gc();
-        }
-
-        return binarySearch(mKeys, 0, mSize, key);
-    }
-
-    /**
-     * Returns an index for which {@link #valueAt} would return the
-     * specified key, or a negative number if no keys map to the
-     * specified value.
-     * Beware that this is a linear search, unlike lookups by key,
-     * and that multiple keys can map to the same value and this will
-     * find only one of them.
-     */
-    public int indexOfValue(E value) {
-        if (mGarbage) {
-            gc();
-        }
-
-        for (int i = 0; i < mSize; i++)
-            if (mValues[i].get() == value)
-                return i;
-
-        return -1;
-    }
-
-    /**
-     * Removes all key-value mappings from this SparseArray.
-     */
-    public void clear() {
-        int n = mSize;
-        WeakReference<?>[] values = mValues;
-
-        for (int i = 0; i < n; i++) {
-            values[i] = null;
-        }
-
-        mSize = 0;
-        mGarbage = false;
-    }
-
-    /**
-     * Puts a key/value pair into the array, optimizing for the case where
-     * the key is greater than all existing keys in the array.
-     */
-    public void append(int key, E value) {
-        if (mSize != 0 && key <= mKeys[mSize - 1]) {
-            put(key, value);
-            return;
-        }
-
-        if (mSize >= mKeys.length && (mGarbage || hasReclaimedRefs())) {
-            gc();
-        }
-
-        int pos = mSize;
-        if (pos >= mKeys.length) {
-            int n = ArrayUtils.idealIntArraySize(pos + 1);
-
-            int[] nkeys = new int[n];
-            WeakReference<?>[] nvalues = new WeakReference[n];
-
-            // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
-            System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
-            System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
-            mKeys = nkeys;
-            mValues = nvalues;
-        }
-
-        mKeys[pos] = key;
-        mValues[pos] = new WeakReference(value);
-        mSize = pos + 1;
-    }
-
-    private boolean hasReclaimedRefs() {
-        for (int i = 0 ; i < mSize ; i++) {
-            if (mValues[i].get() == null) { // DELETED.get() never returns null.
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static int binarySearch(int[] a, int start, int len, int key) {
-        int high = start + len, low = start - 1, guess;
-
-        while (high - low > 1) {
-            guess = (high + low) / 2;
-
-            if (a[guess] < key)
-                low = guess;
-            else
-                high = guess;
-        }
-
-        if (high == start + len)
-            return ~(start + len);
-        else if (a[high] == key)
-            return high;
-        else
-            return ~high;
-    }
-
-    private int[] mKeys;
-    private WeakReference<?>[] mValues;
-    private int mSize;
-}
diff --git a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java b/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
deleted file mode 100644
index 6d013bb..0000000
--- a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
+++ /dev/null
@@ -1,121 +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 com.google.android.maps;
-
-import com.android.layoutlib.bridge.MockView;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * Mock version of the MapView.
- * Only non override public methods from the real MapView have been added in there.
- * Methods that take an unknown class as parameter or as return object, have been removed for now.
- * 
- * TODO: generate automatically.
- *
- */
-public class MapView extends MockView {
-
-    /**
-     * Construct a new WebView with a Context object.
-     * @param context A Context object used to access application assets.
-     */
-    public MapView(Context context) {
-        this(context, null);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     */
-    public MapView(Context context, AttributeSet attrs) {
-        this(context, attrs, com.android.internal.R.attr.mapViewStyle);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters and a default style.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     * @param defStyle The default style resource ID.
-     */
-    public MapView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-    
-    // START FAKE PUBLIC METHODS
-    
-    public void displayZoomControls(boolean takeFocus) {
-    }
-
-    public boolean canCoverCenter() {
-        return false;
-    }
-
-    public void preLoad() {
-    }
-
-    public int getZoomLevel() {
-        return 0;
-    }
-
-    public void setSatellite(boolean on) {
-    }
-
-    public boolean isSatellite() {
-        return false;
-    }
-
-    public void setTraffic(boolean on) {
-    }
-
-    public boolean isTraffic() {
-        return false;
-    }
-
-    public void setStreetView(boolean on) {
-    }
-
-    public boolean isStreetView() {
-        return false;
-    }
-
-    public int getLatitudeSpan() {
-        return 0;
-    }
-
-    public int getLongitudeSpan() {
-        return 0;
-    }
-
-    public int getMaxZoomLevel() {
-        return 0;
-    }
-
-    public void onSaveInstanceState(Bundle state) {
-    }
-
-    public void onRestoreInstanceState(Bundle state) {
-    }
-
-    public View getZoomControls() {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java
deleted file mode 100644
index a773d93..0000000
--- a/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java
+++ /dev/null
@@ -1,70 +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 libcore.icu;
-
-import java.text.FieldPosition;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.ibm.icu.text.DateIntervalFormat;
-import com.ibm.icu.util.DateInterval;
-import com.ibm.icu.util.TimeZone;
-import com.ibm.icu.util.ULocale;
-
-public class DateIntervalFormat_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<DateIntervalFormat_Delegate> sManager =
-            new DelegateManager<DateIntervalFormat_Delegate>(DateIntervalFormat_Delegate.class);
-
-    // ---- delegate data ----
-    private DateIntervalFormat mFormat;
-
-
-    // ---- native methods ----
-
-    /*package*/static String formatDateInterval(long address, long fromDate, long toDate) {
-        DateIntervalFormat_Delegate delegate = sManager.getDelegate((int)address);
-        if (delegate == null) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Unable for find native DateIntervalFormat", null);
-            return null;
-        }
-        DateInterval interval = new DateInterval(fromDate, toDate);
-        StringBuffer sb = new StringBuffer();
-        FieldPosition pos = new FieldPosition(0);
-        delegate.mFormat.format(interval, sb, pos);
-        return sb.toString();
-    }
-
-    /*package*/ static long createDateIntervalFormat(String skeleton, String localeName,
-            String tzName) {
-        TimeZone prevDefaultTz = TimeZone.getDefault();
-        TimeZone.setDefault(TimeZone.getTimeZone(tzName));
-        DateIntervalFormat_Delegate newDelegate = new DateIntervalFormat_Delegate();
-        newDelegate.mFormat =
-                DateIntervalFormat.getInstance(skeleton, new ULocale(localeName));
-        TimeZone.setDefault(prevDefaultTz);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    /*package*/ static void destroyDateIntervalFormat(long address) {
-        sManager.removeJavaReferenceFor((int)address);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
deleted file mode 100644
index ad4103b..0000000
--- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
+++ /dev/null
@@ -1,234 +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 libcore.icu;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.ibm.icu.text.DateTimePatternGenerator;
-import com.ibm.icu.util.ULocale;
-
-import java.util.Locale;
-
-/**
- * Delegate implementing the native methods of libcore.icu.ICU
- *
- * Through the layoutlib_create tool, the original native methods of ICU have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class ICU_Delegate {
-
-    // --- Java delegates
-
-    @LayoutlibDelegate
-    /*package*/ static String toLowerCase(String s, String localeName) {
-        return s.toLowerCase();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String toUpperCase(String s, String localeName) {
-        return s.toUpperCase();
-    }
-
-    // --- Native methods accessing ICU's database.
-
-    @LayoutlibDelegate
-    /*package*/ static String getBestDateTimePatternNative(String skeleton, String localeName) {
-        return DateTimePatternGenerator.getInstance(new ULocale(localeName))
-                .getBestPattern(skeleton);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCldrVersion() {
-        return "22.1.1";      // TODO: check what the right value should be.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getIcuVersion() {
-        return "unknown_layoutlib";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getUnicodeVersion() {
-        return "5.2";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableBreakIteratorLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableCalendarLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableCollatorLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableDateFormatLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableNumberFormatLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableCurrencyCodes() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCurrencyCode(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCurrencyDisplayName(String locale, String currencyCode) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getCurrencyFractionDigits(String currencyCode) {
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCurrencySymbol(String locale, String currencyCode) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayCountryNative(String countryCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayLanguageNative(String languageCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayVariantNative(String variantCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getISO3CountryNative(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getISO3LanguageNative(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String addLikelySubtags(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getScript(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getISOLanguagesNative() {
-        return Locale.getISOLanguages();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getISOCountriesNative() {
-        return Locale.getISOCountries();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean initLocaleDataNative(String locale, LocaleData result) {
-
-        // Used by Calendar.
-        result.firstDayOfWeek = Integer.valueOf(1);
-        result.minimalDaysInFirstWeek = Integer.valueOf(1);
-
-        // Used by DateFormatSymbols.
-        result.amPm = new String[] { "AM", "PM" };
-        result.eras = new String[] { "BC", "AD" };
-
-        result.longMonthNames = new String[] { "January", "February", "March", "April", "May",
-                "June", "July", "August", "September", "October", "November", "December" };
-        result.shortMonthNames = new String[] { "Jan", "Feb", "Mar", "Apr", "May",
-                "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-        result.longStandAloneMonthNames = result.longMonthNames;
-        result.shortStandAloneMonthNames = result.shortMonthNames;
-
-        // The platform code expects this to begin at index 1, rather than 0. It maps it directly to
-        // the constants from java.util.Calendar.<weekday>
-        result.longWeekdayNames = new String[] {
-                "", "Sunday", "Monday" ,"Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
-        result.shortWeekdayNames = new String[] {
-                "", "Sun", "Mon" ,"Tue", "Wed", "Thu", "Fri", "Sat" };
-        result.tinyWeekdayNames = new String[] {
-                "", "S", "M", "T", "W", "T", "F", "S" };
-
-        result.longStandAloneWeekdayNames = result.longWeekdayNames;
-        result.shortStandAloneWeekdayNames = result.shortWeekdayNames;
-        result.tinyStandAloneWeekdayNames = result.tinyWeekdayNames;
-
-        result.fullTimeFormat = "";
-        result.longTimeFormat = "";
-        result.mediumTimeFormat = "";
-        result.shortTimeFormat = "";
-
-        result.fullDateFormat = "";
-        result.longDateFormat = "";
-        result.mediumDateFormat = "";
-        result.shortDateFormat = "";
-
-        // Used by DecimalFormatSymbols.
-        result.zeroDigit = '0';
-        result.decimalSeparator = '.';
-        result.groupingSeparator = ',';
-        result.patternSeparator = ' ';
-        result.percent = '%';
-        result.perMill = '\u2030';
-        result.monetarySeparator = ' ';
-        result.minusSign = '-';
-        result.exponentSeparator = "e";
-        result.infinity = "\u221E";
-        result.NaN = "NaN";
-        // Also used by Currency.
-        result.currencySymbol = "$";
-        result.internationalCurrencySymbol = "USD";
-
-        // Used by DecimalFormat and NumberFormat.
-        result.numberPattern = "%f";
-        result.integerPattern = "%d";
-        result.currencyPattern = "%s";
-        result.percentPattern = "%f";
-
-        return true;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/.classpath b/tools/layoutlib/bridge/tests/.classpath
deleted file mode 100644
index 2b32e09..0000000
--- a/tools/layoutlib/bridge/tests/.classpath
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="res"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_bridge"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib/bridge/tests/.project b/tools/layoutlib/bridge/tests/.project
deleted file mode 100644
index 2325eed..0000000
--- a/tools/layoutlib/bridge/tests/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_bridge-tests</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk
deleted file mode 100644
index 98cade9..0000000
--- a/tools/layoutlib/bridge/tests/Android.mk
+++ /dev/null
@@ -1,32 +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)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_RESOURCE_DIRS := res
-
-LOCAL_MODULE := layoutlib-tests
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := layoutlib kxml2-2.3.0 junit
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/layoutlib/bridge/tests/res/com/android/layoutlib/testdata/layout1.xml b/tools/layoutlib/bridge/tests/res/com/android/layoutlib/testdata/layout1.xml
deleted file mode 100644
index b8fc947..0000000
--- a/tools/layoutlib/bridge/tests/res/com/android/layoutlib/testdata/layout1.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-	android:orientation="vertical"
->
-	<Button
-		android:id="@+id/bouton"
-	    android:layout_width="wrap_content"
-	    android:layout_height="wrap_content"
-	    android:layout_weight="1"
-	    android:text="My Button Text"
-	    >
-	    </Button>
-	<View
-		android:id="@+id/surface"
-	    android:layout_width="match_parent"
-	    android:layout_height="match_parent"
-	    android:layout_weight="2"
-	    />
-	<TextView
-	    android:id="@+id/status"
-	    android:paddingLeft="2dip"
-	    android:layout_weight="0"
-	    android:background="@drawable/black"
-	    android:layout_width="match_parent"
-	    android:layout_height="wrap_content"
-	    android:lines="1"
-	    android:gravity="center_vertical|center_horizontal"
-	    android:text="My TextView Text"
-	    />
-</LinearLayout>
diff --git a/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java b/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
deleted file mode 100644
index ec4edac..0000000
--- a/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import junit.framework.TestCase;
-
-/**
- *
- */
-public class Matrix_DelegateTest extends TestCase {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public void testIdentity() {
-        Matrix m1 = new Matrix();
-
-        assertTrue(m1.isIdentity());
-
-        m1.setValues(new float[] { 1,0,0, 0,1,0, 0,0,1 });
-        assertTrue(m1.isIdentity());
-    }
-
-    public void testCopyConstructor() {
-        Matrix m1 = new Matrix();
-        Matrix m2 = new Matrix(m1);
-
-        float[] v1 = new float[9];
-        float[] v2 = new float[9];
-        m1.getValues(v1);
-        m2.getValues(v2);
-
-        for (int i = 0 ; i < 9; i++) {
-            assertEquals(v1[i], v2[i]);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
deleted file mode 100644
index d3218db..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.create.CreateInfo;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-/**
- * Tests that native delegate classes implement all the required methods.
- *
- * This looks at {@link CreateInfo#DELEGATE_CLASS_NATIVES} to get the list of classes that
- * have their native methods reimplemented through a delegate.
- *
- * Since the reimplemented methods are not native anymore, we look for the annotation
- * {@link LayoutlibDelegate}, and look for a matching method in the delegate (named the same
- * as the modified class with _Delegate added as a suffix).
- * If the original native method is not static, then we make sure the delegate method also
- * include the original class as first parameter (to access "this").
- *
- */
-public class TestDelegates extends TestCase {
-
-    public void testNativeDelegates() {
-
-        final String[] classes = CreateInfo.DELEGATE_CLASS_NATIVES;
-        final int count = classes.length;
-        for (int i = 0 ; i < count ; i++) {
-            loadAndCompareClasses(classes[i], classes[i] + "_Delegate");
-        }
-    }
-
-    public void testMethodDelegates() {
-        final String[] methods = CreateInfo.DELEGATE_METHODS;
-        final int count = methods.length;
-        for (int i = 0 ; i < count ; i++) {
-            String methodName = methods[i];
-
-            // extract the class name
-            String className = methodName.substring(0, methodName.indexOf('#'));
-            String targetClassName = className.replace('$', '_') + "_Delegate";
-
-            loadAndCompareClasses(className, targetClassName);
-        }
-    }
-
-    private void loadAndCompareClasses(String originalClassName, String delegateClassName) {
-        // load the classes
-        try {
-            ClassLoader classLoader = TestDelegates.class.getClassLoader();
-            Class<?> originalClass = classLoader.loadClass(originalClassName);
-            Class<?> delegateClass = classLoader.loadClass(delegateClassName);
-
-            compare(originalClass, delegateClass);
-        } catch (ClassNotFoundException e) {
-           fail("Failed to load class: " + e.getMessage());
-        } catch (SecurityException e) {
-            fail("Failed to load class: " + e.getMessage());
-        }
-    }
-
-    private void compare(Class<?> originalClass, Class<?> delegateClass) throws SecurityException {
-        List<Method> checkedDelegateMethods = new ArrayList<Method>();
-
-        // loop on the methods of the original class, and for the ones that are annotated
-        // with @LayoutlibDelegate, look for a matching method in the delegate class.
-        // The annotation is automatically added by layoutlib_create when it replace a method
-        // by a call to a delegate
-        Method[] originalMethods = originalClass.getDeclaredMethods();
-        for (Method originalMethod : originalMethods) {
-            // look for methods that are delegated: they have the LayoutlibDelegate annotation
-            if (originalMethod.getAnnotation(LayoutlibDelegate.class) == null) {
-                continue;
-            }
-
-            // get the signature.
-            Class<?>[] parameters = originalMethod.getParameterTypes();
-
-            // if the method is not static, then the class is added as the first parameter
-            // (for "this")
-            if ((originalMethod.getModifiers() & Modifier.STATIC) == 0) {
-
-                Class<?>[] newParameters = new Class<?>[parameters.length + 1];
-                newParameters[0] = originalClass;
-                System.arraycopy(parameters, 0, newParameters, 1, parameters.length);
-                parameters = newParameters;
-            }
-
-            // if the original class is an inner class that's not static, then
-            // we add this on the enclosing class at the beginning
-            if (originalClass.getEnclosingClass() != null &&
-                    (originalClass.getModifiers() & Modifier.STATIC) == 0) {
-                Class<?>[] newParameters = new Class<?>[parameters.length + 1];
-                newParameters[0] = originalClass.getEnclosingClass();
-                System.arraycopy(parameters, 0, newParameters, 1, parameters.length);
-                parameters = newParameters;
-            }
-
-            try {
-                // try to load the method with the given parameter types.
-                Method delegateMethod = delegateClass.getDeclaredMethod(originalMethod.getName(),
-                        parameters);
-
-                // check that the method has the annotation
-                assertNotNull(
-                        String.format(
-                                "Delegate method %1$s for class %2$s does not have the @LayoutlibDelegate annotation",
-                                delegateMethod.getName(),
-                                originalClass.getName()),
-                        delegateMethod.getAnnotation(LayoutlibDelegate.class));
-
-                // check that the method is static
-                assertTrue(
-                        String.format(
-                                "Delegate method %1$s for class %2$s is not static",
-                                delegateMethod.getName(),
-                                originalClass.getName()),
-                        (delegateMethod.getModifiers() & Modifier.STATIC) == Modifier.STATIC);
-
-                // add the method as checked.
-                checkedDelegateMethods.add(delegateMethod);
-            } catch (NoSuchMethodException e) {
-                String name = getMethodName(originalMethod, parameters);
-                fail(String.format("Missing %1$s.%2$s", delegateClass.getName(), name));
-            }
-        }
-
-        // look for dead (delegate) code.
-        // This looks for all methods in the delegate class, and if they have the
-        // @LayoutlibDelegate annotation, make sure they have been previously found as a
-        // match for a method in the original class.
-        // If not, this means the method is a delegate for a method that either doesn't exist
-        // anymore or is not delegated anymore.
-        Method[] delegateMethods = delegateClass.getDeclaredMethods();
-        for (Method delegateMethod : delegateMethods) {
-            // look for methods that are delegates: they have the LayoutlibDelegate annotation
-            if (delegateMethod.getAnnotation(LayoutlibDelegate.class) == null) {
-                continue;
-            }
-
-            assertTrue(
-                    String.format(
-                            "Delegate method %1$s.%2$s is not used anymore and must be removed",
-                            delegateClass.getName(),
-                            getMethodName(delegateMethod)),
-                    checkedDelegateMethods.contains(delegateMethod));
-        }
-
-    }
-
-    private String getMethodName(Method method) {
-        return getMethodName(method, method.getParameterTypes());
-    }
-
-    private String getMethodName(Method method, Class<?>[] parameters) {
-        // compute a full class name that's long but not too long.
-        StringBuilder sb = new StringBuilder(method.getName() + "(");
-        for (int j = 0; j < parameters.length; j++) {
-            Class<?> theClass = parameters[j];
-            sb.append(theClass.getName());
-            int dimensions = 0;
-            while (theClass.isArray()) {
-                dimensions++;
-                theClass = theClass.getComponentType();
-            }
-            for (int i = 0; i < dimensions; i++) {
-                sb.append("[]");
-            }
-            if (j < (parameters.length - 1)) {
-                sb.append(",");
-            }
-        }
-        sb.append(")");
-
-        return sb.toString();
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
deleted file mode 100644
index 865a008..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
+++ /dev/null
@@ -1,121 +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 com.android.layoutlib.bridge.android;
-
-import com.android.layoutlib.bridge.impl.ParserFactory;
-
-import org.w3c.dom.Node;
-import org.xmlpull.v1.XmlPullParser;
-
-import junit.framework.TestCase;
-
-public class BridgeXmlBlockParserTest extends TestCase {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public void testXmlBlockParser() throws Exception {
-
-        XmlPullParser parser = ParserFactory.create(
-                getClass().getResourceAsStream("/com/android/layoutlib/testdata/layout1.xml"),
-                        "layout1.xml");
-
-        parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */);
-
-        assertEquals(XmlPullParser.START_DOCUMENT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("LinearLayout", parser.getName());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("Button", parser.getName());
-        assertEquals(XmlPullParser.TEXT, parser.next());
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("View", parser.getName());
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("TextView", parser.getName());
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-        assertEquals(XmlPullParser.END_DOCUMENT, parser.next());
-    }
-
-    //------------
-
-    /**
-     * Quick'n'dirty debug helper that dumps an XML structure to stdout.
-     */
-    @SuppressWarnings("unused")
-    private void dump(Node node, String prefix) {
-        Node n;
-
-        String[] types = {
-                "unknown",
-                "ELEMENT_NODE",
-                "ATTRIBUTE_NODE",
-                "TEXT_NODE",
-                "CDATA_SECTION_NODE",
-                "ENTITY_REFERENCE_NODE",
-                "ENTITY_NODE",
-                "PROCESSING_INSTRUCTION_NODE",
-                "COMMENT_NODE",
-                "DOCUMENT_NODE",
-                "DOCUMENT_TYPE_NODE",
-                "DOCUMENT_FRAGMENT_NODE",
-                "NOTATION_NODE"
-        };
-
-        String s = String.format("%s<%s> %s %s",
-                prefix,
-                types[node.getNodeType()],
-                node.getNodeName(),
-                node.getNodeValue() == null ? "" : node.getNodeValue().trim());
-
-        System.out.println(s);
-
-        n = node.getFirstChild();
-        if (n != null) {
-            dump(n, prefix + "- ");
-        }
-
-        n = node.getNextSibling();
-        if (n != null) {
-            dump(n, prefix);
-        }
-
-    }
-
-}
diff --git a/tools/layoutlib/create/.classpath b/tools/layoutlib/create/.classpath
deleted file mode 100644
index cd8bb0d..0000000
--- a/tools/layoutlib/create/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry excluding="mock_data/" kind="src" path="tests"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/asm-tools/asm-4.0.jar" sourcepath="/ANDROID_PLAT/prebuilts/tools/common/asm-tools/src-4.0.zip"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib/create/.project b/tools/layoutlib/create/.project
deleted file mode 100644
index e100d17..0000000
--- a/tools/layoutlib/create/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_create</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib/create/.settings/README.txt b/tools/layoutlib/create/.settings/README.txt
deleted file mode 100644
index 9120b20..0000000
--- a/tools/layoutlib/create/.settings/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Copy this in eclipse project as a .settings folder at the root.
-This ensure proper compilation compliance and warning/error levels.
\ No newline at end of file
diff --git a/tools/layoutlib/create/.settings/org.eclipse.jdt.core.prefs b/tools/layoutlib/create/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 5381a0e..0000000
--- a/tools/layoutlib/create/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,93 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.nonnull=com.android.annotations.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=com.android.annotations.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled
-org.eclipse.jdt.core.compiler.annotation.nullable=com.android.annotations.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=error
-org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/tools/layoutlib/create/Android.mk b/tools/layoutlib/create/Android.mk
deleted file mode 100644
index 9bd48ab..0000000
--- a/tools/layoutlib/create/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-LOCAL_JAR_MANIFEST := manifest.txt
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	asm-4.0
-
-LOCAL_MODULE := layoutlib_create
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/layoutlib/create/README.txt b/tools/layoutlib/create/README.txt
deleted file mode 100644
index ef2b185..0000000
--- a/tools/layoutlib/create/README.txt
+++ /dev/null
@@ -1,271 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-
-
-- Description -
----------------
-
-Layoutlib_create generates a JAR library used by the Eclipse graphical layout editor
-to perform layout.
-
-
-- Usage -
----------
-
- ./layoutlib_create path/to/android.jar destination.jar
-
-
-- Design Overview -
--------------------
-
-Layoutlib_create uses the "android.jar" containing all the Java code used by Android
-as generated by the Android build, right before the classes are converted to a DEX format.
-
-The Android JAR can't be used directly in Eclipse:
-- it contains references to native code (which we want to avoid in Eclipse),
-- some classes need to be overridden, for example all the drawing code that is
-  replaced by Java 2D calls in Eclipse.
-- some of the classes that need to be changed are final and/or we need access
-  to their private internal state.
-
-Consequently this tool:
-- parses the input JAR,
-- modifies some of the classes directly using some bytecode manipulation,
-- filters some packages and removes those we don't want in the output JAR,
-- injects some new classes,
-- generates a modified JAR file that is suitable for the Android plugin
-  for Eclipse to perform rendering.
-
-The ASM library is used to do the bytecode modification using its visitor pattern API.
-
-The layoutlib_create is *NOT* generic. There is no configuration file. Instead all the
-configuration is done in the main() method and the CreateInfo structure is expected to
-change with the Android platform as new classes are added, changed or removed.
-
-The resulting JAR is used by layoutlib_bridge (a.k.a. "the bridge"), also part of the
-platform, that provides all the necessary missing implementation for rendering graphics
-in Eclipse.
-
-
-
-- Implementation Notes -
-------------------------
-
-The tool works in two phases:
-- first analyze the input jar (AsmAnalyzer class)
-- then generate the output jar (AsmGenerator class),
-
-
-- Analyzer
-----------
-
-The goal of the analyzer is to create a graph of all the classes from the input JAR
-with their dependencies and then only keep the ones we want.
-
-To do that, the analyzer is created with a list of base classes to keep -- everything
-that derives from these is kept. Currently the one such class is android.view.View:
-since we want to render layouts, anything that is sort of a view needs to be kept.
-
-The analyzer is also given a list of class names to keep in the output.
-This is done using shell-like glob patterns that filter on the fully-qualified
-class names, for example "android.*.R**" ("*" does not matches dots whilst "**" does,
-and "." and "$" are interpreted as-is).
-In practice we almost but not quite request the inclusion of full packages.
-
-The analyzer is also given a list of classes to exclude. A fake implementation of these
-classes is injected by the Generator.
-
-With this information, the analyzer parses the input zip to find all the classes.
-All classes deriving from the requested bases classes are kept.
-All classes which name matched the glob pattern are kept.
-The analysis then finds all the dependencies of the classes that are to be kept
-using an ASM visitor on the class, the field types, the method types and annotations types.
-Classes that belong to the current JRE are excluded.
-
-The output of the analyzer is a set of ASM ClassReader instances which are then
-fed to the generator.
-
-
-- Generator
------------
-
-The generator is constructed from a CreateInfo struct that acts as a config file
-and lists:
-- the classes to inject in the output JAR -- these classes are directly implemented
-  in layoutlib_create and will be used to interface with the renderer in Eclipse.
-- specific methods to override (see method stubs details below).
-- specific methods for which to delegate calls.
-- specific methods to remove based on their return type.
-- specific classes to rename.
-- specific classes to refactor.
-
-Each of these are specific strategies we use to be able to modify the Android code
-to fit within the Eclipse renderer. These strategies are explained beow.
-
-The core method of the generator is transform(): it takes an input ASM ClassReader
-and modifies it to produce a byte array suitable for the final JAR file.
-
-The first step of the transformation is to implement the method delegates.
-
-The TransformClassAdapter is then used to process the potentially renamed class.
-All protected or private classes are market as public.
-All classes are made non-final.
-Interfaces are left as-is.
-
-If a method has a return type that must be erased, the whole method is skipped.
-Methods are also changed from protected/private to public.
-The code of the methods is then kept as-is, except for native methods which are
-replaced by a stub. Methods that are to be overridden are also replaced by a stub.
-
-Finally fields are also visited and changed from protected/private to public.
-
-The next step of the transformation is changing the name of the class in case
-we requested the class to be renamed. This uses the RenameClassAdapter to also rename
-all inner classes and references in methods and types. Note that other classes are
-not transformed and keep referencing the original name.
-
-The class is then fed to RefactorClassAdapter which is like RenameClassAdapter but
-updates the references in all classes. This is used to update the references of classes
-in the java package that were added in the Dalvik VM but are not a part of the standard
-JVM. The existing classes are modified to update all references to these non-standard
-classes. An alternate implementation of these (com.android.tools.layoutlib.java.*) is
-injected.
-
-The ClassAdapters are chained together to achieve the desired output. (Look at section
-2.2.7 Transformation chains in the asm user guide, link in the References.) The order of
-execution of these is:
-ClassReader -> [DelegateClassAdapter] -> TransformClassAdapter -> [RenameClassAdapter] ->
-RefactorClassAdapter -> ClassWriter
-
-- Method stubs
---------------
-
-As indicated above, all native and overridden methods are replaced by a stub.
-We don't have the code to replace with in layoutlib_create.
-Instead the StubMethodAdapter replaces the code of the method by a call to
-OverrideMethod.invokeX(). When using the final JAR, the bridge can register
-listeners from these overridden method calls based on the method signatures.
-
-The listeners are currently pretty basic: we only pass the signature of the
-method being called, its caller object and a flag indicating whether the
-method was native. We do not currently provide the parameters. The listener
-can however specify the return value of the overridden method.
-
-This strategy is now obsolete and replaced by the method delegates.
-
-
-- Strategies
-------------
-
-We currently have 6 strategies to deal with overriding the rendering code
-and make it run in Eclipse. Most of these strategies are implemented hand-in-hand
-by the bridge (which runs in Eclipse) and the generator.
-
-
-1- Class Injection
-
-This is the easiest: we currently inject the following classes:
-- OverrideMethod and its associated MethodListener and MethodAdapter are used
-  to intercept calls to some specific methods that are stubbed out and change
-  their return value.
-- CreateInfo class, which configured the generator. Not used yet, but could
-  in theory help us track what the generator changed.
-- AutoCloseable and Objects are part of Java 7. To enable us to still run on Java 6, new
-  classes are injected. The implementation for these classes has been taken from
-  Android's libcore (platform/libcore/luni/src/main/java/java/...).
-- Charsets, IntegralToString and UnsafeByteSequence are not part of the standard JAVA VM.
-  They are added to the Dalvik VM for performance reasons. An implementation that is very
-  close to the original (which is at platform/libcore/luni/src/main/java/...) is injected.
-  Since these classees were in part of the java package, where we can't inject classes,
-  all references to these have been updated (See strategy 4- Refactoring Classes).
-
-
-2- Overriding methods
-
-As explained earlier, the creator doesn't have any replacement code for
-methods to override. Instead it removes the original code and replaces it
-by a call to a specific OveriddeMethod.invokeX(). The bridge then registers
-a listener on the method signature and can provide an implementation.
-
-This strategy is now obsolete and replaced by the method delegates.
-See strategy 5 below.
-
-
-3- Renaming classes
-
-This simply changes the name of a class in its definition, as well as all its
-references in internal inner classes and methods.
-Calls from other classes are not modified -- they keep referencing the original
-class name. This allows the bridge to literally replace an implementation.
-
-An example will make this easier: android.graphics.Paint is the main drawing
-class that we need to replace. To do so, the generator renames Paint to _original_Paint.
-Later the bridge provides its own replacement version of Paint which will be used
-by the rest of the Android stack. The replacement version of Paint can still use
-(either by inheritance or delegation) all the original non-native code of _original_Paint
-if it so desires.
-
-Some of the Android classes are basically wrappers over native objects and since
-we don't have the native code in Eclipse, we need to provide a full alternate
-implementation. Sub-classing doesn't work as some native methods are static and
-we don't control object creation.
-
-This won't rename/replace the inner static methods of a given class.
-
-
-4- Refactoring classes
-
-This is very similar to the Renaming classes except that it also updates the reference in
-all classes. This is done for classes which are added to the Dalvik VM for performance
-reasons but are not present in the Standard Java VM. An implementation for these classes
-is also injected.
-
-
-5- Method erasure based on return type
-
-This is mostly an implementation detail of the bridge: in the Paint class
-mentioned above, some inner static classes are used to pass around
-attributes (e.g. FontMetrics, or the Style enum) and all the original implementation
-is native.
-
-In this case we have a strategy that tells the generator that anything returning, for
-example, the inner class Paint$Style in the Paint class should be discarded and the
-bridge will provide its own implementation.
-
-
-6- Method Delegates
-
-This strategy is used to override method implementations.
-Given a method SomeClass.MethodName(), 1 or 2 methods are generated:
-a- A copy of the original method named SomeClass.MethodName_Original().
-   The content is the original method as-is from the reader.
-   This step is omitted if the method is native, since it has no Java implementation.
-b- A brand new implementation of SomeClass.MethodName() which calls to a
-   non-existing static method named SomeClass_Delegate.MethodName().
-   The implementation of this 'delegate' method is done in layoutlib_brigde.
-
-The delegate method is a static method.
-If the original method is non-static, the delegate method receives the original 'this'
-as its first argument. If the original method is an inner non-static method, it also
-receives the inner 'this' as the second argument.
-
-
-
-- References -
---------------
-
-
-The JVM Specification 2nd edition:
-  http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html
-
-Understanding bytecode:
-  http://www.ibm.com/developerworks/ibm/library/it-haggar_bytecode/
-
-Bytecode opcode list:
-  http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
-
-ASM user guide:
-  http://download.forge.objectweb.org/asm/asm4-guide.pdf
-
-
---
-end
diff --git a/tools/layoutlib/create/manifest.txt b/tools/layoutlib/create/manifest.txt
deleted file mode 100644
index 238e7f9..0000000
--- a/tools/layoutlib/create/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.tools.layoutlib.create.Main
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java
deleted file mode 100644
index 9a48ea6..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes a method that has been converted to a delegate by layoutlib_create.
- */
-@Retention(RetentionPolicy.RUNTIME)
-public @interface LayoutlibDelegate {
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java
deleted file mode 100644
index 0689c92..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes a parameter or field can be null.
- * <p/>
- * When decorating a method call parameter, this denotes the parameter can
- * legitimately be null and the method will gracefully deal with it. Typically used
- * on optional parameters.
- * <p/>
- * When decorating a method, this denotes the method might legitimately return null.
- * <p/>
- * This is a marker annotation and it has no specific attributes.
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface Nullable {
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java
deleted file mode 100644
index e4e016b..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes that the class, method or field has its visibility relaxed so
- * that unit tests can access it.
- * <p/>
- * The <code>visibility</code> argument can be used to specific what the original
- * visibility should have been if it had not been made public or package-private for testing.
- * The default is to consider the element private.
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface VisibleForTesting {
-    /**
-     * Intended visibility if the element had not been made public or package-private for
-     * testing.
-     */
-    enum Visibility {
-        /** The element should be considered protected. */
-        PROTECTED,
-        /** The element should be considered package-private. */
-        PACKAGE,
-        /** The element should be considered private. */
-        PRIVATE
-    }
-
-    /**
-     * Intended visibility if the element had not been made public or package-private for testing.
-     * If not specified, one should assume the element originally intended to be private.
-     */
-    Visibility visibility() default Visibility.PRIVATE;
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
deleted file mode 100644
index b2caa25..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
+++ /dev/null
@@ -1,418 +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.tools.layoutlib.create;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-import org.objectweb.asm.signature.SignatureWriter;
-
-/**
- * Provides the common code for RenameClassAdapter and RefactorClassAdapter. It
- * goes through the complete class and finds references to other classes. It
- * then calls {@link #renameInternalType(String)} to convert the className to
- * the new value, if need be.
- */
-public abstract class AbstractClassAdapter extends ClassVisitor {
-
-    /**
-     * Returns the new FQCN for the class, if the reference to this class needs
-     * to be updated. Else, it returns the same string.
-     * @param name Old FQCN
-     * @return New FQCN if it needs to be renamed, else the old FQCN
-     */
-    abstract String renameInternalType(String name);
-
-    public AbstractClassAdapter(ClassVisitor cv) {
-        super(Opcodes.ASM4, cv);
-    }
-
-    /**
-     * Renames a type descriptor, e.g. "Lcom.package.MyClass;"
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     */
-    String renameTypeDesc(String desc) {
-        if (desc == null) {
-            return null;
-        }
-
-        return renameType(Type.getType(desc));
-    }
-
-    /**
-     * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
-     * object element, e.g. "[Lcom.package.MyClass;"
-     * If the type doesn't need to be renamed, returns the internal name of the input type.
-     */
-    String renameType(Type type) {
-        if (type == null) {
-            return null;
-        }
-
-        if (type.getSort() == Type.OBJECT) {
-            String in = type.getInternalName();
-            return "L" + renameInternalType(in) + ";";
-        } else if (type.getSort() == Type.ARRAY) {
-            StringBuilder sb = new StringBuilder();
-            for (int n = type.getDimensions(); n > 0; n--) {
-                sb.append('[');
-            }
-            sb.append(renameType(type.getElementType()));
-            return sb.toString();
-        }
-        return type.getDescriptor();
-    }
-
-    /**
-     * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
-     * object element, e.g. "[Lcom.package.MyClass;".
-     * This is like renameType() except that it returns a Type object.
-     * If the type doesn't need to be renamed, returns the input type object.
-     */
-    Type renameTypeAsType(Type type) {
-        if (type == null) {
-            return null;
-        }
-
-        if (type.getSort() == Type.OBJECT) {
-            String in = type.getInternalName();
-            String newIn = renameInternalType(in);
-            if (newIn != in) {
-                return Type.getType("L" + newIn + ";");
-            }
-        } else if (type.getSort() == Type.ARRAY) {
-            StringBuilder sb = new StringBuilder();
-            for (int n = type.getDimensions(); n > 0; n--) {
-                sb.append('[');
-            }
-            sb.append(renameType(type.getElementType()));
-            return Type.getType(sb.toString());
-        }
-        return type;
-    }
-
-    /**
-     * Renames a method descriptor, i.e. applies renameType to all arguments and to the
-     * return value.
-     */
-    String renameMethodDesc(String desc) {
-        if (desc == null) {
-            return null;
-        }
-
-        Type[] args = Type.getArgumentTypes(desc);
-
-        StringBuilder sb = new StringBuilder("(");
-        for (Type arg : args) {
-            String name = renameType(arg);
-            sb.append(name);
-        }
-        sb.append(')');
-
-        Type ret = Type.getReturnType(desc);
-        String name = renameType(ret);
-        sb.append(name);
-
-        return sb.toString();
-    }
-
-
-    /**
-     * Renames the ClassSignature handled by ClassVisitor.visit
-     * or the MethodTypeSignature handled by ClassVisitor.visitMethod.
-     */
-    String renameTypeSignature(String sig) {
-        if (sig == null) {
-            return null;
-        }
-        SignatureReader reader = new SignatureReader(sig);
-        SignatureWriter writer = new SignatureWriter();
-        reader.accept(new RenameSignatureAdapter(writer));
-        sig = writer.toString();
-        return sig;
-    }
-
-
-    /**
-     * Renames the FieldTypeSignature handled by ClassVisitor.visitField
-     * or MethodVisitor.visitLocalVariable.
-     */
-    String renameFieldSignature(String sig) {
-        return renameTypeSignature(sig);
-    }
-
-
-    //----------------------------------
-    // Methods from the ClassAdapter
-
-    @Override
-    public void visit(int version, int access, String name, String signature,
-            String superName, String[] interfaces) {
-        name = renameInternalType(name);
-        superName = renameInternalType(superName);
-        signature = renameTypeSignature(signature);
-        if (interfaces != null) {
-            for (int i = 0; i < interfaces.length; ++i) {
-                interfaces[i] = renameInternalType(interfaces[i]);
-            }
-        }
-
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        name = renameInternalType(name);
-        outerName = renameInternalType(outerName);
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-
-    @Override
-    public void visitOuterClass(String owner, String name, String desc) {
-        super.visitOuterClass(renameInternalType(owner), name, renameTypeDesc(desc));
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-        desc = renameMethodDesc(desc);
-        signature = renameTypeSignature(signature);
-        MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
-        return new RenameMethodAdapter(mw);
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        desc = renameTypeDesc(desc);
-        return super.visitAnnotation(desc, visible);
-    }
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc,
-            String signature, Object value) {
-        desc = renameTypeDesc(desc);
-        return super.visitField(access, name, desc, signature, value);
-    }
-
-
-    //----------------------------------
-
-    /**
-     * A method visitor that renames all references from an old class name to a new class name.
-     */
-    public class RenameMethodAdapter extends MethodVisitor {
-
-        /**
-         * Creates a method visitor that renames all references from a given old name to a given new
-         * name. The method visitor will also rename all inner classes.
-         * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
-         */
-        public RenameMethodAdapter(MethodVisitor mv) {
-            super(Opcodes.ASM4, mv);
-        }
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            desc = renameTypeDesc(desc);
-
-            return super.visitAnnotation(desc, visible);
-        }
-
-        @Override
-        public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
-            desc = renameTypeDesc(desc);
-
-            return super.visitParameterAnnotation(parameter, desc, visible);
-        }
-
-        @Override
-        public void visitTypeInsn(int opcode, String type) {
-            // The type sometimes turns out to be a type descriptor. We try to detect it and fix.
-            if (type.indexOf(';') > 0) {
-                type = renameTypeDesc(type);
-            } else {
-                type = renameInternalType(type);
-            }
-            super.visitTypeInsn(opcode, type);
-        }
-
-        @Override
-        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-            owner = renameInternalType(owner);
-            desc = renameTypeDesc(desc);
-
-            super.visitFieldInsn(opcode, owner, name, desc);
-        }
-
-        @Override
-        public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-            // The owner sometimes turns out to be a type descriptor. We try to detect it and fix.
-            if (owner.indexOf(';') > 0) {
-                owner = renameTypeDesc(owner);
-            } else {
-                owner = renameInternalType(owner);
-            }
-            desc = renameMethodDesc(desc);
-
-            super.visitMethodInsn(opcode, owner, name, desc);
-        }
-
-        @Override
-        public void visitLdcInsn(Object cst) {
-            // If cst is a Type, this means the code is trying to pull the .class constant
-            // for this class, so it needs to be renamed too.
-            if (cst instanceof Type) {
-                cst = renameTypeAsType((Type) cst);
-            }
-            super.visitLdcInsn(cst);
-        }
-
-        @Override
-        public void visitMultiANewArrayInsn(String desc, int dims) {
-            desc = renameTypeDesc(desc);
-
-            super.visitMultiANewArrayInsn(desc, dims);
-        }
-
-        @Override
-        public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-            type = renameInternalType(type);
-
-            super.visitTryCatchBlock(start, end, handler, type);
-        }
-
-        @Override
-        public void visitLocalVariable(String name, String desc, String signature,
-                Label start, Label end, int index) {
-            desc = renameTypeDesc(desc);
-            signature = renameFieldSignature(signature);
-
-            super.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-
-    }
-
-    //----------------------------------
-
-    public class RenameSignatureAdapter extends SignatureVisitor {
-
-        private final SignatureVisitor mSv;
-
-        public RenameSignatureAdapter(SignatureVisitor sv) {
-            super(Opcodes.ASM4);
-            mSv = sv;
-        }
-
-        @Override
-        public void visitClassType(String name) {
-            name = renameInternalType(name);
-            mSv.visitClassType(name);
-        }
-
-        @Override
-        public void visitInnerClassType(String name) {
-            name = renameInternalType(name);
-            mSv.visitInnerClassType(name);
-        }
-
-        @Override
-        public SignatureVisitor visitArrayType() {
-            SignatureVisitor sv = mSv.visitArrayType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitBaseType(char descriptor) {
-            mSv.visitBaseType(descriptor);
-        }
-
-        @Override
-        public SignatureVisitor visitClassBound() {
-            SignatureVisitor sv = mSv.visitClassBound();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitEnd() {
-            mSv.visitEnd();
-        }
-
-        @Override
-        public SignatureVisitor visitExceptionType() {
-            SignatureVisitor sv = mSv.visitExceptionType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitFormalTypeParameter(String name) {
-            mSv.visitFormalTypeParameter(name);
-        }
-
-        @Override
-        public SignatureVisitor visitInterface() {
-            SignatureVisitor sv = mSv.visitInterface();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitInterfaceBound() {
-            SignatureVisitor sv = mSv.visitInterfaceBound();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitParameterType() {
-            SignatureVisitor sv = mSv.visitParameterType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitReturnType() {
-            SignatureVisitor sv = mSv.visitReturnType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitSuperclass() {
-            SignatureVisitor sv = mSv.visitSuperclass();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitTypeArgument() {
-            mSv.visitTypeArgument();
-        }
-
-        @Override
-        public SignatureVisitor visitTypeArgument(char wildcard) {
-            SignatureVisitor sv = mSv.visitTypeArgument(wildcard);
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitTypeVariable(String name) {
-            mSv.visitTypeVariable(name);
-        }
-
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
deleted file mode 100644
index 1572a40..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
+++ /dev/null
@@ -1,854 +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 com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.regex.Pattern;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * Analyzes the input JAR using the ASM java bytecode manipulation library
- * to list the desired classes and their dependencies.
- */
-public class AsmAnalyzer {
-
-    // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
-
-    /** Output logger. */
-    private final Log mLog;
-    /** The input source JAR to parse. */
-    private final List<String> mOsSourceJar;
-    /** The generator to fill with the class list and dependency list. */
-    private final AsmGenerator mGen;
-    /** Keep all classes that derive from these one (these included). */
-    private final String[] mDeriveFrom;
-    /** Glob patterns of classes to keep, e.g. "com.foo.*" */
-    private final String[] mIncludeGlobs;
-    /** The set of classes to exclude.*/
-    private final Set<String> mExcludedClasses;
-
-    /**
-     * Creates a new analyzer.
-     *
-     * @param log The log output.
-     * @param osJarPath The input source JARs to parse.
-     * @param gen The generator to fill with the class list and dependency list.
-     * @param deriveFrom Keep all classes that derive from these one (these included).
-     * @param includeGlobs Glob patterns of classes to keep, e.g. "com.foo.*"
-     *        ("*" does not matches dots whilst "**" does, "." and "$" are interpreted as-is)
-     */
-    public AsmAnalyzer(Log log, List<String> osJarPath, AsmGenerator gen,
-            String[] deriveFrom, String[] includeGlobs, Set<String> excludeClasses) {
-        mLog = log;
-        mGen = gen;
-        mOsSourceJar = osJarPath != null ? osJarPath : new ArrayList<String>();
-        mDeriveFrom = deriveFrom != null ? deriveFrom : new String[0];
-        mIncludeGlobs = includeGlobs != null ? includeGlobs : new String[0];
-        mExcludedClasses = excludeClasses;
-    }
-
-    /**
-     * Starts the analysis using parameters from the constructor.
-     * Fills the generator with classes & dependencies found.
-     */
-    public void analyze() throws IOException, LogAbortException {
-        Map<String, ClassReader> zipClasses = parseZip(mOsSourceJar);
-        mLog.info("Found %d classes in input JAR%s.", zipClasses.size(),
-                mOsSourceJar.size() > 1 ? "s" : "");
-
-        Map<String, ClassReader> found = findIncludes(zipClasses);
-        Map<String, ClassReader> deps = findDeps(zipClasses, found);
-
-        if (mGen != null) {
-            mGen.setKeep(found);
-            mGen.setDeps(deps);
-        }
-    }
-
-    /**
-     * Parses a JAR file and returns a list of all classes founds using a map
-     * class name => ASM ClassReader. Class names are in the form "android.view.View".
-     */
-    Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException {
-        TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>();
-
-        for (String jarPath : jarPathList) {
-            ZipFile zip = new ZipFile(jarPath);
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            ZipEntry entry;
-            while (entries.hasMoreElements()) {
-                entry = entries.nextElement();
-                if (entry.getName().endsWith(".class")) {
-                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
-                    String className = classReaderToClassName(cr);
-                    classes.put(className, cr);
-                }
-            }
-        }
-
-        return classes;
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name for a ClassReader.
-     * E.g. it returns something like android.view.View.
-     */
-    static String classReaderToClassName(ClassReader classReader) {
-        if (classReader == null) {
-            return null;
-        } else {
-            return classReader.getClassName().replace('/', '.');
-        }
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name from a path-like FQCN.
-     * E.g. it returns android.view.View from android/view/View.
-     */
-    static String internalToBinaryClassName(String className) {
-        if (className == null) {
-            return null;
-        } else {
-            return className.replace('/', '.');
-        }
-    }
-
-    /**
-     * Process the "includes" arrays.
-     * <p/>
-     * This updates the in_out_found map.
-     */
-    Map<String, ClassReader> findIncludes(Map<String, ClassReader> zipClasses)
-            throws LogAbortException {
-        TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>();
-
-        mLog.debug("Find classes to include.");
-
-        for (String s : mIncludeGlobs) {
-            findGlobs(s, zipClasses, found);
-        }
-        for (String s : mDeriveFrom) {
-            findClassesDerivingFrom(s, zipClasses, found);
-        }
-
-        return found;
-    }
-
-
-    /**
-     * Uses ASM to find the class reader for the given FQCN class name.
-     * If found, insert it in the in_out_found map.
-     * Returns the class reader object.
-     */
-    ClassReader findClass(String className, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-        ClassReader classReader = zipClasses.get(className);
-        if (classReader == null) {
-            throw new LogAbortException("Class %s not found by ASM in %s",
-                    className, mOsSourceJar);
-        }
-
-        inOutFound.put(className, classReader);
-        return classReader;
-    }
-
-    /**
-     * Insert in the inOutFound map all classes found in zipClasses that match the
-     * given glob pattern.
-     * <p/>
-     * The glob pattern is not a regexp. It only accepts the "*" keyword to mean
-     * "anything but a period". The "." and "$" characters match themselves.
-     * The "**" keyword means everything including ".".
-     * <p/>
-     * Examples:
-     * <ul>
-     * <li>com.foo.* matches all classes in the package com.foo but NOT sub-packages.
-     * <li>com.foo*.*$Event matches all internal Event classes in a com.foo*.* class.
-     * </ul>
-     */
-    void findGlobs(String globPattern, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-        // transforms the glob pattern in a regexp:
-        // - escape "." with "\."
-        // - replace "*" by "[^.]*"
-        // - escape "$" with "\$"
-        // - add end-of-line match $
-        globPattern = globPattern.replaceAll("\\$", "\\\\\\$");
-        globPattern = globPattern.replaceAll("\\.", "\\\\.");
-        // prevent ** from being altered by the next rule, then process the * rule and finally
-        // the real ** rule (which is now @)
-        globPattern = globPattern.replaceAll("\\*\\*", "@");
-        globPattern = globPattern.replaceAll("\\*", "[^.]*");
-        globPattern = globPattern.replaceAll("@", ".*");
-        globPattern += "$";
-
-        Pattern regexp = Pattern.compile(globPattern);
-
-        for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
-            String class_name = entry.getKey();
-            if (regexp.matcher(class_name).matches()) {
-                findClass(class_name, zipClasses, inOutFound);
-            }
-        }
-    }
-
-    /**
-     * Checks all the classes defined in the JarClassName instance and uses BCEL to
-     * determine if they are derived from the given FQCN super class name.
-     * Inserts the super class and all the class objects found in the map.
-     */
-    void findClassesDerivingFrom(String super_name, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-        findClass(super_name, zipClasses, inOutFound);
-
-        for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
-            String className = entry.getKey();
-            if (super_name.equals(className)) {
-                continue;
-            }
-            ClassReader classReader = entry.getValue();
-            ClassReader parent_cr = classReader;
-            while (parent_cr != null) {
-                String parent_name = internalToBinaryClassName(parent_cr.getSuperName());
-                if (parent_name == null) {
-                    // not found
-                    break;
-                } else if (super_name.equals(parent_name)) {
-                    inOutFound.put(className, classReader);
-                    break;
-                }
-                parent_cr = zipClasses.get(parent_name);
-            }
-        }
-    }
-
-    /**
-     * Instantiates a new DependencyVisitor. Useful for unit tests.
-     */
-    DependencyVisitor getVisitor(Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inKeep,
-            Map<String, ClassReader> outKeep,
-            Map<String, ClassReader> inDeps,
-            Map<String, ClassReader> outDeps) {
-        return new DependencyVisitor(zipClasses, inKeep, outKeep, inDeps, outDeps);
-    }
-
-    /**
-     * Finds all dependencies for all classes in keepClasses which are also
-     * listed in zipClasses. Returns a map of all the dependencies found.
-     */
-    Map<String, ClassReader> findDeps(Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutKeepClasses) {
-
-        TreeMap<String, ClassReader> deps = new TreeMap<String, ClassReader>();
-        TreeMap<String, ClassReader> new_deps = new TreeMap<String, ClassReader>();
-        TreeMap<String, ClassReader> new_keep = new TreeMap<String, ClassReader>();
-        TreeMap<String, ClassReader> temp = new TreeMap<String, ClassReader>();
-
-        DependencyVisitor visitor = getVisitor(zipClasses,
-                inOutKeepClasses, new_keep,
-                deps, new_deps);
-
-        for (ClassReader cr : inOutKeepClasses.values()) {
-            cr.accept(visitor, 0 /* flags */);
-        }
-
-        while (new_deps.size() > 0 || new_keep.size() > 0) {
-            deps.putAll(new_deps);
-            inOutKeepClasses.putAll(new_keep);
-
-            temp.clear();
-            temp.putAll(new_deps);
-            temp.putAll(new_keep);
-            new_deps.clear();
-            new_keep.clear();
-            mLog.debug("Found %1$d to keep, %2$d dependencies.",
-                    inOutKeepClasses.size(), deps.size());
-
-            for (ClassReader cr : temp.values()) {
-                cr.accept(visitor, 0 /* flags */);
-            }
-        }
-
-        mLog.info("Found %1$d classes to keep, %2$d class dependencies.",
-                inOutKeepClasses.size(), deps.size());
-
-        return deps;
-    }
-
-
-
-    // ----------------------------------
-
-    /**
-     * Visitor to collect all the type dependencies from a class.
-     */
-    public class DependencyVisitor extends ClassVisitor {
-
-        /** All classes found in the source JAR. */
-        private final Map<String, ClassReader> mZipClasses;
-        /** Classes from which dependencies are to be found. */
-        private final Map<String, ClassReader> mInKeep;
-        /** Dependencies already known. */
-        private final Map<String, ClassReader> mInDeps;
-        /** New dependencies found by this visitor. */
-        private final Map<String, ClassReader> mOutDeps;
-        /** New classes to keep as-is found by this visitor. */
-        private final Map<String, ClassReader> mOutKeep;
-
-        /**
-         * Creates a new visitor that will find all the dependencies for the visited class.
-         * Types which are already in the zipClasses, keepClasses or inDeps are not marked.
-         * New dependencies are marked in outDeps.
-         *
-         * @param zipClasses All classes found in the source JAR.
-         * @param inKeep Classes from which dependencies are to be found.
-         * @param inDeps Dependencies already known.
-         * @param outDeps New dependencies found by this visitor.
-         */
-        public DependencyVisitor(Map<String, ClassReader> zipClasses,
-                Map<String, ClassReader> inKeep,
-                Map<String, ClassReader> outKeep,
-                Map<String,ClassReader> inDeps,
-                Map<String,ClassReader> outDeps) {
-            super(Opcodes.ASM4);
-            mZipClasses = zipClasses;
-            mInKeep = inKeep;
-            mOutKeep = outKeep;
-            mInDeps = inDeps;
-            mOutDeps = outDeps;
-        }
-
-        /**
-         * Considers the given class name as a dependency.
-         * If it does, add to the mOutDeps map.
-         */
-        public void considerName(String className) {
-            if (className == null) {
-                return;
-            }
-
-            className = internalToBinaryClassName(className);
-
-            // exclude classes that have already been found or are marked to be excluded
-            if (mInKeep.containsKey(className) ||
-                    mOutKeep.containsKey(className) ||
-                    mInDeps.containsKey(className) ||
-                    mOutDeps.containsKey(className) ||
-                    mExcludedClasses.contains(getBaseName(className))) {
-                return;
-            }
-
-            // exclude classes that are not part of the JAR file being examined
-            ClassReader cr = mZipClasses.get(className);
-            if (cr == null) {
-                return;
-            }
-
-            try {
-                // exclude classes that are part of the default JRE (the one executing this program)
-                if (getClass().getClassLoader().loadClass(className) != null) {
-                    return;
-                }
-            } catch (ClassNotFoundException e) {
-                // ignore
-            }
-
-            // accept this class:
-            // - android classes are added to dependencies
-            // - non-android classes are added to the list of classes to keep as-is (they don't need
-            //   to be stubbed).
-            if (className.indexOf("android") >= 0) {  // TODO make configurable
-                mOutDeps.put(className, cr);
-            } else {
-                mOutKeep.put(className, cr);
-            }
-        }
-
-        /**
-         * Considers this array of names using considerName().
-         */
-        public void considerNames(String[] classNames) {
-            if (classNames != null) {
-                for (String className : classNames) {
-                    considerName(className);
-                }
-            }
-        }
-
-        /**
-         * Considers this signature or type signature by invoking the {@link SignatureVisitor}
-         * on it.
-         */
-        public void considerSignature(String signature) {
-            if (signature != null) {
-                SignatureReader sr = new SignatureReader(signature);
-                // SignatureReader.accept will call accessType so we don't really have
-                // to differentiate where the signature comes from.
-                sr.accept(new MySignatureVisitor());
-            }
-        }
-
-        /**
-         * Considers this {@link Type}. For arrays, the element type is considered.
-         * If the type is an object, it's internal name is considered.
-         */
-        public void considerType(Type t) {
-            if (t != null) {
-                if (t.getSort() == Type.ARRAY) {
-                    t = t.getElementType();
-                }
-                if (t.getSort() == Type.OBJECT) {
-                    considerName(t.getInternalName());
-                }
-            }
-        }
-
-        /**
-         * Considers a descriptor string. The descriptor is converted to a {@link Type}
-         * and then considerType() is invoked.
-         */
-        public void considerDesc(String desc) {
-            if (desc != null) {
-                try {
-                    Type t = Type.getType(desc);
-                    considerType(t);
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    // ignore, not a valid type.
-                }
-            }
-        }
-
-        private String getBaseName(String className) {
-            int pos = className.indexOf('$');
-            if (pos > 0) {
-                return className.substring(0, pos);
-            }
-            return className;
-        }
-
-        // ---------------------------------------------------
-        // --- ClassVisitor, FieldVisitor
-        // ---------------------------------------------------
-
-        // Visits a class header
-        @Override
-        public void visit(int version, int access, String name,
-                String signature, String superName, String[] interfaces) {
-            // signature is the signature of this class. May be null if the class is not a generic
-            // one, and does not extend or implement generic classes or interfaces.
-
-            if (signature != null) {
-                considerSignature(signature);
-            }
-
-            // superName is the internal of name of the super class (see getInternalName).
-            // For interfaces, the super class is Object. May be null but only for the Object class.
-            considerName(superName);
-
-            // interfaces is the internal names of the class's interfaces (see getInternalName).
-            // May be null.
-            considerNames(interfaces);
-        }
-
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            // desc is the class descriptor of the annotation class.
-            considerDesc(desc);
-            return new MyAnnotationVisitor();
-        }
-
-        @Override
-        public void visitAttribute(Attribute attr) {
-            // pass
-        }
-
-        // Visits the end of a class
-        @Override
-        public void visitEnd() {
-            // pass
-        }
-
-        private class MyFieldVisitor extends FieldVisitor {
-
-            public MyFieldVisitor() {
-                super(Opcodes.ASM4);
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitAttribute(Attribute attr) {
-                // pass
-            }
-
-            // Visits the end of a class
-            @Override
-            public void visitEnd() {
-                // pass
-            }
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc,
-                String signature, Object value) {
-            // desc is the field's descriptor (see Type).
-            considerDesc(desc);
-
-            // signature is the field's signature. May be null if the field's type does not use
-            // generic types.
-            considerSignature(signature);
-
-            return new MyFieldVisitor();
-        }
-
-        @Override
-        public void visitInnerClass(String name, String outerName, String innerName, int access) {
-            // name is the internal name of an inner class (see getInternalName).
-            considerName(name);
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc,
-                String signature, String[] exceptions) {
-            // desc is the method's descriptor (see Type).
-            considerDesc(desc);
-            // signature is the method's signature. May be null if the method parameters, return
-            // type and exceptions do not use generic types.
-            considerSignature(signature);
-
-            return new MyMethodVisitor();
-        }
-
-        @Override
-        public void visitOuterClass(String owner, String name, String desc) {
-            // pass
-        }
-
-        @Override
-        public void visitSource(String source, String debug) {
-            // pass
-        }
-
-
-        // ---------------------------------------------------
-        // --- MethodVisitor
-        // ---------------------------------------------------
-
-        private class MyMethodVisitor extends MethodVisitor {
-
-            public MyMethodVisitor() {
-                super(Opcodes.ASM4);
-            }
-
-
-            @Override
-            public AnnotationVisitor visitAnnotationDefault() {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitCode() {
-                // pass
-            }
-
-            // field instruction
-            @Override
-            public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-                // name is the field's name.
-                considerName(name);
-                // desc is the field's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            @Override
-            public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
-                // pass
-            }
-
-            @Override
-            public void visitIincInsn(int var, int increment) {
-                // pass -- an IINC instruction
-            }
-
-            @Override
-            public void visitInsn(int opcode) {
-                // pass -- a zero operand instruction
-            }
-
-            @Override
-            public void visitIntInsn(int opcode, int operand) {
-                // pass -- a single int operand instruction
-            }
-
-            @Override
-            public void visitJumpInsn(int opcode, Label label) {
-                // pass -- a jump instruction
-            }
-
-            @Override
-            public void visitLabel(Label label) {
-                // pass -- a label target
-            }
-
-            // instruction to load a constant from the stack
-            @Override
-            public void visitLdcInsn(Object cst) {
-                if (cst instanceof Type) {
-                    considerType((Type) cst);
-                }
-            }
-
-            @Override
-            public void visitLineNumber(int line, Label start) {
-                // pass
-            }
-
-            @Override
-            public void visitLocalVariable(String name, String desc,
-                    String signature, Label start, Label end, int index) {
-                // desc is the type descriptor of this local variable.
-                considerDesc(desc);
-                // signature is the type signature of this local variable. May be null if the local
-                // variable type does not use generic types.
-                considerSignature(signature);
-            }
-
-            @Override
-            public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-                // pass -- a lookup switch instruction
-            }
-
-            @Override
-            public void visitMaxs(int maxStack, int maxLocals) {
-                // pass
-            }
-
-            // instruction that invokes a method
-            @Override
-            public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-
-                // owner is the internal name of the method's owner class
-                considerName(owner);
-                // desc is the method's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            // instruction multianewarray, whatever that is
-            @Override
-            public void visitMultiANewArrayInsn(String desc, int dims) {
-
-                // desc an array type descriptor.
-                considerDesc(desc);
-            }
-
-            @Override
-            public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-                    boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
-                // pass -- table switch instruction
-
-            }
-
-            @Override
-            public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-                // type is the internal name of the type of exceptions handled by the handler,
-                // or null to catch any exceptions (for "finally" blocks).
-                considerName(type);
-            }
-
-            // type instruction
-            @Override
-            public void visitTypeInsn(int opcode, String type) {
-                // type is the operand of the instruction to be visited. This operand must be the
-                // internal name of an object or array class.
-                considerName(type);
-            }
-
-            @Override
-            public void visitVarInsn(int opcode, int var) {
-                // pass -- local variable instruction
-            }
-        }
-
-        private class MySignatureVisitor extends SignatureVisitor {
-
-            public MySignatureVisitor() {
-                super(Opcodes.ASM4);
-            }
-
-            // ---------------------------------------------------
-            // --- SignatureVisitor
-            // ---------------------------------------------------
-
-            private String mCurrentSignatureClass = null;
-
-            // Starts the visit of a signature corresponding to a class or interface type
-            @Override
-            public void visitClassType(String name) {
-                mCurrentSignatureClass = name;
-                considerName(name);
-            }
-
-            // Visits an inner class
-            @Override
-            public void visitInnerClassType(String name) {
-                if (mCurrentSignatureClass != null) {
-                    mCurrentSignatureClass += "$" + name;
-                    considerName(mCurrentSignatureClass);
-                }
-            }
-
-            @Override
-            public SignatureVisitor visitArrayType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitBaseType(char descriptor) {
-                // pass -- a primitive type, ignored
-            }
-
-            @Override
-            public SignatureVisitor visitClassBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitExceptionType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitFormalTypeParameter(String name) {
-                // pass
-            }
-
-            @Override
-            public SignatureVisitor visitInterface() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitInterfaceBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitParameterType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitReturnType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitSuperclass() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitTypeArgument(char wildcard) {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitTypeVariable(String name) {
-                // pass
-            }
-
-            @Override
-            public void visitTypeArgument() {
-                // pass
-            }
-        }
-
-
-        // ---------------------------------------------------
-        // --- AnnotationVisitor
-        // ---------------------------------------------------
-
-        private class MyAnnotationVisitor extends AnnotationVisitor {
-
-            public MyAnnotationVisitor() {
-                super(Opcodes.ASM4);
-            }
-
-            // Visits a primitive value of an annotation
-            @Override
-            public void visit(String name, Object value) {
-                // value is the actual value, whose type must be Byte, Boolean, Character, Short,
-                // Integer, Long, Float, Double, String or Type
-                if (value instanceof Type) {
-                    considerType((Type) value);
-                }
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String name, String desc) {
-                // desc is the class descriptor of the nested annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public AnnotationVisitor visitArray(String name) {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitEnum(String name, String desc, String value) {
-                // desc is the class descriptor of the enumeration class.
-                considerDesc(desc);
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
deleted file mode 100644
index b102561..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ /dev/null
@@ -1,384 +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 com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.jar.JarEntry;
-import java.util.jar.JarOutputStream;
-
-/**
- * Class that generates a new JAR from a list of classes, some of which are to be kept as-is
- * and some of which are to be stubbed partially or totally.
- */
-public class AsmGenerator {
-
-    /** Output logger. */
-    private final Log mLog;
-    /** The path of the destination JAR to create. */
-    private final String mOsDestJar;
-    /** List of classes to inject in the final JAR from _this_ archive. */
-    private final Class<?>[] mInjectClasses;
-    /** The set of methods to stub out. */
-    private final Set<String> mStubMethods;
-    /** All classes to output as-is, except if they have native methods. */
-    private Map<String, ClassReader> mKeep;
-    /** All dependencies that must be completely stubbed. */
-    private Map<String, ClassReader> mDeps;
-    /** Counter of number of classes renamed during transform. */
-    private int mRenameCount;
-    /** FQCN Names of the classes to rename: map old-FQCN => new-FQCN */
-    private final HashMap<String, String> mRenameClasses;
-    /** FQCN Names of "old" classes that were NOT renamed. This starts with the full list of
-     *  old-FQCN to rename and they get erased as they get renamed. At the end, classes still
-     *  left here are not in the code base anymore and thus were not renamed. */
-    private HashSet<String> mClassesNotRenamed;
-    /** A map { FQCN => set { list of return types to delete from the FQCN } }. */
-    private HashMap<String, Set<String>> mDeleteReturns;
-    /** A map { FQCN => set { method names } } of methods to rewrite as delegates.
-     *  The special name {@link DelegateClassAdapter#ALL_NATIVES} can be used as in internal set. */
-    private final HashMap<String, Set<String>> mDelegateMethods;
-    /** FQCN Names of classes to refactor. All reference to old-FQCN will be updated to new-FQCN.
-     * map old-FQCN => new-FQCN */
-    private final HashMap<String, String> mRefactorClasses;
-
-    /**
-     * Creates a new generator that can generate the output JAR with the stubbed classes.
-     *
-     * @param log Output logger.
-     * @param osDestJar The path of the destination JAR to create.
-     * @param createInfo Creation parameters. Must not be null.
-     */
-    public AsmGenerator(Log log, String osDestJar, ICreateInfo createInfo) {
-        mLog = log;
-        mOsDestJar = osDestJar;
-        mInjectClasses = createInfo.getInjectedClasses();
-        mStubMethods = new HashSet<String>(Arrays.asList(createInfo.getOverriddenMethods()));
-
-        // Create the map/set of methods to change to delegates
-        mDelegateMethods = new HashMap<String, Set<String>>();
-        for (String signature : createInfo.getDelegateMethods()) {
-            int pos = signature.indexOf('#');
-            if (pos <= 0 || pos >= signature.length() - 1) {
-                continue;
-            }
-            String className = binaryToInternalClassName(signature.substring(0, pos));
-            String methodName = signature.substring(pos + 1);
-            Set<String> methods = mDelegateMethods.get(className);
-            if (methods == null) {
-                methods = new HashSet<String>();
-                mDelegateMethods.put(className, methods);
-            }
-            methods.add(methodName);
-        }
-        for (String className : createInfo.getDelegateClassNatives()) {
-            className = binaryToInternalClassName(className);
-            Set<String> methods = mDelegateMethods.get(className);
-            if (methods == null) {
-                methods = new HashSet<String>();
-                mDelegateMethods.put(className, methods);
-            }
-            methods.add(DelegateClassAdapter.ALL_NATIVES);
-        }
-
-        // Create the map of classes to rename.
-        mRenameClasses = new HashMap<String, String>();
-        mClassesNotRenamed = new HashSet<String>();
-        String[] renameClasses = createInfo.getRenamedClasses();
-        int n = renameClasses.length;
-        for (int i = 0; i < n; i += 2) {
-            assert i + 1 < n;
-            // The ASM class names uses "/" separators, whereas regular FQCN use "."
-            String oldFqcn = binaryToInternalClassName(renameClasses[i]);
-            String newFqcn = binaryToInternalClassName(renameClasses[i + 1]);
-            mRenameClasses.put(oldFqcn, newFqcn);
-            mClassesNotRenamed.add(oldFqcn);
-        }
-
-        // Create a map of classes to be refactored.
-        mRefactorClasses = new HashMap<String, String>();
-        String[] refactorClasses = createInfo.getJavaPkgClasses();
-        n = refactorClasses.length;
-        for (int i = 0; i < n; i += 2) {
-            assert i + 1 < n;
-            String oldFqcn = binaryToInternalClassName(refactorClasses[i]);
-            String newFqcn = binaryToInternalClassName(refactorClasses[i + 1]);
-            mRefactorClasses.put(oldFqcn, newFqcn);;
-        }
-
-        // create the map of renamed class -> return type of method to delete.
-        mDeleteReturns = new HashMap<String, Set<String>>();
-        String[] deleteReturns = createInfo.getDeleteReturns();
-        Set<String> returnTypes = null;
-        String renamedClass = null;
-        for (String className : deleteReturns) {
-            // if we reach the end of a section, add it to the main map
-            if (className == null) {
-                if (returnTypes != null) {
-                    mDeleteReturns.put(renamedClass, returnTypes);
-                }
-
-                renamedClass = null;
-                continue;
-            }
-
-            // if the renamed class is null, this is the beginning of a section
-            if (renamedClass == null) {
-                renamedClass = binaryToInternalClassName(className);
-                continue;
-            }
-
-            // just a standard return type, we add it to the list.
-            if (returnTypes == null) {
-                returnTypes = new HashSet<String>();
-            }
-            returnTypes.add(binaryToInternalClassName(className));
-        }
-    }
-
-    /**
-     * Returns the list of classes that have not been renamed yet.
-     * <p/>
-     * The names are "internal class names" rather than FQCN, i.e. they use "/" instead "."
-     * as package separators.
-     */
-    public Set<String> getClassesNotRenamed() {
-        return mClassesNotRenamed;
-    }
-
-    /**
-     * Utility that returns the internal ASM class name from a fully qualified binary class
-     * name. E.g. it returns android/view/View from android.view.View.
-     */
-    String binaryToInternalClassName(String className) {
-        if (className == null) {
-            return null;
-        } else {
-            return className.replace('.', '/');
-        }
-    }
-
-    /** Sets the map of classes to output as-is, except if they have native methods */
-    public void setKeep(Map<String, ClassReader> keep) {
-        mKeep = keep;
-    }
-
-    /** Sets the map of dependencies that must be completely stubbed */
-    public void setDeps(Map<String, ClassReader> deps) {
-        mDeps = deps;
-    }
-
-    /** Gets the map of classes to output as-is, except if they have native methods */
-    public Map<String, ClassReader> getKeep() {
-        return mKeep;
-    }
-
-    /** Gets the map of dependencies that must be completely stubbed */
-    public Map<String, ClassReader> getDeps() {
-        return mDeps;
-    }
-
-    /** Generates the final JAR */
-    public void generate() throws FileNotFoundException, IOException {
-        TreeMap<String, byte[]> all = new TreeMap<String, byte[]>();
-
-        for (Class<?> clazz : mInjectClasses) {
-            String name = classToEntryPath(clazz);
-            InputStream is = ClassLoader.getSystemResourceAsStream(name);
-            ClassReader cr = new ClassReader(is);
-            byte[] b = transform(cr, true /* stubNativesOnly */);
-            name = classNameToEntryPath(transformName(cr.getClassName()));
-            all.put(name, b);
-        }
-
-        for (Entry<String, ClassReader> entry : mDeps.entrySet()) {
-            ClassReader cr = entry.getValue();
-            byte[] b = transform(cr, true /* stubNativesOnly */);
-            String name = classNameToEntryPath(transformName(cr.getClassName()));
-            all.put(name, b);
-        }
-
-        for (Entry<String, ClassReader> entry : mKeep.entrySet()) {
-            ClassReader cr = entry.getValue();
-            byte[] b = transform(cr, true /* stubNativesOnly */);
-            String name = classNameToEntryPath(transformName(cr.getClassName()));
-            all.put(name, b);
-        }
-
-        mLog.info("# deps classes: %d", mDeps.size());
-        mLog.info("# keep classes: %d", mKeep.size());
-        mLog.info("# renamed     : %d", mRenameCount);
-
-        createJar(new FileOutputStream(mOsDestJar), all);
-        mLog.info("Created JAR file %s", mOsDestJar);
-    }
-
-    /**
-     * Writes the JAR file.
-     *
-     * @param outStream The file output stream were to write the JAR.
-     * @param all The map of all classes to output.
-     * @throws IOException if an I/O error has occurred
-     */
-    void createJar(FileOutputStream outStream, Map<String,byte[]> all) throws IOException {
-        JarOutputStream jar = new JarOutputStream(outStream);
-        for (Entry<String, byte[]> entry : all.entrySet()) {
-            String name = entry.getKey();
-            JarEntry jar_entry = new JarEntry(name);
-            jar.putNextEntry(jar_entry);
-            jar.write(entry.getValue());
-            jar.closeEntry();
-        }
-        jar.flush();
-        jar.close();
-    }
-
-    /**
-     * Utility method that converts a fully qualified java name into a JAR entry path
-     * e.g. for the input "android.view.View" it returns "android/view/View.class"
-     */
-    String classNameToEntryPath(String className) {
-        return className.replaceAll("\\.", "/").concat(".class");
-    }
-
-    /**
-     * Utility method to get the JAR entry path from a Class name.
-     * e.g. it returns someting like "com/foo/OuterClass$InnerClass1$InnerClass2.class"
-     */
-    private String classToEntryPath(Class<?> clazz) {
-        String name = "";
-        Class<?> parent;
-        while ((parent = clazz.getEnclosingClass()) != null) {
-            name = "$" + clazz.getSimpleName() + name;
-            clazz = parent;
-        }
-        return classNameToEntryPath(clazz.getCanonicalName() + name);
-    }
-
-    /**
-     * Transforms a class.
-     * <p/>
-     * There are 3 kind of transformations:
-     *
-     * 1- For "mock" dependencies classes, we want to remove all code from methods and replace
-     * by a stub. Native methods must be implemented with this stub too. Abstract methods are
-     * left intact. Modified classes must be overridable (non-private, non-final).
-     * Native methods must be made non-final, non-private.
-     *
-     * 2- For "keep" classes, we want to rewrite all native methods as indicated above.
-     * If a class has native methods, it must also be made non-private, non-final.
-     *
-     * Note that unfortunately static methods cannot be changed to non-static (since static and
-     * non-static are invoked differently.)
-     */
-    byte[] transform(ClassReader cr, boolean stubNativesOnly) {
-
-        boolean hasNativeMethods = hasNativeMethods(cr);
-
-        // Get the class name, as an internal name (e.g. com/android/SomeClass$InnerClass)
-        String className = cr.getClassName();
-
-        String newName = transformName(className);
-        // transformName returns its input argument if there's no need to rename the class
-        if (newName != className) {
-            mRenameCount++;
-            // This class is being renamed, so remove it from the list of classes not renamed.
-            mClassesNotRenamed.remove(className);
-        }
-
-        mLog.debug("Transform %s%s%s%s", className,
-                newName == className ? "" : " (renamed to " + newName + ")",
-                hasNativeMethods ? " -- has natives" : "",
-                stubNativesOnly ? " -- stub natives only" : "");
-
-        // Rewrite the new class from scratch, without reusing the constant pool from the
-        // original class reader.
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-
-        ClassVisitor cv = new RefactorClassAdapter(cw, mRefactorClasses);
-        if (newName != className) {
-            cv = new RenameClassAdapter(cv, className, newName);
-        }
-
-        cv = new TransformClassAdapter(mLog, mStubMethods,
-                mDeleteReturns.get(className),
-                newName, cv,
-                stubNativesOnly, stubNativesOnly || hasNativeMethods);
-
-        Set<String> delegateMethods = mDelegateMethods.get(className);
-        if (delegateMethods != null && !delegateMethods.isEmpty()) {
-            // If delegateMethods only contains one entry ALL_NATIVES and the class is
-            // known to have no native methods, just skip this step.
-            if (hasNativeMethods ||
-                    !(delegateMethods.size() == 1 &&
-                            delegateMethods.contains(DelegateClassAdapter.ALL_NATIVES))) {
-                cv = new DelegateClassAdapter(mLog, cv, className, delegateMethods);
-            }
-        }
-
-        cr.accept(cv, 0 /* flags */);
-        return cw.toByteArray();
-    }
-
-    /**
-     * Should this class be renamed, this returns the new name. Otherwise it returns the
-     * original name.
-     *
-     * @param className The internal ASM name of the class that may have to be renamed
-     * @return A new transformed name or the original input argument.
-     */
-    String transformName(String className) {
-        String newName = mRenameClasses.get(className);
-        if (newName != null) {
-            return newName;
-        }
-        int pos = className.indexOf('$');
-        if (pos > 0) {
-            // Is this an inner class of a renamed class?
-            String base = className.substring(0, pos);
-            newName = mRenameClasses.get(base);
-            if (newName != null) {
-                return newName + className.substring(pos);
-            }
-        }
-
-        return className;
-    }
-
-    /**
-     * Returns true if a class has any native methods.
-     */
-    boolean hasNativeMethods(ClassReader cr) {
-        ClassHasNativeVisitor cv = new ClassHasNativeVisitor();
-        cr.accept(cv, 0 /* flags */);
-        return cv.hasNativeMethods();
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
deleted file mode 100644
index 2c955fd..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
+++ /dev/null
@@ -1,102 +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 com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.VisibleForTesting;
-import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Indicates if a class contains any native methods.
- */
-public class ClassHasNativeVisitor extends ClassVisitor {
-    public ClassHasNativeVisitor() {
-        super(Opcodes.ASM4);
-    }
-
-    private boolean mHasNativeMethods = false;
-
-    public boolean hasNativeMethods() {
-        return mHasNativeMethods;
-    }
-
-    @VisibleForTesting(visibility=Visibility.PRIVATE)
-    protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
-        mHasNativeMethods = hasNativeMethods;
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature,
-            String superName, String[] interfaces) {
-        // pass
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void visitAttribute(Attribute attr) {
-        // pass
-    }
-
-    @Override
-    public void visitEnd() {
-        // pass
-    }
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc,
-            String signature, Object value) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName,
-            String innerName, int access) {
-        // pass
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-        if ((access & Opcodes.ACC_NATIVE) != 0) {
-            setHasNativeMethods(true, name);
-        }
-        return null;
-    }
-
-    @Override
-    public void visitOuterClass(String owner, String name, String desc) {
-        // pass
-    }
-
-    @Override
-    public void visitSource(String source, String debug) {
-        // pass
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
deleted file mode 100644
index f6779e3..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ /dev/null
@@ -1,243 +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 com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.java.AutoCloseable;
-import com.android.tools.layoutlib.java.Charsets;
-import com.android.tools.layoutlib.java.IntegralToString;
-import com.android.tools.layoutlib.java.Objects;
-import com.android.tools.layoutlib.java.UnsafeByteSequence;
-
-/**
- * Describes the work to be done by {@link AsmGenerator}.
- */
-public final class CreateInfo implements ICreateInfo {
-
-    /**
-     * Returns the list of class from layoutlib_create to inject in layoutlib.
-     * The list can be empty but must not be null.
-     */
-    @Override
-    public Class<?>[] getInjectedClasses() {
-        return INJECTED_CLASSES;
-    }
-
-    /**
-     * Returns the list of methods to rewrite as delegates.
-     * The list can be empty but must not be null.
-     */
-    @Override
-    public String[] getDelegateMethods() {
-        return DELEGATE_METHODS;
-    }
-
-    /**
-     * Returns the list of classes on which to delegate all native methods.
-     * The list can be empty but must not be null.
-     */
-    @Override
-    public String[] getDelegateClassNatives() {
-        return DELEGATE_CLASS_NATIVES;
-    }
-
-    /**
-     * Returns The list of methods to stub out. Each entry must be in the form
-     * "package.package.OuterClass$InnerClass#MethodName".
-     * The list can be empty but must not be null.
-     * <p/>
-     * This usage is deprecated. Please use method 'delegates' instead.
-     */
-    @Override
-    public String[] getOverriddenMethods() {
-        return OVERRIDDEN_METHODS;
-    }
-
-    /**
-     * Returns the list of classes to rename, must be an even list: the binary FQCN
-     * of class to replace followed by the new FQCN.
-     * The list can be empty but must not be null.
-     */
-    @Override
-    public String[] getRenamedClasses() {
-        return RENAMED_CLASSES;
-    }
-
-    /**
-     * Returns the list of classes for which the methods returning them should be deleted.
-     * The array contains a list of null terminated section starting with the name of the class
-     * to rename in which the methods are deleted, followed by a list of return types identifying
-     * the methods to delete.
-     * The list can be empty but must not be null.
-     */
-    @Override
-    public String[] getDeleteReturns() {
-        return DELETE_RETURNS;
-    }
-
-    /**
-     * Returns the list of classes to refactor, must be an even list: the binary FQCN of class to
-     * replace followed by the new FQCN. All references to the old class should be updated to the
-     * new class. The list can be empty but must not be null.
-     */
-    @Override
-    public String[] getJavaPkgClasses() {
-      return JAVA_PKG_CLASSES;
-    }
-    //-----
-
-    /**
-     * The list of class from layoutlib_create to inject in layoutlib.
-     */
-    private final static Class<?>[] INJECTED_CLASSES = new Class<?>[] {
-            OverrideMethod.class,
-            MethodListener.class,
-            MethodAdapter.class,
-            ICreateInfo.class,
-            CreateInfo.class,
-            LayoutlibDelegate.class,
-            /* Java package classes */
-            AutoCloseable.class,
-            Objects.class,
-            IntegralToString.class,
-            UnsafeByteSequence.class,
-            Charsets.class,
-        };
-
-    /**
-     * The list of methods to rewrite as delegates.
-     */
-    public final static String[] DELEGATE_METHODS = new String[] {
-        "android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;",
-        "android.content.res.Resources$Theme#obtainStyledAttributes",
-        "android.content.res.Resources$Theme#resolveAttribute",
-        "android.content.res.TypedArray#getValueAt",
-        "android.graphics.BitmapFactory#finishDecode",
-        "android.os.Handler#sendMessageAtTime",
-        "android.os.HandlerThread#run",
-        "android.os.Build#getString",
-        "android.text.format.DateFormat#is24HourFormat",
-        "android.text.format.Time#format1",
-        "android.view.Choreographer#getRefreshRate",
-        "android.view.Display#updateDisplayInfoLocked",
-        "android.view.LayoutInflater#rInflate",
-        "android.view.LayoutInflater#parseInclude",
-        "android.view.View#isInEditMode",
-        "android.view.ViewRootImpl#isInTouchMode",
-        "android.view.WindowManagerGlobal#getWindowManagerService",
-        "android.view.inputmethod.InputMethodManager#getInstance",
-        "com.android.internal.util.XmlUtils#convertValueToInt",
-        "com.android.internal.textservice.ITextServicesManager$Stub#asInterface",
-    };
-
-    /**
-     * The list of classes on which to delegate all native methods.
-     */
-    public final static String[] DELEGATE_CLASS_NATIVES = new String[] {
-        "android.animation.PropertyValuesHolder",
-        "android.graphics.AvoidXfermode",
-        "android.graphics.Bitmap",
-        "android.graphics.BitmapFactory",
-        "android.graphics.BitmapShader",
-        "android.graphics.BlurMaskFilter",
-        "android.graphics.Canvas",
-        "android.graphics.ColorFilter",
-        "android.graphics.ColorMatrixColorFilter",
-        "android.graphics.ComposePathEffect",
-        "android.graphics.ComposeShader",
-        "android.graphics.CornerPathEffect",
-        "android.graphics.DashPathEffect",
-        "android.graphics.DiscretePathEffect",
-        "android.graphics.DrawFilter",
-        "android.graphics.EmbossMaskFilter",
-        "android.graphics.LayerRasterizer",
-        "android.graphics.LightingColorFilter",
-        "android.graphics.LinearGradient",
-        "android.graphics.MaskFilter",
-        "android.graphics.Matrix",
-        "android.graphics.NinePatch",
-        "android.graphics.Paint",
-        "android.graphics.PaintFlagsDrawFilter",
-        "android.graphics.Path",
-        "android.graphics.PathDashPathEffect",
-        "android.graphics.PathEffect",
-        "android.graphics.PixelXorXfermode",
-        "android.graphics.PorterDuffColorFilter",
-        "android.graphics.PorterDuffXfermode",
-        "android.graphics.RadialGradient",
-        "android.graphics.Rasterizer",
-        "android.graphics.Region",
-        "android.graphics.Shader",
-        "android.graphics.SumPathEffect",
-        "android.graphics.SweepGradient",
-        "android.graphics.Typeface",
-        "android.graphics.Xfermode",
-        "android.os.SystemClock",
-        "android.text.AndroidBidi",
-        "android.util.FloatMath",
-        "android.view.Display",
-        "libcore.icu.DateIntervalFormat",
-        "libcore.icu.ICU",
-    };
-
-    /**
-     * The list of methods to stub out. Each entry must be in the form
-     *  "package.package.OuterClass$InnerClass#MethodName".
-     *  This usage is deprecated. Please use method 'delegates' instead.
-     */
-    private final static String[] OVERRIDDEN_METHODS = new String[] {
-    };
-
-    /**
-     *  The list of classes to rename, must be an even list: the binary FQCN
-     *  of class to replace followed by the new FQCN.
-     */
-    private final static String[] RENAMED_CLASSES =
-        new String[] {
-            "android.os.ServiceManager",                       "android.os._Original_ServiceManager",
-            "android.util.LruCache",                           "android.util._Original_LruCache",
-            "android.view.SurfaceView",                        "android.view._Original_SurfaceView",
-            "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager",
-            "android.webkit.WebView",                          "android.webkit._Original_WebView",
-            "com.android.internal.policy.PolicyManager",       "com.android.internal.policy._Original_PolicyManager",
-        };
-
-    /**
-     * The list of class references to update, must be an even list: the binary
-     * FQCN of class to replace followed by the new FQCN. The classes to
-     * replace are to be excluded from the output.
-     */
-    private final static String[] JAVA_PKG_CLASSES =
-        new String[] {
-            "java.lang.AutoCloseable",                         "com.android.tools.layoutlib.java.AutoCloseable",
-            "java.util.Objects",                               "com.android.tools.layoutlib.java.Objects",
-            "java.nio.charset.Charsets",                       "com.android.tools.layoutlib.java.Charsets",
-            "java.lang.IntegralToString",                      "com.android.tools.layoutlib.java.IntegralToString",
-            "java.lang.UnsafeByteSequence",                    "com.android.tools.layoutlib.java.UnsafeByteSequence",
-        };
-
-    /**
-     * List of classes for which the methods returning them should be deleted.
-     * The array contains a list of null terminated section starting with the name of the class
-     * to rename in which the methods are deleted, followed by a list of return types identifying
-     * the methods to delete.
-     */
-    private final static String[] DELETE_RETURNS =
-        new String[] {
-            null };                         // separator, for next class/methods list.
-}
-
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
deleted file mode 100644
index 927be97..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-import java.util.Set;
-
-/**
- * A {@link DelegateClassAdapter} can transform some methods from a class into
- * delegates that defer the call to an associated delegate class.
- * <p/>
- * This is used to override specific methods and or all native methods in classes.
- */
-public class DelegateClassAdapter extends ClassVisitor {
-
-    /** Suffix added to original methods. */
-    private static final String ORIGINAL_SUFFIX = "_Original";
-    private static String CONSTRUCTOR = "<init>";
-    private static String CLASS_INIT = "<clinit>";
-
-    public final static String ALL_NATIVES = "<<all_natives>>";
-
-    private final String mClassName;
-    private final Set<String> mDelegateMethods;
-    private final Log mLog;
-
-    /**
-     * Creates a new {@link DelegateClassAdapter} that can transform some methods
-     * from a class into delegates that defer the call to an associated delegate class.
-     * <p/>
-     * This is used to override specific methods and or all native methods in classes.
-     *
-     * @param log The logger object. Must not be null.
-     * @param cv the class visitor to which this adapter must delegate calls.
-     * @param className The internal class name of the class to visit,
-     *          e.g. <code>com/android/SomeClass$InnerClass</code>.
-     * @param delegateMethods The set of method names to modify and/or the
-     *          special constant {@link #ALL_NATIVES} to convert all native methods.
-     */
-    public DelegateClassAdapter(Log log,
-            ClassVisitor cv,
-            String className,
-            Set<String> delegateMethods) {
-        super(Opcodes.ASM4, cv);
-        mLog = log;
-        mClassName = className;
-        mDelegateMethods = delegateMethods;
-    }
-
-    //----------------------------------
-    // Methods from the ClassAdapter
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-
-        boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
-        boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
-
-        boolean useDelegate = (isNative && mDelegateMethods.contains(ALL_NATIVES)) ||
-                              mDelegateMethods.contains(name);
-
-        if (!useDelegate) {
-            // Not creating a delegate for this method, pass it as-is from the reader
-            // to the writer.
-            return super.visitMethod(access, name, desc, signature, exceptions);
-        }
-
-        if (useDelegate) {
-            if (CONSTRUCTOR.equals(name) || CLASS_INIT.equals(name)) {
-                // We don't currently support generating delegates for constructors.
-                throw new UnsupportedOperationException(
-                    String.format(
-                        "Delegate doesn't support overriding constructor %1$s:%2$s(%3$s)",  //$NON-NLS-1$
-                        mClassName, name, desc));
-            }
-        }
-
-        if (isNative) {
-            // Remove native flag
-            access = access & ~Opcodes.ACC_NATIVE;
-            MethodVisitor mwDelegate = super.visitMethod(access, name, desc, signature, exceptions);
-
-            DelegateMethodAdapter2 a = new DelegateMethodAdapter2(
-                    mLog, null /*mwOriginal*/, mwDelegate, mClassName, name, desc, isStatic);
-
-            // A native has no code to visit, so we need to generate it directly.
-            a.generateDelegateCode();
-
-            return mwDelegate;
-        }
-
-        // Given a non-native SomeClass.MethodName(), we want to generate 2 methods:
-        // - A copy of the original method named SomeClass.MethodName_Original().
-        //   The content is the original method as-is from the reader.
-        // - A brand new implementation of SomeClass.MethodName() which calls to a
-        //   non-existing method named SomeClass_Delegate.MethodName().
-        //   The implementation of this 'delegate' method is done in layoutlib_brigde.
-
-        int accessDelegate = access;
-        // change access to public for the original one
-        if (Main.sOptions.generatePublicAccess) {
-            access &= ~(Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE);
-            access |= Opcodes.ACC_PUBLIC;
-        }
-
-        MethodVisitor mwOriginal = super.visitMethod(access, name + ORIGINAL_SUFFIX,
-                                                     desc, signature, exceptions);
-        MethodVisitor mwDelegate = super.visitMethod(accessDelegate, name,
-                                                     desc, signature, exceptions);
-
-        DelegateMethodAdapter2 a = new DelegateMethodAdapter2(
-                mLog, mwOriginal, mwDelegate, mClassName, name, desc, isStatic);
-        return a;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter2.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter2.java
deleted file mode 100644
index 0000b22..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter2.java
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.util.ArrayList;
-
-/**
- * This method adapter generates delegate methods.
- * <p/>
- * Given a method {@code SomeClass.MethodName()}, this generates 1 or 2 methods:
- * <ul>
- * <li> A copy of the original method named {@code SomeClass.MethodName_Original()}.
- *   The content is the original method as-is from the reader.
- *   This step is omitted if the method is native, since it has no Java implementation.
- * <li> A brand new implementation of {@code SomeClass.MethodName()} which calls to a
- *   non-existing method named {@code SomeClass_Delegate.MethodName()}.
- *   The implementation of this 'delegate' method is done in layoutlib_brigde.
- * </ul>
- * A method visitor is generally constructed to generate a single method; however
- * here we might want to generate one or two depending on the context. To achieve
- * that, the visitor here generates the 'original' method and acts as a no-op if
- * no such method exists (e.g. when the original is a native method).
- * The delegate method is generated after the {@code visitEnd} of the original method
- * or by having the class adapter <em>directly</em> call {@link #generateDelegateCode()}
- * for native methods.
- * <p/>
- * When generating the 'delegate', the implementation generates a call to a class
- * class named <code>&lt;className&gt;_Delegate</code> with static methods matching
- * the methods to be overridden here. The methods have the same return type.
- * The argument type list is the same except the "this" reference is passed first
- * for non-static methods.
- * <p/>
- * A new annotation is added to these 'delegate' methods so that we can easily find them
- * for automated testing.
- * <p/>
- * This class isn't intended to be generic or reusable.
- * It is called by {@link DelegateClassAdapter}, which takes care of properly initializing
- * the two method writers for the original and the delegate class, as needed, with their
- * expected names.
- * <p/>
- * The class adapter also takes care of calling {@link #generateDelegateCode()} directly for
- * a native and use the visitor pattern for non-natives.
- * Note that native methods have, by definition, no code so there's nothing a visitor
- * can visit.
- * <p/>
- * Instances of this class are not re-usable.
- * The class adapter creates a new instance for each method.
- */
-class DelegateMethodAdapter2 extends MethodVisitor {
-
-    /** Suffix added to delegate classes. */
-    public static final String DELEGATE_SUFFIX = "_Delegate";
-
-    /** The parent method writer to copy of the original method.
-     *  Null when dealing with a native original method. */
-    private MethodVisitor mOrgWriter;
-    /** The parent method writer to generate the delegating method. Never null. */
-    private MethodVisitor mDelWriter;
-    /** The original method descriptor (return type + argument types.) */
-    private String mDesc;
-    /** True if the original method is static. */
-    private final boolean mIsStatic;
-    /** The internal class name (e.g. <code>com/android/SomeClass$InnerClass</code>.) */
-    private final String mClassName;
-    /** The method name. */
-    private final String mMethodName;
-    /** Logger object. */
-    private final Log mLog;
-
-    /** Array used to capture the first line number information from the original method
-     *  and duplicate it in the delegate. */
-    private Object[] mDelegateLineNumber;
-
-    /**
-     * Creates a new {@link DelegateMethodAdapter2} that will transform this method
-     * into a delegate call.
-     * <p/>
-     * See {@link DelegateMethodAdapter2} for more details.
-     *
-     * @param log The logger object. Must not be null.
-     * @param mvOriginal The parent method writer to copy of the original method.
-     *          Must be {@code null} when dealing with a native original method.
-     * @param mvDelegate The parent method writer to generate the delegating method.
-     *          Must never be null.
-     * @param className The internal class name of the class to visit,
-     *          e.g. <code>com/android/SomeClass$InnerClass</code>.
-     * @param methodName The simple name of the method.
-     * @param desc A method descriptor (c.f. {@link Type#getReturnType(String)} +
-     *          {@link Type#getArgumentTypes(String)})
-     * @param isStatic True if the method is declared static.
-     */
-    public DelegateMethodAdapter2(Log log,
-            MethodVisitor mvOriginal,
-            MethodVisitor mvDelegate,
-            String className,
-            String methodName,
-            String desc,
-            boolean isStatic) {
-        super(Opcodes.ASM4);
-        mLog = log;
-        mOrgWriter = mvOriginal;
-        mDelWriter = mvDelegate;
-        mClassName = className;
-        mMethodName = methodName;
-        mDesc = desc;
-        mIsStatic = isStatic;
-    }
-
-    /**
-     * Generates the new code for the method.
-     * <p/>
-     * For native methods, this must be invoked directly by {@link DelegateClassAdapter}
-     * (since they have no code to visit).
-     * <p/>
-     * Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
-     * return this instance of {@link DelegateMethodAdapter2} and let the normal visitor pattern
-     * invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
-     * this method will be invoked from {@link MethodVisitor#visitEnd()}.
-     */
-    public void generateDelegateCode() {
-        /*
-         * The goal is to generate a call to a static delegate method.
-         * If this method is non-static, the first parameter will be 'this'.
-         * All the parameters must be passed and then the eventual return type returned.
-         *
-         * Example, let's say we have a method such as
-         *   public void myMethod(int a, Object b, ArrayList<String> c) { ... }
-         *
-         * We'll want to create a body that calls a delegate method like this:
-         *   TheClass_Delegate.myMethod(this, a, b, c);
-         *
-         * If the method is non-static and the class name is an inner class (e.g. has $ in its
-         * last segment), we want to push the 'this' of the outer class first:
-         *   OuterClass_InnerClass_Delegate.myMethod(
-         *     OuterClass.this,
-         *     OuterClass$InnerClass.this,
-         *     a, b, c);
-         *
-         * Only one level of inner class is supported right now, for simplicity and because
-         * we don't need more.
-         *
-         * The generated class name is the current class name with "_Delegate" appended to it.
-         * One thing to realize is that we don't care about generics -- since generic types
-         * are erased at build time, they have no influence on the method name being called.
-         */
-
-        // Add our annotation
-        AnnotationVisitor aw = mDelWriter.visitAnnotation(
-                Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(),
-                true); // visible at runtime
-        if (aw != null) {
-            aw.visitEnd();
-        }
-
-        mDelWriter.visitCode();
-
-        if (mDelegateLineNumber != null) {
-            Object[] p = mDelegateLineNumber;
-            mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]);
-        }
-
-        ArrayList<Type> paramTypes = new ArrayList<Type>();
-        String delegateClassName = mClassName + DELEGATE_SUFFIX;
-        boolean pushedArg0 = false;
-        int maxStack = 0;
-
-        // Check if the last segment of the class name has inner an class.
-        // Right now we only support one level of inner classes.
-        Type outerType = null;
-        int slash = mClassName.lastIndexOf('/');
-        int dol = mClassName.lastIndexOf('$');
-        if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
-            String outerClass = mClassName.substring(0, dol);
-            outerType = Type.getObjectType(outerClass);
-
-            // Change a delegate class name to "com/foo/Outer_Inner_Delegate"
-            delegateClassName = delegateClassName.replace('$', '_');
-        }
-
-        // For an instance method (e.g. non-static), push the 'this' preceded
-        // by the 'this' of any outer class, if any.
-        if (!mIsStatic) {
-
-            if (outerType != null) {
-                // The first-level inner class has a package-protected member called 'this$0'
-                // that points to the outer class.
-
-                // Push this.getField("this$0") on the call stack.
-                mDelWriter.visitVarInsn(Opcodes.ALOAD, 0); // var 0 = this
-                mDelWriter.visitFieldInsn(Opcodes.GETFIELD,
-                        mClassName,                 // class where the field is defined
-                        "this$0",                   // field name
-                        outerType.getDescriptor()); // type of the field
-                maxStack++;
-                paramTypes.add(outerType);
-
-            }
-
-            // Push "this" for the instance method, which is always ALOAD 0
-            mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
-            maxStack++;
-            pushedArg0 = true;
-            paramTypes.add(Type.getObjectType(mClassName));
-        }
-
-        // Push all other arguments. Start at arg 1 if we already pushed 'this' above.
-        Type[] argTypes = Type.getArgumentTypes(mDesc);
-        int maxLocals = pushedArg0 ? 1 : 0;
-        for (Type t : argTypes) {
-            int size = t.getSize();
-            mDelWriter.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
-            maxLocals += size;
-            maxStack += size;
-            paramTypes.add(t);
-        }
-
-        // Construct the descriptor of the delegate based on the parameters
-        // we pushed on the call stack. The return type remains unchanged.
-        String desc = Type.getMethodDescriptor(
-                Type.getReturnType(mDesc),
-                paramTypes.toArray(new Type[paramTypes.size()]));
-
-        // Invoke the static delegate
-        mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC,
-                delegateClassName,
-                mMethodName,
-                desc);
-
-        Type returnType = Type.getReturnType(mDesc);
-        mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
-
-        mDelWriter.visitMaxs(maxStack, maxLocals);
-        mDelWriter.visitEnd();
-
-        // For debugging now. Maybe we should collect these and store them in
-        // a text file for helping create the delegates. We could also compare
-        // the text file to a golden and break the build on unsupported changes
-        // or regressions. Even better we could fancy-print something that looks
-        // like the expected Java method declaration.
-        mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
-    }
-
-    /* Pass down to visitor writer. In this implementation, either do nothing. */
-    @Override
-    public void visitCode() {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitCode();
-        }
-    }
-
-    /*
-     * visitMaxs is called just before visitEnd if there was any code to rewrite.
-     */
-    @Override
-    public void visitMaxs(int maxStack, int maxLocals) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitMaxs(maxStack, maxLocals);
-        }
-    }
-
-    /** End of visiting. Generate the delegating code. */
-    @Override
-    public void visitEnd() {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitEnd();
-        }
-        generateDelegateCode();
-    }
-
-    /* Writes all annotation from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        if (mOrgWriter != null) {
-            return mOrgWriter.visitAnnotation(desc, visible);
-        } else {
-            return null;
-        }
-    }
-
-    /* Writes all annotation default values from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotationDefault() {
-        if (mOrgWriter != null) {
-            return mOrgWriter.visitAnnotationDefault();
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-            boolean visible) {
-        if (mOrgWriter != null) {
-            return mOrgWriter.visitParameterAnnotation(parameter, desc, visible);
-        } else {
-            return null;
-        }
-    }
-
-    /* Writes all attributes from the original method. */
-    @Override
-    public void visitAttribute(Attribute attr) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitAttribute(attr);
-        }
-    }
-
-    /*
-     * Only writes the first line number present in the original code so that source
-     * viewers can direct to the correct method, even if the content doesn't match.
-     */
-    @Override
-    public void visitLineNumber(int line, Label start) {
-        // Capture the first line values for the new delegate method
-        if (mDelegateLineNumber == null) {
-            mDelegateLineNumber = new Object[] { line, start };
-        }
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLineNumber(line, start);
-        }
-    }
-
-    @Override
-    public void visitInsn(int opcode) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitInsn(opcode);
-        }
-    }
-
-    @Override
-    public void visitLabel(Label label) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLabel(label);
-        }
-    }
-
-    @Override
-    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitTryCatchBlock(start, end, handler, type);
-        }
-    }
-
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitMethodInsn(opcode, owner, name, desc);
-        }
-    }
-
-    @Override
-    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitFieldInsn(opcode, owner, name, desc);
-        }
-    }
-
-    @Override
-    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitFrame(type, nLocal, local, nStack, stack);
-        }
-    }
-
-    @Override
-    public void visitIincInsn(int var, int increment) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitIincInsn(var, increment);
-        }
-    }
-
-    @Override
-    public void visitIntInsn(int opcode, int operand) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitIntInsn(opcode, operand);
-        }
-    }
-
-    @Override
-    public void visitJumpInsn(int opcode, Label label) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitJumpInsn(opcode, label);
-        }
-    }
-
-    @Override
-    public void visitLdcInsn(Object cst) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLdcInsn(cst);
-        }
-    }
-
-    @Override
-    public void visitLocalVariable(String name, String desc, String signature,
-            Label start, Label end, int index) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLookupSwitchInsn(dflt, keys, labels);
-        }
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(String desc, int dims) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitMultiANewArrayInsn(desc, dims);
-        }
-    }
-
-    @Override
-    public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitTableSwitchInsn(min, max, dflt, labels);
-        }
-    }
-
-    @Override
-    public void visitTypeInsn(int opcode, String type) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitTypeInsn(opcode, type);
-        }
-    }
-
-    @Override
-    public void visitVarInsn(int opcode, int var) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitVarInsn(opcode, var);
-        }
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
deleted file mode 100644
index c988c70..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
+++ /dev/null
@@ -1,787 +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.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.VisibleForTesting;
-import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * Analyzes the input JAR using the ASM java bytecode manipulation library
- * to list the classes and their dependencies. A "dependency" is a class
- * used by another class.
- */
-public class DependencyFinder {
-
-    // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
-
-    /** Output logger. */
-    private final Log mLog;
-
-    /**
-     * Creates a new analyzer.
-     *
-     * @param log The log output.
-     */
-    public DependencyFinder(Log log) {
-        mLog = log;
-    }
-
-    /**
-     * Starts the analysis using parameters from the constructor.
-     *
-     * @param osJarPath The input source JARs to parse.
-     * @return A pair: [0]: map { class FQCN => set of FQCN class dependencies }.
-     *                 [1]: map { missing class FQCN => set of FQCN class that uses it. }
-     */
-    public List<Map<String, Set<String>>> findDeps(List<String> osJarPath) throws IOException {
-
-        Map<String, ClassReader> zipClasses = parseZip(osJarPath);
-        mLog.info("Found %d classes in input JAR%s.",
-                zipClasses.size(),
-                osJarPath.size() > 1 ? "s" : "");
-
-        Map<String, Set<String>> deps = findClassesDeps(zipClasses);
-
-        Map<String, Set<String>> missing = findMissingClasses(deps, zipClasses.keySet());
-
-        List<Map<String, Set<String>>> result = new ArrayList<Map<String,Set<String>>>(2);
-        result.add(deps);
-        result.add(missing);
-        return result;
-    }
-
-    /**
-     * Prints dependencies to the current logger, found stuff and missing stuff.
-     */
-    public void printAllDeps(List<Map<String, Set<String>>> result) {
-        assert result.size() == 2;
-        Map<String, Set<String>> deps = result.get(0);
-        Map<String, Set<String>> missing = result.get(1);
-
-        // Print all dependences found in the format:
-        // +Found: <FQCN from zip>
-        //     uses: FQCN
-
-        mLog.info("++++++ %d Entries found in source JARs", deps.size());
-        mLog.info("");
-
-        for (Entry<String, Set<String>> entry : deps.entrySet()) {
-            mLog.info(    "+Found  : %s", entry.getKey());
-            for (String dep : entry.getValue()) {
-                mLog.info("    uses: %s", dep);
-            }
-
-            mLog.info("");
-        }
-
-
-        // Now print all missing dependences in the format:
-        // -Missing <FQCN>:
-        //     used by: <FQCN>
-
-        mLog.info("");
-        mLog.info("------ %d Entries missing from source JARs", missing.size());
-        mLog.info("");
-
-        for (Entry<String, Set<String>> entry : missing.entrySet()) {
-            mLog.info(    "-Missing  : %s", entry.getKey());
-            for (String dep : entry.getValue()) {
-                mLog.info("   used by: %s", dep);
-            }
-
-            mLog.info("");
-        }
-    }
-
-    /**
-     * Prints only a summary of the missing dependencies to the current logger.
-     */
-    public void printMissingDeps(List<Map<String, Set<String>>> result) {
-        assert result.size() == 2;
-        @SuppressWarnings("unused") Map<String, Set<String>> deps = result.get(0);
-        Map<String, Set<String>> missing = result.get(1);
-
-        for (String fqcn : missing.keySet()) {
-            mLog.info("%s", fqcn);
-        }
-    }
-
-    // ----------------
-
-    /**
-     * Parses a JAR file and returns a list of all classes founds using a map
-     * class name => ASM ClassReader. Class names are in the form "android.view.View".
-     */
-    Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException {
-        TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>();
-
-        for (String jarPath : jarPathList) {
-            ZipFile zip = new ZipFile(jarPath);
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            ZipEntry entry;
-            while (entries.hasMoreElements()) {
-                entry = entries.nextElement();
-                if (entry.getName().endsWith(".class")) {
-                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
-                    String className = classReaderToClassName(cr);
-                    classes.put(className, cr);
-                }
-            }
-        }
-
-        return classes;
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name for a ClassReader.
-     * E.g. it returns something like android.view.View.
-     */
-    static String classReaderToClassName(ClassReader classReader) {
-        if (classReader == null) {
-            return null;
-        } else {
-            return classReader.getClassName().replace('/', '.');
-        }
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name from a path-like FQCN.
-     * E.g. it returns android.view.View from android/view/View.
-     */
-    static String internalToBinaryClassName(String className) {
-        if (className == null) {
-            return null;
-        } else {
-            return className.replace('/', '.');
-        }
-    }
-
-    /**
-     * Finds all dependencies for all classes in keepClasses which are also
-     * listed in zipClasses. Returns a map of all the dependencies found.
-     */
-    Map<String, Set<String>> findClassesDeps(Map<String, ClassReader> zipClasses) {
-
-        // The dependencies that we'll collect.
-        // It's a map Class name => uses class names.
-        Map<String, Set<String>> dependencyMap = new TreeMap<String, Set<String>>();
-
-        DependencyVisitor visitor = getVisitor();
-
-        int count = 0;
-        try {
-            for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
-                String name = entry.getKey();
-
-                TreeSet<String> set = new TreeSet<String>();
-                dependencyMap.put(name, set);
-                visitor.setDependencySet(set);
-
-                ClassReader cr = entry.getValue();
-                cr.accept(visitor, 0 /* flags */);
-
-                visitor.setDependencySet(null);
-
-                mLog.debugNoln("Visited %d classes\r", ++count);
-            }
-        } finally {
-            mLog.debugNoln("\n");
-        }
-
-        return dependencyMap;
-    }
-
-    /**
-     * Computes which classes FQCN were found as dependencies that are NOT listed
-     * in the original JAR classes.
-     *
-     * @param deps The map { FQCN => dependencies[] } returned by {@link #findClassesDeps(Map)}.
-     * @param zipClasses The set of all classes FQCN found in the JAR files.
-     * @return A map { FQCN not found in the zipClasses => classes using it }
-     */
-    private Map<String, Set<String>> findMissingClasses(
-            Map<String, Set<String>> deps,
-            Set<String> zipClasses) {
-        Map<String, Set<String>> missing = new TreeMap<String, Set<String>>();
-
-        for (Entry<String, Set<String>> entry : deps.entrySet()) {
-            String name = entry.getKey();
-
-            for (String dep : entry.getValue()) {
-                if (!zipClasses.contains(dep)) {
-                    // This dependency doesn't exist in the zip classes.
-                    Set<String> set = missing.get(dep);
-                    if (set == null) {
-                        set = new TreeSet<String>();
-                        missing.put(dep, set);
-                    }
-                    set.add(name);
-                }
-            }
-
-        }
-
-        return missing;
-    }
-
-
-    // ----------------------------------
-
-    /**
-     * Instantiates a new DependencyVisitor. Useful for unit tests.
-     */
-    @VisibleForTesting(visibility=Visibility.PRIVATE)
-    DependencyVisitor getVisitor() {
-        return new DependencyVisitor();
-    }
-
-    /**
-     * Visitor to collect all the type dependencies from a class.
-     */
-    public class DependencyVisitor extends ClassVisitor {
-
-        private Set<String> mCurrentDepSet;
-
-        /**
-         * Creates a new visitor that will find all the dependencies for the visited class.
-         */
-        public DependencyVisitor() {
-            super(Opcodes.ASM4);
-        }
-
-        /**
-         * Sets the {@link Set} where to record direct dependencies for this class.
-         * This will change before each {@link ClassReader#accept(ClassVisitor, int)} call.
-         */
-        public void setDependencySet(Set<String> set) {
-            mCurrentDepSet = set;
-        }
-
-        /**
-         * Considers the given class name as a dependency.
-         */
-        public void considerName(String className) {
-            if (className == null) {
-                return;
-            }
-
-            className = internalToBinaryClassName(className);
-
-            try {
-                // exclude classes that are part of the default JRE (the one executing this program)
-                if (getClass().getClassLoader().loadClass(className) != null) {
-                    return;
-                }
-            } catch (ClassNotFoundException e) {
-                // ignore
-            }
-
-            // Add it to the dependency set for the currently visited class, as needed.
-            assert mCurrentDepSet != null;
-            if (mCurrentDepSet != null) {
-                mCurrentDepSet.add(className);
-            }
-        }
-
-        /**
-         * Considers this array of names using considerName().
-         */
-        public void considerNames(String[] classNames) {
-            if (classNames != null) {
-                for (String className : classNames) {
-                    considerName(className);
-                }
-            }
-        }
-
-        /**
-         * Considers this signature or type signature by invoking the {@link SignatureVisitor}
-         * on it.
-         */
-        public void considerSignature(String signature) {
-            if (signature != null) {
-                SignatureReader sr = new SignatureReader(signature);
-                // SignatureReader.accept will call accessType so we don't really have
-                // to differentiate where the signature comes from.
-                sr.accept(new MySignatureVisitor());
-            }
-        }
-
-        /**
-         * Considers this {@link Type}. For arrays, the element type is considered.
-         * If the type is an object, it's internal name is considered.
-         */
-        public void considerType(Type t) {
-            if (t != null) {
-                if (t.getSort() == Type.ARRAY) {
-                    t = t.getElementType();
-                }
-                if (t.getSort() == Type.OBJECT) {
-                    considerName(t.getInternalName());
-                }
-            }
-        }
-
-        /**
-         * Considers a descriptor string. The descriptor is converted to a {@link Type}
-         * and then considerType() is invoked.
-         */
-        public boolean considerDesc(String desc) {
-            if (desc != null) {
-                try {
-                    if (desc.length() > 0 && desc.charAt(0) == '(') {
-                        // This is a method descriptor with arguments and a return type.
-                        Type t = Type.getReturnType(desc);
-                        considerType(t);
-
-                        for (Type arg : Type.getArgumentTypes(desc)) {
-                            considerType(arg);
-                        }
-
-                    } else {
-                        Type t = Type.getType(desc);
-                        considerType(t);
-                    }
-                    return true;
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    // ignore, not a valid type.
-                }
-            }
-            return false;
-        }
-
-
-        // ---------------------------------------------------
-        // --- ClassVisitor, FieldVisitor
-        // ---------------------------------------------------
-
-        // Visits a class header
-        @Override
-        public void visit(int version, int access, String name,
-                String signature, String superName, String[] interfaces) {
-            // signature is the signature of this class. May be null if the class is not a generic
-            // one, and does not extend or implement generic classes or interfaces.
-
-            if (signature != null) {
-                considerSignature(signature);
-            }
-
-            // superName is the internal of name of the super class (see getInternalName).
-            // For interfaces, the super class is Object. May be null but only for the Object class.
-            considerName(superName);
-
-            // interfaces is the internal names of the class's interfaces (see getInternalName).
-            // May be null.
-            considerNames(interfaces);
-        }
-
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            // desc is the class descriptor of the annotation class.
-            considerDesc(desc);
-            return new MyAnnotationVisitor();
-        }
-
-        @Override
-        public void visitAttribute(Attribute attr) {
-            // pass
-        }
-
-        // Visits the end of a class
-        @Override
-        public void visitEnd() {
-            // pass
-        }
-
-        private class MyFieldVisitor extends FieldVisitor {
-
-            public MyFieldVisitor() {
-                super(Opcodes.ASM4);
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitAttribute(Attribute attr) {
-                // pass
-            }
-
-            // Visits the end of a class
-            @Override
-            public void visitEnd() {
-                // pass
-            }
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc,
-                String signature, Object value) {
-            // desc is the field's descriptor (see Type).
-            considerDesc(desc);
-
-            // signature is the field's signature. May be null if the field's type does not use
-            // generic types.
-            considerSignature(signature);
-
-            return new MyFieldVisitor();
-        }
-
-        @Override
-        public void visitInnerClass(String name, String outerName, String innerName, int access) {
-            // name is the internal name of an inner class (see getInternalName).
-            // Note: outerName/innerName seems to be null when we're reading the
-            // _Original_ClassName classes generated by layoutlib_create.
-            if (outerName != null) {
-                considerName(name);
-            }
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc,
-                String signature, String[] exceptions) {
-            // desc is the method's descriptor (see Type).
-            considerDesc(desc);
-            // signature is the method's signature. May be null if the method parameters, return
-            // type and exceptions do not use generic types.
-            considerSignature(signature);
-
-            return new MyMethodVisitor();
-        }
-
-        @Override
-        public void visitOuterClass(String owner, String name, String desc) {
-            // pass
-        }
-
-        @Override
-        public void visitSource(String source, String debug) {
-            // pass
-        }
-
-
-        // ---------------------------------------------------
-        // --- MethodVisitor
-        // ---------------------------------------------------
-
-        private class MyMethodVisitor extends MethodVisitor {
-
-            public MyMethodVisitor() {
-                super(Opcodes.ASM4);
-            }
-
-
-            @Override
-            public AnnotationVisitor visitAnnotationDefault() {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitCode() {
-                // pass
-            }
-
-            // field instruction
-            @Override
-            public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-                // name is the field's name.
-                // desc is the field's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            @Override
-            public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
-                // pass
-            }
-
-            @Override
-            public void visitIincInsn(int var, int increment) {
-                // pass -- an IINC instruction
-            }
-
-            @Override
-            public void visitInsn(int opcode) {
-                // pass -- a zero operand instruction
-            }
-
-            @Override
-            public void visitIntInsn(int opcode, int operand) {
-                // pass -- a single int operand instruction
-            }
-
-            @Override
-            public void visitJumpInsn(int opcode, Label label) {
-                // pass -- a jump instruction
-            }
-
-            @Override
-            public void visitLabel(Label label) {
-                // pass -- a label target
-            }
-
-            // instruction to load a constant from the stack
-            @Override
-            public void visitLdcInsn(Object cst) {
-                if (cst instanceof Type) {
-                    considerType((Type) cst);
-                }
-            }
-
-            @Override
-            public void visitLineNumber(int line, Label start) {
-                // pass
-            }
-
-            @Override
-            public void visitLocalVariable(String name, String desc,
-                    String signature, Label start, Label end, int index) {
-                // desc is the type descriptor of this local variable.
-                considerDesc(desc);
-                // signature is the type signature of this local variable. May be null if the local
-                // variable type does not use generic types.
-                considerSignature(signature);
-            }
-
-            @Override
-            public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-                // pass -- a lookup switch instruction
-            }
-
-            @Override
-            public void visitMaxs(int maxStack, int maxLocals) {
-                // pass
-            }
-
-            // instruction that invokes a method
-            @Override
-            public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-
-                // owner is the internal name of the method's owner class
-                if (!considerDesc(owner) && owner.indexOf('/') != -1) {
-                    considerName(owner);
-                }
-                // desc is the method's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            // instruction multianewarray, whatever that is
-            @Override
-            public void visitMultiANewArrayInsn(String desc, int dims) {
-
-                // desc an array type descriptor.
-                considerDesc(desc);
-            }
-
-            @Override
-            public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-                    boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-                // pass -- table switch instruction
-
-            }
-
-            @Override
-            public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-                // type is the internal name of the type of exceptions handled by the handler,
-                // or null to catch any exceptions (for "finally" blocks).
-                considerName(type);
-            }
-
-            // type instruction
-            @Override
-            public void visitTypeInsn(int opcode, String type) {
-                // type is the operand of the instruction to be visited. This operand must be the
-                // internal name of an object or array class.
-                considerName(type);
-            }
-
-            @Override
-            public void visitVarInsn(int opcode, int var) {
-                // pass -- local variable instruction
-            }
-        }
-
-        private class MySignatureVisitor extends SignatureVisitor {
-
-            public MySignatureVisitor() {
-                super(Opcodes.ASM4);
-            }
-
-            // ---------------------------------------------------
-            // --- SignatureVisitor
-            // ---------------------------------------------------
-
-            private String mCurrentSignatureClass = null;
-
-            // Starts the visit of a signature corresponding to a class or interface type
-            @Override
-            public void visitClassType(String name) {
-                mCurrentSignatureClass = name;
-                considerName(name);
-            }
-
-            // Visits an inner class
-            @Override
-            public void visitInnerClassType(String name) {
-                if (mCurrentSignatureClass != null) {
-                    mCurrentSignatureClass += "$" + name;
-                    considerName(mCurrentSignatureClass);
-                }
-            }
-
-            @Override
-            public SignatureVisitor visitArrayType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitBaseType(char descriptor) {
-                // pass -- a primitive type, ignored
-            }
-
-            @Override
-            public SignatureVisitor visitClassBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitExceptionType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitFormalTypeParameter(String name) {
-                // pass
-            }
-
-            @Override
-            public SignatureVisitor visitInterface() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitInterfaceBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitParameterType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitReturnType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitSuperclass() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitTypeArgument(char wildcard) {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitTypeVariable(String name) {
-                // pass
-            }
-
-            @Override
-            public void visitTypeArgument() {
-                // pass
-            }
-        }
-
-
-        // ---------------------------------------------------
-        // --- AnnotationVisitor
-        // ---------------------------------------------------
-
-        private class MyAnnotationVisitor extends AnnotationVisitor {
-
-            public MyAnnotationVisitor() {
-                super(Opcodes.ASM4);
-            }
-
-            // Visits a primitive value of an annotation
-            @Override
-            public void visit(String name, Object value) {
-                // value is the actual value, whose type must be Byte, Boolean, Character, Short,
-                // Integer, Long, Float, Double, String or Type
-                if (value instanceof Type) {
-                    considerType((Type) value);
-                }
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String name, String desc) {
-                // desc is the class descriptor of the nested annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public AnnotationVisitor visitArray(String name) {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitEnum(String name, String desc, String value) {
-                // desc is the class descriptor of the enumeration class.
-                considerDesc(desc);
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
deleted file mode 100644
index 9387814..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-/**
- * Interface describing the work to be done by {@link AsmGenerator}.
- */
-public interface ICreateInfo {
-
-    /**
-     * Returns the list of class from layoutlib_create to inject in layoutlib.
-     * The list can be empty but must not be null.
-     */
-    public abstract Class<?>[] getInjectedClasses();
-
-    /**
-     * Returns the list of methods to rewrite as delegates.
-     * The list can be empty but must not be null.
-     */
-    public abstract String[] getDelegateMethods();
-
-    /**
-     * Returns the list of classes on which to delegate all native methods.
-     * The list can be empty but must not be null.
-     */
-    public abstract String[] getDelegateClassNatives();
-
-    /**
-     * Returns The list of methods to stub out. Each entry must be in the form
-     * "package.package.OuterClass$InnerClass#MethodName".
-     * The list can be empty but must not be null.
-     */
-    public abstract String[] getOverriddenMethods();
-
-    /**
-     * Returns the list of classes to rename, must be an even list: the binary FQCN
-     * of class to replace followed by the new FQCN.
-     * The list can be empty but must not be null.
-     */
-    public abstract String[] getRenamedClasses();
-
-    /**
-     * Returns the list of classes for which the methods returning them should be deleted.
-     * The array contains a list of null terminated section starting with the name of the class
-     * to rename in which the methods are deleted, followed by a list of return types identifying
-     * the methods to delete.
-     * The list can be empty but must not be null.
-     */
-    public abstract String[] getDeleteReturns();
-
-    /**
-     * Returns the list of classes to refactor, must be an even list: the
-     * binary FQCN of class to replace followed by the new FQCN. All references
-     * to the old class should be updated to the new class.
-     * The list can be empty but must not be null.
-     */
-    public abstract String[] getJavaPkgClasses();
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
deleted file mode 100644
index c3ba591..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
+++ /dev/null
@@ -1,72 +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 com.android.tools.layoutlib.create;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-public class Log {
-
-    private boolean mVerbose = false;
-
-    public void setVerbose(boolean verbose) {
-        mVerbose = verbose;
-    }
-
-    public void debug(String format, Object... args) {
-        if (mVerbose) {
-            info(format, args);
-        }
-    }
-
-    /** Similar to debug() but doesn't do a \n automatically. */
-    public void debugNoln(String format, Object... args) {
-        if (mVerbose) {
-            String s = String.format(format, args);
-            System.out.print(s);
-        }
-    }
-
-    public void info(String format, Object... args) {
-        String s = String.format(format, args);
-        outPrintln(s);
-    }
-
-    public void error(String format, Object... args) {
-        String s = String.format(format, args);
-        errPrintln(s);
-    }
-
-    public void exception(Throwable t, String format, Object... args) {
-        StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw);
-        t.printStackTrace(pw);
-        pw.flush();
-        error(format + "\n" + sw.toString(), args);
-    }
-
-    /** for unit testing */
-    protected void errPrintln(String msg) {
-        System.err.println(msg);
-    }
-
-    /** for unit testing */
-    protected void outPrintln(String msg) {
-        System.out.println(msg);
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java
deleted file mode 100644
index dc4b4a7..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-public class LogAbortException extends Exception {
-
-    private final String mFormat;
-    private final Object[] mArgs;
-
-    public LogAbortException(String format, Object... args) {
-        mFormat = format;
-        mArgs = args;
-    }
-    
-    public void error(Log log) {
-        log.error(mFormat, mArgs);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
deleted file mode 100644
index ee501d2..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ /dev/null
@@ -1,227 +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 com.android.tools.layoutlib.create;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-
-/**
- * Entry point for the layoutlib_create tool.
- * <p/>
- * The tool does not currently rely on any external configuration file.
- * Instead the configuration is mostly done via the {@link CreateInfo} class.
- * <p/>
- * For a complete description of the tool and its implementation, please refer to
- * the "README.txt" file at the root of this project.
- * <p/>
- * For a quick test, invoke this as follows:
- * <pre>
- * $ make layoutlib
- * </pre>
- * which does:
- * <pre>
- * $ make layoutlib_create &lt;bunch of framework jars&gt;
- * $ java -jar out/host/linux-x86/framework/layoutlib_create.jar \
- *        out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar \
- *        out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar \
- *        out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
- * </pre>
- */
-public class Main {
-
-    public static class Options {
-        public boolean generatePublicAccess = true;
-        public boolean listAllDeps = false;
-        public boolean listOnlyMissingDeps = false;
-    }
-
-    public static final Options sOptions = new Options();
-
-    public static void main(String[] args) {
-
-        Log log = new Log();
-
-        ArrayList<String> osJarPath = new ArrayList<String>();
-        String[] osDestJar = { null };
-
-        if (!processArgs(log, args, osJarPath, osDestJar)) {
-            log.error("Usage: layoutlib_create [-v] [-p] output.jar input.jar ...");
-            log.error("Usage: layoutlib_create [-v] [--list-deps|--missing-deps] input.jar ...");
-            System.exit(1);
-        }
-
-        if (sOptions.listAllDeps || sOptions.listOnlyMissingDeps) {
-            System.exit(listDeps(osJarPath, log));
-
-        } else {
-            System.exit(createLayoutLib(osDestJar[0], osJarPath, log));
-        }
-
-
-        System.exit(1);
-    }
-
-    private static int createLayoutLib(String osDestJar, ArrayList<String> osJarPath, Log log) {
-        log.info("Output: %1$s", osDestJar);
-        for (String path : osJarPath) {
-            log.info("Input :      %1$s", path);
-        }
-
-        try {
-            CreateInfo info = new CreateInfo();
-            Set<String> excludeClasses = getExcludedClasses(info);
-            AsmGenerator agen = new AsmGenerator(log, osDestJar, info);
-
-            AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath, agen,
-                    new String[] {                          // derived from
-                        "android.view.View",
-                        "android.app.Fragment"
-                    },
-                    new String[] {                          // include classes
-                        "android.*", // for android.R
-                        "android.util.*",
-                        "com.android.internal.util.*",
-                        "android.view.*",
-                        "android.widget.*",
-                        "com.android.internal.widget.*",
-                        "android.text.**",
-                        "android.graphics.*",
-                        "android.graphics.drawable.*",
-                        "android.content.*",
-                        "android.content.res.*",
-                        "org.apache.harmony.xml.*",
-                        "com.android.internal.R**",
-                        "android.pim.*", // for datepicker
-                        "android.os.*",  // for android.os.Handler
-                        "android.database.ContentObserver", // for Digital clock
-                        "com.android.i18n.phonenumbers.*",  // for TextView with autolink attribute
-                    },
-                    excludeClasses);
-            aa.analyze();
-            agen.generate();
-
-            // Throw an error if any class failed to get renamed by the generator
-            //
-            // IMPORTANT: if you're building the platform and you get this error message,
-            // it means the renameClasses[] array in AsmGenerator needs to be updated: some
-            // class should have been renamed but it was not found in the input JAR files.
-            Set<String> notRenamed = agen.getClassesNotRenamed();
-            if (notRenamed.size() > 0) {
-                // (80-column guide below for error formatting)
-                // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
-                log.error(
-                  "ERROR when running layoutlib_create: the following classes are referenced\n" +
-                  "by tools/layoutlib/create but were not actually found in the input JAR files.\n" +
-                  "This may be due to some platform classes having been renamed.");
-                for (String fqcn : notRenamed) {
-                    log.error("- Class not found: %s", fqcn.replace('/', '.'));
-                }
-                for (String path : osJarPath) {
-                    log.info("- Input JAR : %1$s", path);
-                }
-                return 1;
-            }
-
-            return 0;
-        } catch (IOException e) {
-            log.exception(e, "Failed to load jar");
-        } catch (LogAbortException e) {
-            e.error(log);
-        }
-
-        return 1;
-    }
-
-    private static Set<String> getExcludedClasses(CreateInfo info) {
-        String[] refactoredClasses = info.getJavaPkgClasses();
-        Set<String> excludedClasses = new HashSet<String>(refactoredClasses.length);
-        for (int i = 0; i < refactoredClasses.length; i+=2) {
-            excludedClasses.add(refactoredClasses[i]);
-        }
-        return excludedClasses;
-
-    }
-
-    private static int listDeps(ArrayList<String> osJarPath, Log log) {
-        DependencyFinder df = new DependencyFinder(log);
-        try {
-            List<Map<String, Set<String>>> result = df.findDeps(osJarPath);
-            if (sOptions.listAllDeps) {
-                df.printAllDeps(result);
-            } else if (sOptions.listOnlyMissingDeps) {
-                df.printMissingDeps(result);
-            }
-        } catch (IOException e) {
-            log.exception(e, "Failed to load jar");
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns true if args where properly parsed.
-     * Returns false if program should exit with command-line usage.
-     * <p/>
-     * Note: the String[0] is an output parameter wrapped in an array, since there is no
-     * "out" parameter support.
-     */
-    private static boolean processArgs(Log log, String[] args,
-            ArrayList<String> osJarPath, String[] osDestJar) {
-        boolean needs_dest = true;
-        for (int i = 0; i < args.length; i++) {
-            String s = args[i];
-            if (s.equals("-v")) {
-                log.setVerbose(true);
-            } else if (s.equals("-p")) {
-                sOptions.generatePublicAccess = false;
-            } else if (s.equals("--list-deps")) {
-                sOptions.listAllDeps = true;
-                needs_dest = false;
-            } else if (s.equals("--missing-deps")) {
-                sOptions.listOnlyMissingDeps = true;
-                needs_dest = false;
-            } else if (!s.startsWith("-")) {
-                if (needs_dest && osDestJar[0] == null) {
-                    osDestJar[0] = s;
-                } else {
-                    osJarPath.add(s);
-                }
-            } else {
-                log.error("Unknow argument: %s", s);
-                return false;
-            }
-        }
-
-        if (osJarPath.isEmpty()) {
-            log.error("Missing parameter: path to input jar");
-            return false;
-        }
-        if (needs_dest && osDestJar[0] == null) {
-            log.error("Missing parameter: path to output jar");
-            return false;
-        }
-
-        sOptions.generatePublicAccess = false;
-
-        return true;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java
deleted file mode 100644
index 7d1e4cf..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java
+++ /dev/null
@@ -1,97 +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 com.android.tools.layoutlib.create;
-
-
-/**
- * An adapter to make it easier to use {@link MethodListener}.
- * <p/>
- * The adapter calls the void {@link #onInvokeV(String, boolean, Object)} listener
- * for all types (I, L, F, D and A), returning 0 or null as appropriate.
- */
-public class MethodAdapter implements MethodListener {
-    /**
-     * A stub method is being invoked.
-     * <p/>
-     * Known limitation: caller arguments are not available.
-     *
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
-     * @param isNative True if the method was a native method.
-     * @param caller The calling object. Null for static methods, "this" for instance methods.
-     */
-    @Override
-    public void onInvokeV(String signature, boolean isNative, Object caller) {
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an integer, or a boolean, or a short or a byte.
-     */
-    @Override
-    public int onInvokeI(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a long.
-     */
-    @Override
-    public long onInvokeL(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a float.
-     */
-    @Override
-    public float onInvokeF(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a double.
-     */
-    @Override
-    public double onInvokeD(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an object.
-     */
-    @Override
-    public Object onInvokeA(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return null;
-    }
-}
-
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java
deleted file mode 100644
index 6fc2b24..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java
+++ /dev/null
@@ -1,76 +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 com.android.tools.layoutlib.create;
-
-
-/**
- * Interface to allow a method invocation to be listened upon.
- * <p/>
- * This is used by {@link OverrideMethod} to register a listener for methods that
- * have been stubbed by the {@link AsmGenerator}. At runtime the stub will call either a
- * default global listener or a specific listener based on the method signature.
- */
-public interface MethodListener {
-    /**
-     * A stub method is being invoked.
-     * <p/>
-     * Known limitation: caller arguments are not available.
-     *  
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
-     * @param isNative True if the method was a native method.
-     * @param caller The calling object. Null for static methods, "this" for instance methods.
-     */
-    public void onInvokeV(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an integer, or a boolean, or a short or a byte.
-     */
-    public int onInvokeI(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a long.
-     */
-    public long onInvokeL(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a float.
-     */
-    public float onInvokeF(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a double.
-     */
-    public double onInvokeD(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an object.
-     */
-    public Object onInvokeA(String signature, boolean isNative, Object caller);
-}
-    
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
deleted file mode 100644
index a6aff99..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
+++ /dev/null
@@ -1,151 +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 com.android.tools.layoutlib.create;
-
-import java.util.HashMap;
-
-/**
- * Allows stub methods from LayoutLib to be overriden at runtime.
- * <p/>
- * Implementation note: all types required by this class(inner/outer classes & interfaces)
- * must be referenced by the injectClass argument to {@link AsmGenerator} in Main.java;
- * Otherwise they won't be accessible in layoutlib.jar at runtime.
- */
-public final class OverrideMethod {
-
-    /** Map of method overridden. */
-    private static HashMap<String, MethodListener> sMethods = new HashMap<String, MethodListener>();
-    /** Default listener for all method not listed in sMethods. Nothing if null. */
-    private static MethodListener sDefaultListener = null;
-    
-    /**
-     * Sets the default listener for all methods not specifically handled.
-     * Null means to do nothing.
-     */
-    public static void setDefaultListener(MethodListener listener) {
-        sDefaultListener = listener;
-    }
-
-    /**
-     * Defines or reset a listener for the given method signature.
-     * 
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V"
-     * @param listener The new listener. Removes it if null.
-     */
-    public static void setMethodListener(String signature, MethodListener listener) {
-        if (listener == null) {
-            sMethods.remove(signature);
-        } else {
-            sMethods.put(signature, listener);
-        }
-    }
-    
-    /**
-     * Invokes the specific listener for the given signature or the default one if defined.
-     * <p/>
-     * This version invokes the method listener for the void return type. 
-     * <p/>
-     * Note: this is not intended to be used by the LayoutLib Bridge. It is intended to be called
-     * by the stubbed methods generated by the LayoutLib_create tool.
-     * 
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
-     * @param isNative True if the method was a native method.
-     * @param caller The calling object. Null for static methods, "this" for instance methods.
-     */
-    public static void invokeV(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            i.onInvokeV(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            sDefaultListener.onInvokeV(signature, isNative, caller);
-        }
-    }
-    
-    /**
-     * Invokes the specific listener for the int return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static int invokeI(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeI(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeI(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the long return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static long invokeL(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeL(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeL(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the float return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static float invokeF(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeF(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeF(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the double return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static double invokeD(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeD(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeD(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the object return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static Object invokeA(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeA(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeA(signature, isNative, caller);
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java
deleted file mode 100644
index 91161f5..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java
+++ /dev/null
@@ -1,49 +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.tools.layoutlib.create;
-
-import java.util.HashMap;
-
-import org.objectweb.asm.ClassVisitor;
-
-public class RefactorClassAdapter extends AbstractClassAdapter {
-
-    private final HashMap<String, String> mRefactorClasses;
-
-    RefactorClassAdapter(ClassVisitor cv, HashMap<String, String> refactorClasses) {
-        super(cv);
-        mRefactorClasses = refactorClasses;
-    }
-
-    @Override
-    protected String renameInternalType(String oldClassName) {
-        if (oldClassName != null) {
-            String newName = mRefactorClasses.get(oldClassName);
-            if (newName != null) {
-                return newName;
-            }
-            int pos = oldClassName.indexOf('$');
-            if (pos > 0) {
-                newName = mRefactorClasses.get(oldClassName.substring(0, pos));
-                if (newName != null) {
-                    return newName + oldClassName.substring(pos);
-                }
-            }
-        }
-        return oldClassName;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
deleted file mode 100644
index 661074c..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
+++ /dev/null
@@ -1,87 +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 com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-
-/**
- * This class visitor renames a class from a given old name to a given new name.
- * The class visitor will also rename all inner classes and references in the methods.
- * <p/>
- *
- * For inner classes, this handles only the case where the outer class name changes.
- * The inner class name should remain the same.
- */
-public class RenameClassAdapter extends AbstractClassAdapter {
-
-
-    private final String mOldName;
-    private final String mNewName;
-    private String mOldBase;
-    private String mNewBase;
-
-    /**
-     * Creates a class visitor that renames a class from a given old name to a given new name.
-     * The class visitor will also rename all inner classes and references in the methods.
-     * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
-     */
-    public RenameClassAdapter(ClassVisitor cv, String oldName, String newName) {
-        super(cv);
-        mOldBase = mOldName = oldName;
-        mNewBase = mNewName = newName;
-
-        int pos = mOldName.indexOf('$');
-        if (pos > 0) {
-            mOldBase = mOldName.substring(0, pos);
-        }
-        pos = mNewName.indexOf('$');
-        if (pos > 0) {
-            mNewBase = mNewName.substring(0, pos);
-        }
-
-        assert (mOldBase == null && mNewBase == null) || (mOldBase != null && mNewBase != null);
-    }
-
-    /**
-     * Renames an internal type name, e.g. "com.package.MyClass".
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     * <p/>
-     * The internal type of some of the MethodVisitor turns out to be a type
-       descriptor sometimes so descriptors are renamed too.
-     */
-    @Override
-    protected String renameInternalType(String type) {
-        if (type == null) {
-            return null;
-        }
-
-        if (type.equals(mOldName)) {
-            return mNewName;
-        }
-
-        if (mOldBase != mOldName && type.equals(mOldBase)) {
-            return mNewBase;
-        }
-
-        int pos = type.indexOf('$');
-        if (pos == mOldBase.length() && type.startsWith(mOldBase)) {
-            return mNewBase + type.substring(pos);
-        }
-        return type;
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
deleted file mode 100644
index 51e7535..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
+++ /dev/null
@@ -1,376 +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 com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-/**
- * This method adapter rewrites a method by discarding the original code and generating
- * a stub depending on the return type. Original annotations are passed along unchanged.
- */
-class StubMethodAdapter extends MethodVisitor {
-
-    private static String CONSTRUCTOR = "<init>";
-    private static String CLASS_INIT = "<clinit>";
-
-    /** The parent method writer */
-    private MethodVisitor mParentVisitor;
-    /** The method return type. Can be null. */
-    private Type mReturnType;
-    /** Message to be printed by stub methods. */
-    private String mInvokeSignature;
-    /** Flag to output the first line number. */
-    private boolean mOutputFirstLineNumber = true;
-    /** Flag that is true when implementing a constructor, to accept all original
-     *  code calling the original super constructor. */
-    private boolean mIsInitMethod = false;
-
-    private boolean mMessageGenerated;
-    private final boolean mIsStatic;
-    private final boolean mIsNative;
-
-    public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType,
-            String invokeSignature, boolean isStatic, boolean isNative) {
-        super(Opcodes.ASM4);
-        mParentVisitor = mv;
-        mReturnType = returnType;
-        mInvokeSignature = invokeSignature;
-        mIsStatic = isStatic;
-        mIsNative = isNative;
-
-        if (CONSTRUCTOR.equals(methodName) || CLASS_INIT.equals(methodName)) {
-            mIsInitMethod = true;
-        }
-    }
-
-    private void generateInvoke() {
-        /* Generates the code:
-         *  OverrideMethod.invoke("signature", mIsNative ? true : false, null or this);
-         */
-        mParentVisitor.visitLdcInsn(mInvokeSignature);
-        // push true or false
-        mParentVisitor.visitInsn(mIsNative ? Opcodes.ICONST_1 : Opcodes.ICONST_0);
-        // push null or this
-        if (mIsStatic) {
-            mParentVisitor.visitInsn(Opcodes.ACONST_NULL);
-        } else {
-            mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0);
-        }
-
-        int sort = mReturnType != null ? mReturnType.getSort() : Type.VOID;
-        switch(sort) {
-        case Type.VOID:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeV",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)V");
-            mParentVisitor.visitInsn(Opcodes.RETURN);
-            break;
-        case Type.BOOLEAN:
-        case Type.CHAR:
-        case Type.BYTE:
-        case Type.SHORT:
-        case Type.INT:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeI",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)I");
-            switch(sort) {
-            case Type.BOOLEAN:
-                Label l1 = new Label();
-                mParentVisitor.visitJumpInsn(Opcodes.IFEQ, l1);
-                mParentVisitor.visitInsn(Opcodes.ICONST_1);
-                mParentVisitor.visitInsn(Opcodes.IRETURN);
-                mParentVisitor.visitLabel(l1);
-                mParentVisitor.visitInsn(Opcodes.ICONST_0);
-                break;
-            case Type.CHAR:
-                mParentVisitor.visitInsn(Opcodes.I2C);
-                break;
-            case Type.BYTE:
-                mParentVisitor.visitInsn(Opcodes.I2B);
-                break;
-            case Type.SHORT:
-                mParentVisitor.visitInsn(Opcodes.I2S);
-                break;
-            }
-            mParentVisitor.visitInsn(Opcodes.IRETURN);
-            break;
-        case Type.LONG:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeL",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)J");
-            mParentVisitor.visitInsn(Opcodes.LRETURN);
-            break;
-        case Type.FLOAT:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeF",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)F");
-            mParentVisitor.visitInsn(Opcodes.FRETURN);
-            break;
-        case Type.DOUBLE:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeD",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)D");
-            mParentVisitor.visitInsn(Opcodes.DRETURN);
-            break;
-        case Type.ARRAY:
-        case Type.OBJECT:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeA",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;");
-            mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName());
-            mParentVisitor.visitInsn(Opcodes.ARETURN);
-            break;
-        }
-
-    }
-
-    private void generatePop() {
-        /* Pops the stack, depending on the return type.
-         */
-        switch(mReturnType != null ? mReturnType.getSort() : Type.VOID) {
-        case Type.VOID:
-            break;
-        case Type.BOOLEAN:
-        case Type.CHAR:
-        case Type.BYTE:
-        case Type.SHORT:
-        case Type.INT:
-        case Type.FLOAT:
-        case Type.ARRAY:
-        case Type.OBJECT:
-            mParentVisitor.visitInsn(Opcodes.POP);
-            break;
-        case Type.LONG:
-        case Type.DOUBLE:
-            mParentVisitor.visitInsn(Opcodes.POP2);
-            break;
-        }
-    }
-
-    /* Pass down to visitor writer. In this implementation, either do nothing. */
-    @Override
-    public void visitCode() {
-        mParentVisitor.visitCode();
-    }
-
-    /*
-     * visitMaxs is called just before visitEnd if there was any code to rewrite.
-     * For non-constructor, generate the messaging code and the return statement
-     * if it hasn't been done before.
-     */
-    @Override
-    public void visitMaxs(int maxStack, int maxLocals) {
-        if (!mIsInitMethod && !mMessageGenerated) {
-            generateInvoke();
-            mMessageGenerated = true;
-        }
-        mParentVisitor.visitMaxs(maxStack, maxLocals);
-    }
-
-    /**
-     * End of visiting.
-     * For non-constructor, generate the messaging code and the return statement
-     * if it hasn't been done before.
-     */
-    @Override
-    public void visitEnd() {
-        if (!mIsInitMethod && !mMessageGenerated) {
-            generateInvoke();
-            mMessageGenerated = true;
-            mParentVisitor.visitMaxs(1, 1);
-        }
-        mParentVisitor.visitEnd();
-    }
-
-    /* Writes all annotation from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        return mParentVisitor.visitAnnotation(desc, visible);
-    }
-
-    /* Writes all annotation default values from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotationDefault() {
-        return mParentVisitor.visitAnnotationDefault();
-    }
-
-    @Override
-    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-            boolean visible) {
-        return mParentVisitor.visitParameterAnnotation(parameter, desc, visible);
-    }
-
-    /* Writes all attributes from the original method. */
-    @Override
-    public void visitAttribute(Attribute attr) {
-        mParentVisitor.visitAttribute(attr);
-    }
-
-    /*
-     * Only writes the first line number present in the original code so that source
-     * viewers can direct to the correct method, even if the content doesn't match.
-     */
-    @Override
-    public void visitLineNumber(int line, Label start) {
-        if (mIsInitMethod || mOutputFirstLineNumber) {
-            mParentVisitor.visitLineNumber(line, start);
-            mOutputFirstLineNumber = false;
-        }
-    }
-
-    /**
-     * For non-constructor, rewrite existing "return" instructions to write the message.
-     */
-    @Override
-    public void visitInsn(int opcode) {
-        if (mIsInitMethod) {
-            switch (opcode) {
-            case Opcodes.RETURN:
-            case Opcodes.ARETURN:
-            case Opcodes.DRETURN:
-            case Opcodes.FRETURN:
-            case Opcodes.IRETURN:
-            case Opcodes.LRETURN:
-                // Pop the last word from the stack since invoke will generate its own return.
-                generatePop();
-                generateInvoke();
-                mMessageGenerated = true;
-                //$FALL-THROUGH$
-            default:
-                mParentVisitor.visitInsn(opcode);
-            }
-        }
-    }
-
-    @Override
-    public void visitLabel(Label label) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLabel(label);
-        }
-    }
-
-    @Override
-    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitTryCatchBlock(start, end, handler, type);
-        }
-    }
-
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitMethodInsn(opcode, owner, name, desc);
-        }
-    }
-
-    @Override
-    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitFieldInsn(opcode, owner, name, desc);
-        }
-    }
-
-    @Override
-    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitFrame(type, nLocal, local, nStack, stack);
-        }
-    }
-
-    @Override
-    public void visitIincInsn(int var, int increment) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitIincInsn(var, increment);
-        }
-    }
-
-    @Override
-    public void visitIntInsn(int opcode, int operand) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitIntInsn(opcode, operand);
-        }
-    }
-
-    @Override
-    public void visitJumpInsn(int opcode, Label label) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitJumpInsn(opcode, label);
-        }
-    }
-
-    @Override
-    public void visitLdcInsn(Object cst) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLdcInsn(cst);
-        }
-    }
-
-    @Override
-    public void visitLocalVariable(String name, String desc, String signature,
-            Label start, Label end, int index) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLookupSwitchInsn(dflt, keys, labels);
-        }
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(String desc, int dims) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitMultiANewArrayInsn(desc, dims);
-        }
-    }
-
-    @Override
-    public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitTableSwitchInsn(min, max, dflt, labels);
-        }
-    }
-
-    @Override
-    public void visitTypeInsn(int opcode, String type) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitTypeInsn(opcode, type);
-        }
-    }
-
-    @Override
-    public void visitVarInsn(int opcode, int var) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitVarInsn(opcode, var);
-        }
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
deleted file mode 100644
index d45a183..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
+++ /dev/null
@@ -1,183 +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 com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.util.Set;
-
-/**
- * Class adapter that can stub some or all of the methods of the class.
- */
-class TransformClassAdapter extends ClassVisitor {
-
-    /** True if all methods should be stubbed, false if only native ones must be stubbed. */
-    private final boolean mStubAll;
-    /** True if the class is an interface. */
-    private boolean mIsInterface;
-    private final String mClassName;
-    private final Log mLog;
-    private final Set<String> mStubMethods;
-    private Set<String> mDeleteReturns;
-
-    /**
-     * Creates a new class adapter that will stub some or all methods.
-     * @param logger
-     * @param stubMethods  list of method signatures to always stub out
-     * @param deleteReturns list of types that trigger the deletion of methods returning them.
-     * @param className The name of the class being modified
-     * @param cv The parent class writer visitor
-     * @param stubNativesOnly True if only native methods should be stubbed. False if all
-     *                        methods should be stubbed.
-     * @param hasNative True if the method has natives, in which case its access should be
-     *                  changed.
-     */
-    public TransformClassAdapter(Log logger, Set<String> stubMethods,
-            Set<String> deleteReturns, String className, ClassVisitor cv,
-            boolean stubNativesOnly, boolean hasNative) {
-        super(Opcodes.ASM4, cv);
-        mLog = logger;
-        mStubMethods = stubMethods;
-        mClassName = className;
-        mStubAll = !stubNativesOnly;
-        mIsInterface = false;
-        mDeleteReturns = deleteReturns;
-    }
-
-    /* Visits the class header. */
-    @Override
-    public void visit(int version, int access, String name,
-            String signature, String superName, String[] interfaces) {
-
-        // This class might be being renamed.
-        name = mClassName;
-
-        // remove protected or private and set as public
-        if (Main.sOptions.generatePublicAccess) {
-            access = access & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED);
-            access |= Opcodes.ACC_PUBLIC;
-        }
-        // remove final
-        access = access & ~Opcodes.ACC_FINAL;
-        // note: leave abstract classes as such
-        // don't try to implement stub for interfaces
-
-        mIsInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-
-    /* Visits the header of an inner class. */
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        // remove protected or private and set as public
-        if (Main.sOptions.generatePublicAccess) {
-            access = access & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED);
-            access |= Opcodes.ACC_PUBLIC;
-        }
-        // remove final
-        access = access & ~Opcodes.ACC_FINAL;
-        // note: leave abstract classes as such
-        // don't try to implement stub for interfaces
-
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-
-    /* Visits a method. */
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-
-        if (mDeleteReturns != null) {
-            Type t = Type.getReturnType(desc);
-            if (t.getSort() == Type.OBJECT) {
-                String returnType = t.getInternalName();
-                if (returnType != null) {
-                    if (mDeleteReturns.contains(returnType)) {
-                        return null;
-                    }
-                }
-            }
-        }
-
-        String methodSignature = mClassName.replace('/', '.') + "#" + name;
-
-        // change access to public
-        if (Main.sOptions.generatePublicAccess) {
-            access &= ~(Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE);
-            access |= Opcodes.ACC_PUBLIC;
-        }
-
-        // remove final
-        access = access & ~Opcodes.ACC_FINAL;
-
-        // stub this method if they are all to be stubbed or if it is a native method
-        // and don't try to stub interfaces nor abstract non-native methods.
-        if (!mIsInterface &&
-            ((access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) != Opcodes.ACC_ABSTRACT) &&
-            (mStubAll ||
-             (access & Opcodes.ACC_NATIVE) != 0) ||
-             mStubMethods.contains(methodSignature)) {
-
-            boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
-            boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
-
-            // remove abstract, final and native
-            access = access & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_NATIVE);
-
-            String invokeSignature = methodSignature + desc;
-            mLog.debug("  Stub: %s (%s)", invokeSignature, isNative ? "native" : "");
-
-            MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
-            return new StubMethodAdapter(mw, name, returnType(desc), invokeSignature,
-                    isStatic, isNative);
-
-        } else {
-            mLog.debug("  Keep: %s %s", name, desc);
-            return super.visitMethod(access, name, desc, signature, exceptions);
-        }
-    }
-
-    /* Visits a field. Makes it public. */
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc, String signature,
-            Object value) {
-        // change access to public
-        if (Main.sOptions.generatePublicAccess) {
-            access &= ~(Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE);
-            access |= Opcodes.ACC_PUBLIC;
-        }
-        return super.visitField(access, name, desc, signature, value);
-    }
-
-    /**
-     * Extracts the return {@link Type} of this descriptor.
-     */
-    Type returnType(String desc) {
-        if (desc != null) {
-            try {
-                return Type.getReturnType(desc);
-            } catch (ArrayIndexOutOfBoundsException e) {
-                // ignore, not a valid type.
-            }
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java
deleted file mode 100644
index ed2c128..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java
+++ /dev/null
@@ -1,31 +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.tools.layoutlib.java;
-
-/**
- * Defines the same interface as the java.lang.AutoCloseable which was added in
- * Java 7. This hack makes it possible to run the Android code which uses Java 7
- * features (API 18 and beyond) to run on Java 6.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/lang/AutoCloseable.java
- */
-public interface AutoCloseable {
-    /**
-     * Closes the object and release any system resources it holds.
-     */
-    void close() throws Exception; }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java
deleted file mode 100644
index f73b06b..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java
+++ /dev/null
@@ -1,133 +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.tools.layoutlib.java;
-
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-
-/**
- * Defines the same class as the java.nio.charset.Charsets which was added in
- * Dalvik VM. This hack, provides a replacement for that class which can't be
- * loaded in the standard JVM since it's in the java package and standard JVM
- * doesn't have it. An implementation of the native methods in the original
- * class has been added.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/nio/charset/Charsets
- */
-public final class Charsets {
-    /**
-     * A cheap and type-safe constant for the ISO-8859-1 Charset.
-     */
-    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
-
-    /**
-     * A cheap and type-safe constant for the US-ASCII Charset.
-     */
-    public static final Charset US_ASCII = Charset.forName("US-ASCII");
-
-    /**
-     * A cheap and type-safe constant for the UTF-8 Charset.
-     */
-    public static final Charset UTF_8 = Charset.forName("UTF-8");
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in US-ASCII. Unrepresentable characters are replaced by (byte) '?'.
-     */
-    public static byte[] toAsciiBytes(char[] chars, int offset, int length) {
-        CharBuffer cb = CharBuffer.allocate(length);
-        cb.put(chars, offset, length);
-        return US_ASCII.encode(cb).array();
-    }
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in ISO-8859-1. Unrepresentable characters are replaced by (byte) '?'.
-     */
-    public static byte[] toIsoLatin1Bytes(char[] chars, int offset, int length) {
-        CharBuffer cb = CharBuffer.allocate(length);
-        cb.put(chars, offset, length);
-        return ISO_8859_1.encode(cb).array();
-    }
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in UTF-8. All characters are representable in UTF-8.
-     */
-    public static byte[] toUtf8Bytes(char[] chars, int offset, int length) {
-        CharBuffer cb = CharBuffer.allocate(length);
-        cb.put(chars, offset, length);
-        return UTF_8.encode(cb).array();
-    }
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in UTF-16BE. All characters are representable in UTF-16BE.
-     */
-    public static byte[] toBigEndianUtf16Bytes(char[] chars, int offset, int length) {
-        byte[] result = new byte[length * 2];
-        int end = offset + length;
-        int resultIndex = 0;
-        for (int i = offset; i < end; ++i) {
-            char ch = chars[i];
-            result[resultIndex++] = (byte) (ch >> 8);
-            result[resultIndex++] = (byte) ch;
-        }
-        return result;
-    }
-
-    /**
-     * Decodes the given US-ASCII bytes into the given char[]. Equivalent to but faster than:
-     *
-     * for (int i = 0; i < count; ++i) {
-     *     char ch = (char) (data[start++] & 0xff);
-     *     value[i] = (ch <= 0x7f) ? ch : REPLACEMENT_CHAR;
-     * }
-     */
-    public static void asciiBytesToChars(byte[] bytes, int offset, int length, char[] chars) {
-        if (bytes == null || chars == null) {
-            return;
-        }
-        final char REPLACEMENT_CHAR = (char)0xffd;
-        int start = offset;
-        for (int i = 0; i < length; ++i) {
-            char ch = (char) (bytes[start++] & 0xff);
-            chars[i] = (ch <= 0x7f) ? ch : REPLACEMENT_CHAR;
-        }
-    }
-
-    /**
-     * Decodes the given ISO-8859-1 bytes into the given char[]. Equivalent to but faster than:
-     *
-     * for (int i = 0; i < count; ++i) {
-     *     value[i] = (char) (data[start++] & 0xff);
-     * }
-     */
-    public static void isoLatin1BytesToChars(byte[] bytes, int offset, int length, char[] chars) {
-        if (bytes == null || chars == null) {
-            return;
-        }
-        int start = offset;
-        for (int i = 0; i < length; ++i) {
-            chars[i] = (char) (bytes[start++] & 0xff);
-        }
-    }
-
-    private Charsets() {
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java
deleted file mode 100644
index e6dd00a..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java
+++ /dev/null
@@ -1,537 +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.tools.layoutlib.java;
-
-/**
- * Defines the same class as the java.lang.IntegralToString which was added in
- * Dalvik VM. This hack, provides a replacement for that class which can't be
- * loaded in the standard JVM since it's in the java package and standard JVM
- * doesn't have it. Since it's no longer in java.lang, access to package
- * private methods and classes has been replaced by the closes matching public
- * implementation.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/lang/IntegralToString.java
- */
-public final class IntegralToString {
-    /**
-     * When appending to an AbstractStringBuilder, this thread-local char[] lets us avoid
-     * allocation of a temporary array. (We can't write straight into the AbstractStringBuilder
-     * because it's almost as expensive to work out the exact length of the result as it is to
-     * do the formatting. We could try being conservative and "delete"-ing the unused space
-     * afterwards, but then we'd need to duplicate convertInt and convertLong rather than share
-     * the code.)
-     */
-    private static final ThreadLocal<char[]> BUFFER = new ThreadLocal<char[]>() {
-        @Override protected char[] initialValue() {
-            return new char[20]; // Maximum length of a base-10 long.
-        }
-    };
-
-    /**
-     * These tables are used to special-case toString computation for
-     * small values.  This serves three purposes: it reduces memory usage;
-     * it increases performance for small values; and it decreases the
-     * number of comparisons required to do the length computation.
-     * Elements of this table are lazily initialized on first use.
-     * No locking is necessary, i.e., we use the non-volatile, racy
-     * single-check idiom.
-     */
-    private static final String[] SMALL_NONNEGATIVE_VALUES = new String[100];
-    private static final String[] SMALL_NEGATIVE_VALUES = new String[100];
-
-    /** TENS[i] contains the tens digit of the number i, 0 <= i <= 99. */
-    private static final char[] TENS = {
-        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
-        '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
-        '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
-        '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
-        '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
-        '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
-        '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
-        '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
-        '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
-        '9', '9', '9', '9', '9', '9', '9', '9', '9', '9'
-    };
-
-    /** Ones [i] contains the tens digit of the number i, 0 <= i <= 99. */
-    private static final char[] ONES = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-    };
-
-    /**
-     * Table for MOD / DIV 10 computation described in Section 10-21
-     * of Hank Warren's "Hacker's Delight" online addendum.
-     * http://www.hackersdelight.org/divcMore.pdf
-     */
-    private static final char[] MOD_10_TABLE = {
-        0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 0
-    };
-
-    /**
-     * The digits for every supported radix.
-     */
-    private static final char[] DIGITS = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
-        'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
-        'u', 'v', 'w', 'x', 'y', 'z'
-    };
-
-    private static final char[] UPPER_CASE_DIGITS = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
-        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
-        'U', 'V', 'W', 'X', 'Y', 'Z'
-    };
-
-    private IntegralToString() {
-    }
-
-    /**
-     * Equivalent to Integer.toString(i, radix).
-     */
-    public static String intToString(int i, int radix) {
-        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
-            radix = 10;
-        }
-        if (radix == 10) {
-            return intToString(i);
-        }
-
-        /*
-         * If i is positive, negate it. This is the opposite of what one might
-         * expect. It is necessary because the range of the negative values is
-         * strictly larger than that of the positive values: there is no
-         * positive value corresponding to Integer.MIN_VALUE.
-         */
-        boolean negative = false;
-        if (i < 0) {
-            negative = true;
-        } else {
-            i = -i;
-        }
-
-        int bufLen = radix < 8 ? 33 : 12;  // Max chars in result (conservative)
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            int q = i / radix;
-            buf[--cursor] = DIGITS[radix * q - i];
-            i = q;
-        } while (i != 0);
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    /**
-     * Equivalent to Integer.toString(i).
-     */
-    public static String intToString(int i) {
-        return convertInt(null, i);
-    }
-
-    /**
-     * Equivalent to sb.append(Integer.toString(i)).
-     */
-    public static void appendInt(StringBuilder sb, int i) {
-        convertInt(sb, i);
-    }
-
-    /**
-     * Returns the string representation of i and leaves sb alone if sb is null.
-     * Returns null and appends the string representation of i to sb if sb is non-null.
-     */
-    private static String convertInt(StringBuilder sb, int i) {
-        boolean negative = false;
-        String quickResult = null;
-        if (i < 0) {
-            negative = true;
-            i = -i;
-            if (i < 100) {
-                if (i < 0) {
-                    // If -n is still negative, n is Integer.MIN_VALUE
-                    quickResult = "-2147483648";
-                } else {
-                    quickResult = SMALL_NEGATIVE_VALUES[i];
-                    if (quickResult == null) {
-                        SMALL_NEGATIVE_VALUES[i] = quickResult =
-                                i < 10 ? stringOf('-', ONES[i]) : stringOf('-', TENS[i], ONES[i]);
-                    }
-                }
-            }
-        } else {
-            if (i < 100) {
-                quickResult = SMALL_NONNEGATIVE_VALUES[i];
-                if (quickResult == null) {
-                    SMALL_NONNEGATIVE_VALUES[i] = quickResult =
-                            i < 10 ? stringOf(ONES[i]) : stringOf(TENS[i], ONES[i]);
-                }
-            }
-        }
-        if (quickResult != null) {
-            if (sb != null) {
-                sb.append(quickResult);
-                return null;
-            }
-            return quickResult;
-        }
-
-        int bufLen = 11; // Max number of chars in result
-        char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
-        int cursor = bufLen;
-
-        // Calculate digits two-at-a-time till remaining digits fit in 16 bits
-        while (i >= (1 << 16)) {
-            // Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8
-            int q = (int) ((0x51EB851FL * i) >>> 37);
-            int r = i - 100*q;
-            buf[--cursor] = ONES[r];
-            buf[--cursor] = TENS[r];
-            i = q;
-        }
-
-        // Calculate remaining digits one-at-a-time for performance
-        while (i != 0) {
-            // Compute q = n/10 and r = n % 10 as per "Hacker's Delight" 10-8
-            int q = (0xCCCD * i) >>> 19;
-            int r = i - 10*q;
-            buf[--cursor] = DIGITS[r];
-            i = q;
-        }
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-
-        if (sb != null) {
-            sb.append(buf, cursor, bufLen - cursor);
-            return null;
-        } else {
-            return new String(buf, cursor, bufLen - cursor);
-        }
-    }
-
-    /**
-     * Equivalent to Long.toString(v, radix).
-     */
-    public static String longToString(long v, int radix) {
-        int i = (int) v;
-        if (i == v) {
-            return intToString(i, radix);
-        }
-
-        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
-            radix = 10;
-        }
-        if (radix == 10) {
-            return longToString(v);
-        }
-
-        /*
-         * If v is positive, negate it. This is the opposite of what one might
-         * expect. It is necessary because the range of the negative values is
-         * strictly larger than that of the positive values: there is no
-         * positive value corresponding to Integer.MIN_VALUE.
-         */
-        boolean negative = false;
-        if (v < 0) {
-            negative = true;
-        } else {
-            v = -v;
-        }
-
-        int bufLen = radix < 8 ? 65 : 23;  // Max chars in result (conservative)
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            long q = v / radix;
-            buf[--cursor] = DIGITS[(int) (radix * q - v)];
-            v = q;
-        } while (v != 0);
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    /**
-     * Equivalent to Long.toString(l).
-     */
-    public static String longToString(long l) {
-        return convertLong(null, l);
-    }
-
-    /**
-     * Equivalent to sb.append(Long.toString(l)).
-     */
-    public static void appendLong(StringBuilder sb, long l) {
-        convertLong(sb, l);
-    }
-
-    /**
-     * Returns the string representation of n and leaves sb alone if sb is null.
-     * Returns null and appends the string representation of n to sb if sb is non-null.
-     */
-    private static String convertLong(StringBuilder sb, long n) {
-        int i = (int) n;
-        if (i == n) {
-            return convertInt(sb, i);
-        }
-
-        boolean negative = (n < 0);
-        if (negative) {
-            n = -n;
-            if (n < 0) {
-                // If -n is still negative, n is Long.MIN_VALUE
-                String quickResult = "-9223372036854775808";
-                if (sb != null) {
-                    sb.append(quickResult);
-                    return null;
-                }
-                return quickResult;
-            }
-        }
-
-        int bufLen = 20; // Maximum number of chars in result
-        char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
-
-        int low = (int) (n % 1000000000); // Extract low-order 9 digits
-        int cursor = intIntoCharArray(buf, bufLen, low);
-
-        // Zero-pad Low order part to 9 digits
-        while (cursor != (bufLen - 9)) {
-            buf[--cursor] = '0';
-        }
-
-        /*
-         * The remaining digits are (n - low) / 1,000,000,000.  This
-         * "exact division" is done as per the online addendum to Hank Warren's
-         * "Hacker's Delight" 10-20, http://www.hackersdelight.org/divcMore.pdf
-         */
-        n = ((n - low) >>> 9) * 0x8E47CE423A2E9C6DL;
-
-        /*
-         * If the remaining digits fit in an int, emit them using a
-         * single call to intIntoCharArray. Otherwise, strip off the
-         * low-order digit, put it in buf, and then call intIntoCharArray
-         * on the remaining digits (which now fit in an int).
-         */
-        if ((n & (-1L << 32)) == 0) {
-            cursor = intIntoCharArray(buf, cursor, (int) n);
-        } else {
-            /*
-             * Set midDigit to n % 10
-             */
-            int lo32 = (int) n;
-            int hi32 = (int) (n >>> 32);
-
-            // midDigit = ((unsigned) low32) % 10, per "Hacker's Delight" 10-21
-            int midDigit = MOD_10_TABLE[(0x19999999 * lo32 + (lo32 >>> 1) + (lo32 >>> 3)) >>> 28];
-
-            // Adjust midDigit for hi32. (assert hi32 == 1 || hi32 == 2)
-            midDigit -= hi32 << 2;  // 1L << 32 == -4 MOD 10
-            if (midDigit < 0) {
-                midDigit += 10;
-            }
-            buf[--cursor] = DIGITS[midDigit];
-
-            // Exact division as per Warren 10-20
-            int rest = ((int) ((n - midDigit) >>> 1)) * 0xCCCCCCCD;
-            cursor = intIntoCharArray(buf, cursor, rest);
-        }
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-        if (sb != null) {
-            sb.append(buf, cursor, bufLen - cursor);
-            return null;
-        } else {
-            return new String(buf, cursor, bufLen - cursor);
-        }
-    }
-
-    /**
-     * Inserts the unsigned decimal integer represented by n into the specified
-     * character array starting at position cursor.  Returns the index after
-     * the last character inserted (i.e., the value to pass in as cursor the
-     * next time this method is called). Note that n is interpreted as a large
-     * positive integer (not a negative integer) if its sign bit is set.
-     */
-    private static int intIntoCharArray(char[] buf, int cursor, int n) {
-        // Calculate digits two-at-a-time till remaining digits fit in 16 bits
-        while ((n & 0xffff0000) != 0) {
-            /*
-             * Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8.
-             * This computation is slightly different from the corresponding
-             * computation in intToString: the shifts before and after
-             * multiply can't be combined, as that would yield the wrong result
-             * if n's sign bit were set.
-             */
-            int q = (int) ((0x51EB851FL * (n >>> 2)) >>> 35);
-            int r = n - 100*q;
-            buf[--cursor] = ONES[r];
-            buf[--cursor] = TENS[r];
-            n = q;
-        }
-
-        // Calculate remaining digits one-at-a-time for performance
-        while (n != 0) {
-            // Compute q = n / 10 and r = n % 10 as per "Hacker's Delight" 10-8
-            int q = (0xCCCD * n) >>> 19;
-            int r = n - 10*q;
-            buf[--cursor] = DIGITS[r];
-            n = q;
-        }
-        return cursor;
-    }
-
-    public static String intToBinaryString(int i) {
-        int bufLen = 32;  // Max number of binary digits in an int
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[i & 1];
-        }  while ((i >>>= 1) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String longToBinaryString(long v) {
-        int i = (int) v;
-        if (v >= 0 && i == v) {
-            return intToBinaryString(i);
-        }
-
-        int bufLen = 64;  // Max number of binary digits in a long
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[((int) v) & 1];
-        }  while ((v >>>= 1) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static StringBuilder appendByteAsHex(StringBuilder sb, byte b, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        sb.append(digits[(b >> 4) & 0xf]);
-        sb.append(digits[b & 0xf]);
-        return sb;
-    }
-
-    public static String byteToHexString(byte b, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        char[] buf = new char[2]; // We always want two digits.
-        buf[0] = digits[(b >> 4) & 0xf];
-        buf[1] = digits[b & 0xf];
-        return new String(buf, 0, 2);
-    }
-
-    public static String bytesToHexString(byte[] bytes, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        char[] buf = new char[bytes.length * 2];
-        int c = 0;
-        for (byte b : bytes) {
-            buf[c++] = digits[(b >> 4) & 0xf];
-            buf[c++] = digits[b & 0xf];
-        }
-        return new String(buf);
-    }
-
-    public static String intToHexString(int i, boolean upperCase, int minWidth) {
-        int bufLen = 8;  // Max number of hex digits in an int
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        do {
-            buf[--cursor] = digits[i & 0xf];
-        } while ((i >>>= 4) != 0 || (bufLen - cursor < minWidth));
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String longToHexString(long v) {
-        int i = (int) v;
-        if (v >= 0 && i == v) {
-            return intToHexString(i, false, 0);
-        }
-
-        int bufLen = 16;  // Max number of hex digits in a long
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[((int) v) & 0xF];
-        } while ((v >>>= 4) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String intToOctalString(int i) {
-        int bufLen = 11;  // Max number of octal digits in an int
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[i & 7];
-        } while ((i >>>= 3) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String longToOctalString(long v) {
-        int i = (int) v;
-        if (v >= 0 && i == v) {
-            return intToOctalString(i);
-        }
-        int bufLen = 22;  // Max number of octal digits in a long
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[((int) v) & 7];
-        } while ((v >>>= 3) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    private static String stringOf(char... args) {
-        return new String(args, 0, args.length);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Objects.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Objects.java
deleted file mode 100644
index eb1ef72..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Objects.java
+++ /dev/null
@@ -1,132 +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.tools.layoutlib.java;
-
-import java.util.Arrays;
-import java.util.Comparator;
-
-/**
- * Defines the same class as the java.util.Objects which is added in Java 7.
- * This hack makes it possible to run the Android code which uses Java 7 features
- * (API 18 and beyond) to run on Java 6.
- * <p/>
- * Extracted from API level 19, file:
- * platform/libcore/luni/src/main/java/java/util/Objects.java
- */
-public final class Objects {
-  private Objects() {}
-
-  /**
-   * Returns 0 if {@code a == b}, or {@code c.compare(a, b)} otherwise.
-   * That is, this makes {@code c} null-safe.
-   */
-  public static <T> int compare(T a, T b, Comparator<? super T> c) {
-    if (a == b) {
-      return 0;
-    }
-    return c.compare(a, b);
-  }
-
-  /**
-   * Returns true if both arguments are null,
-   * the result of {@link Arrays#equals} if both arguments are primitive arrays,
-   * the result of {@link Arrays#deepEquals} if both arguments are arrays of reference types,
-   * and the result of {@link #equals} otherwise.
-   */
-  public static boolean deepEquals(Object a, Object b) {
-    if (a == null || b == null) {
-      return a == b;
-    } else if (a instanceof Object[] && b instanceof Object[]) {
-      return Arrays.deepEquals((Object[]) a, (Object[]) b);
-    } else if (a instanceof boolean[] && b instanceof boolean[]) {
-      return Arrays.equals((boolean[]) a, (boolean[]) b);
-    } else if (a instanceof byte[] && b instanceof byte[]) {
-      return Arrays.equals((byte[]) a, (byte[]) b);
-    } else if (a instanceof char[] && b instanceof char[]) {
-      return Arrays.equals((char[]) a, (char[]) b);
-    } else if (a instanceof double[] && b instanceof double[]) {
-      return Arrays.equals((double[]) a, (double[]) b);
-    } else if (a instanceof float[] && b instanceof float[]) {
-      return Arrays.equals((float[]) a, (float[]) b);
-    } else if (a instanceof int[] && b instanceof int[]) {
-      return Arrays.equals((int[]) a, (int[]) b);
-    } else if (a instanceof long[] && b instanceof long[]) {
-      return Arrays.equals((long[]) a, (long[]) b);
-    } else if (a instanceof short[] && b instanceof short[]) {
-      return Arrays.equals((short[]) a, (short[]) b);
-    }
-    return a.equals(b);
-  }
-
-  /**
-   * Null-safe equivalent of {@code a.equals(b)}.
-   */
-  public static boolean equals(Object a, Object b) {
-    return (a == null) ? (b == null) : a.equals(b);
-  }
-
-  /**
-   * Convenience wrapper for {@link Arrays#hashCode}, adding varargs.
-   * This can be used to compute a hash code for an object's fields as follows:
-   * {@code Objects.hash(a, b, c)}.
-   */
-  public static int hash(Object... values) {
-    return Arrays.hashCode(values);
-  }
-
-  /**
-   * Returns 0 for null or {@code o.hashCode()}.
-   */
-  public static int hashCode(Object o) {
-    return (o == null) ? 0 : o.hashCode();
-  }
-
-  /**
-   * Returns {@code o} if non-null, or throws {@code NullPointerException}.
-   */
-  public static <T> T requireNonNull(T o) {
-    if (o == null) {
-      throw new NullPointerException();
-    }
-    return o;
-  }
-
-  /**
-   * Returns {@code o} if non-null, or throws {@code NullPointerException}
-   * with the given detail message.
-   */
-  public static <T> T requireNonNull(T o, String message) {
-    if (o == null) {
-      throw new NullPointerException(message);
-    }
-    return o;
-  }
-
-  /**
-   * Returns "null" for null or {@code o.toString()}.
-   */
-  public static String toString(Object o) {
-    return (o == null) ? "null" : o.toString();
-  }
-
-  /**
-   * Returns {@code nullString} for null or {@code o.toString()}.
-   */
-  public static String toString(Object o, String nullString) {
-    return (o == null) ? nullString : o.toString();
-  }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java
deleted file mode 100644
index 0e09080..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java
+++ /dev/null
@@ -1,81 +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.tools.layoutlib.java;
-
-import java.nio.charset.Charset;
-
-/**
- * Defines the same class as the java.lang.UnsafeByteSequence which was added in
- * Dalvik VM. This hack, provides a replacement for that class which can't be
- * loaded in the standard JVM since it's in the java package and standard JVM
- * doesn't have it.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/lang/UnsafeByteSequence.java
- */
-public class UnsafeByteSequence {
-    private byte[] bytes;
-    private int count;
-
-    public UnsafeByteSequence(int initialCapacity) {
-        this.bytes = new byte[initialCapacity];
-    }
-
-    public int size() {
-        return count;
-    }
-
-    /**
-     * Moves the write pointer back to the beginning of the sequence,
-     * but without resizing or reallocating the buffer.
-     */
-    public void rewind() {
-        count = 0;
-    }
-
-    public void write(byte[] buffer, int offset, int length) {
-        if (count + length >= bytes.length) {
-            byte[] newBytes = new byte[(count + length) * 2];
-            System.arraycopy(bytes, 0, newBytes, 0, count);
-            bytes = newBytes;
-        }
-        System.arraycopy(buffer, offset, bytes, count, length);
-        count += length;
-    }
-
-    public void write(int b) {
-        if (count == bytes.length) {
-            byte[] newBytes = new byte[count * 2];
-            System.arraycopy(bytes, 0, newBytes, 0, count);
-            bytes = newBytes;
-        }
-        bytes[count++] = (byte) b;
-    }
-
-    public byte[] toByteArray() {
-        if (count == bytes.length) {
-            return bytes;
-        }
-        byte[] result = new byte[count];
-        System.arraycopy(bytes, 0, result, 0, count);
-        return result;
-    }
-
-    public String toString(Charset cs) {
-        return new String(bytes, 0, count, cs);
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
deleted file mode 100644
index 005fc9d..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
+++ /dev/null
@@ -1,236 +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 com.android.tools.layoutlib.create;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import com.android.tools.layoutlib.create.AsmAnalyzer.DependencyVisitor;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-/**
- * Unit tests for some methods of {@link AsmAnalyzer}.
- */
-public class AsmAnalyzerTest {
-
-    private MockLog mLog;
-    private ArrayList<String> mOsJarPath;
-    private AsmAnalyzer mAa;
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-        URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar");
-
-        mOsJarPath = new ArrayList<String>();
-        mOsJarPath.add(url.getFile());
-
-        Set<String> excludeClasses = new HashSet<String>(1);
-        excludeClasses.add("java.lang.JavaClass");
-        mAa = new AsmAnalyzer(mLog, mOsJarPath, null /* gen */,
-                null /* deriveFrom */, null /* includeGlobs */, excludeClasses);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-    }
-
-    @Test
-    public void testParseZip() throws IOException {
-        Map<String, ClassReader> map = mAa.parseZip(mOsJarPath);
-
-        assertArrayEquals(new String[] {
-                "java.lang.JavaClass",
-                "mock_android.dummy.InnerTest",
-                "mock_android.dummy.InnerTest$DerivingClass",
-                "mock_android.dummy.InnerTest$MyGenerics1",
-                "mock_android.dummy.InnerTest$MyIntEnum",
-                "mock_android.dummy.InnerTest$MyStaticInnerClass",
-                "mock_android.dummy.InnerTest$NotStaticInner1",
-                "mock_android.dummy.InnerTest$NotStaticInner2",
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams",
-                "mock_android.widget.LinearLayout",
-                "mock_android.widget.LinearLayout$LayoutParams",
-                "mock_android.widget.TableLayout",
-                "mock_android.widget.TableLayout$LayoutParams"
-            },
-            map.keySet().toArray());
-    }
-
-    @Test
-    public void testFindClass() throws IOException, LogAbortException {
-        Map<String, ClassReader> zipClasses = mAa.parseZip(mOsJarPath);
-        TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>();
-
-        ClassReader cr = mAa.findClass("mock_android.view.ViewGroup$LayoutParams",
-                zipClasses, found);
-
-        assertNotNull(cr);
-        assertEquals("mock_android/view/ViewGroup$LayoutParams", cr.getClassName());
-        assertArrayEquals(new String[] { "mock_android.view.ViewGroup$LayoutParams" },
-                found.keySet().toArray());
-        assertArrayEquals(new ClassReader[] { cr }, found.values().toArray());
-    }
-
-    @Test
-    public void testFindGlobs() throws IOException, LogAbortException {
-        Map<String, ClassReader> zipClasses = mAa.parseZip(mOsJarPath);
-        TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>();
-
-        // this matches classes, a package match returns nothing
-        found.clear();
-        mAa.findGlobs("mock_android.view", zipClasses, found);
-
-        assertArrayEquals(new String[] { },
-            found.keySet().toArray());
-
-        // a complex glob search. * is a search pattern that matches names, not dots
-        mAa.findGlobs("mock_android.*.*Group$*Layout*", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams"
-            },
-            found.keySet().toArray());
-
-        // a complex glob search. ** is a search pattern that matches names including dots
-        mAa.findGlobs("mock_android.**Group*", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.ViewGroup",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams"
-            },
-            found.keySet().toArray());
-
-        // matches a single class
-        found.clear();
-        mAa.findGlobs("mock_android.view.View", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View"
-            },
-            found.keySet().toArray());
-
-        // matches everyting inside the given package but not sub-packages
-        found.clear();
-        mAa.findGlobs("mock_android.view.*", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams"
-            },
-            found.keySet().toArray());
-
-        for (String key : found.keySet()) {
-            ClassReader value = found.get(key);
-            assertNotNull("No value for " + key, value);
-            assertEquals(key, AsmAnalyzer.classReaderToClassName(value));
-        }
-    }
-
-    @Test
-    public void testFindClassesDerivingFrom() throws LogAbortException, IOException {
-        Map<String, ClassReader> zipClasses = mAa.parseZip(mOsJarPath);
-        TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>();
-
-        mAa.findClassesDerivingFrom("mock_android.view.View", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup",
-                "mock_android.widget.LinearLayout",
-                "mock_android.widget.TableLayout",
-            },
-            found.keySet().toArray());
-
-        for (String key : found.keySet()) {
-            ClassReader value = found.get(key);
-            assertNotNull("No value for " + key, value);
-            assertEquals(key, AsmAnalyzer.classReaderToClassName(value));
-        }
-    }
-
-    @Test
-    public void testDependencyVisitor() throws IOException, LogAbortException {
-        Map<String, ClassReader> zipClasses = mAa.parseZip(mOsJarPath);
-        TreeMap<String, ClassReader> keep = new TreeMap<String, ClassReader>();
-        TreeMap<String, ClassReader> new_keep = new TreeMap<String, ClassReader>();
-        TreeMap<String, ClassReader> in_deps = new TreeMap<String, ClassReader>();
-        TreeMap<String, ClassReader> out_deps = new TreeMap<String, ClassReader>();
-
-        ClassReader cr = mAa.findClass("mock_android.widget.TableLayout", zipClasses, keep);
-        DependencyVisitor visitor = mAa.getVisitor(zipClasses, keep, new_keep, in_deps, out_deps);
-
-        // get first level dependencies
-        cr.accept(visitor, 0 /* flags */);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.ViewGroup",
-                "mock_android.widget.TableLayout$LayoutParams",
-            },
-            out_deps.keySet().toArray());
-
-        in_deps.putAll(out_deps);
-        out_deps.clear();
-
-        // get second level dependencies
-        for (ClassReader cr2 : in_deps.values()) {
-            cr2.accept(visitor, 0 /* flags */);
-        }
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams",
-            },
-            out_deps.keySet().toArray());
-
-        in_deps.putAll(out_deps);
-        out_deps.clear();
-
-        // get third level dependencies (there are none)
-        for (ClassReader cr2 : in_deps.values()) {
-            cr2.accept(visitor, 0 /* flags */);
-        }
-        keep.putAll(new_keep);
-
-        assertArrayEquals(new String[] { }, out_deps.keySet().toArray());
-        assertArrayEquals(new String[] {
-                "mock_android.widget.TableLayout",
-        }, keep.keySet().toArray());
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
deleted file mode 100644
index 8a27173..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
+++ /dev/null
@@ -1,330 +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 com.android.tools.layoutlib.create;
-
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * Unit tests for some methods of {@link AsmGenerator}.
- */
-public class AsmGeneratorTest {
-
-    private MockLog mLog;
-    private ArrayList<String> mOsJarPath;
-    private String mOsDestJar;
-    private File mTempFile;
-
-    // ASM internal name for the the class in java package that should be refactored.
-    private static final String JAVA_CLASS_NAME = "java/lang/JavaClass";
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-        URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar");
-
-        mOsJarPath = new ArrayList<String>();
-        mOsJarPath.add(url.getFile());
-
-        mTempFile = File.createTempFile("mock", ".jar");
-        mOsDestJar = mTempFile.getAbsolutePath();
-        mTempFile.deleteOnExit();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        if (mTempFile != null) {
-            mTempFile.delete();
-            mTempFile = null;
-        }
-    }
-
-    @Test
-    public void testClassRenaming() throws IOException, LogAbortException {
-
-        ICreateInfo ci = new ICreateInfo() {
-            @Override
-            public Class<?>[] getInjectedClasses() {
-                // classes to inject in the final JAR
-                return new Class<?>[0];
-            }
-
-            @Override
-            public String[] getDelegateMethods() {
-                return new String[0];
-            }
-
-            @Override
-            public String[] getDelegateClassNatives() {
-                return new String[0];
-            }
-
-            @Override
-            public String[] getOverriddenMethods() {
-                // methods to force override
-                return new String[0];
-            }
-
-            @Override
-            public String[] getRenamedClasses() {
-                // classes to rename (so that we can replace them)
-                return new String[] {
-                        "mock_android.view.View", "mock_android.view._Original_View",
-                        "not.an.actual.ClassName", "anoter.fake.NewClassName",
-                };
-            }
-
-            @Override
-            public String[] getJavaPkgClasses() {
-              return new String[0];
-            }
-
-            @Override
-            public String[] getDeleteReturns() {
-                 // methods deleted from their return type.
-                return new String[0];
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                    "**"
-                },
-                new HashSet<String>(0) /* excluded classes */);
-        aa.analyze();
-        agen.generate();
-
-        Set<String> notRenamed = agen.getClassesNotRenamed();
-        assertArrayEquals(new String[] { "not/an/actual/ClassName" }, notRenamed.toArray());
-
-    }
-
-    @Test
-    public void testClassRefactoring() throws IOException, LogAbortException {
-        ICreateInfo ci = new ICreateInfo() {
-            @Override
-            public Class<?>[] getInjectedClasses() {
-                // classes to inject in the final JAR
-                return new Class<?>[] {
-                        com.android.tools.layoutlib.create.dataclass.JavaClass.class
-                };
-            }
-
-            @Override
-            public String[] getDelegateMethods() {
-                return new String[0];
-            }
-
-            @Override
-            public String[] getDelegateClassNatives() {
-                return new String[0];
-            }
-
-            @Override
-            public String[] getOverriddenMethods() {
-                // methods to force override
-                return new String[0];
-            }
-
-            @Override
-            public String[] getRenamedClasses() {
-                // classes to rename (so that we can replace them)
-                return new String[0];
-            }
-
-            @Override
-            public String[] getJavaPkgClasses() {
-             // classes to refactor (so that we can replace them)
-                return new String[] {
-                        "java.lang.JavaClass", "com.android.tools.layoutlib.create.dataclass.JavaClass",
-                };
-            }
-
-            @Override
-            public String[] getDeleteReturns() {
-                 // methods deleted from their return type.
-                return new String[0];
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                    "**"
-                },
-                new HashSet<String>(1));
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = parseZip(mOsDestJar);
-        boolean injectedClassFound = false;
-        for (ClassReader cr: output.values()) {
-            TestClassVisitor cv = new TestClassVisitor();
-            cr.accept(cv, 0);
-            injectedClassFound |= cv.mInjectedClassFound;
-        }
-        assertTrue(injectedClassFound);
-    }
-
-    private Map<String,ClassReader> parseZip(String jarPath) throws IOException {
-        TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>();
-
-            ZipFile zip = new ZipFile(jarPath);
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            ZipEntry entry;
-            while (entries.hasMoreElements()) {
-                entry = entries.nextElement();
-                if (entry.getName().endsWith(".class")) {
-                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
-                    String className = classReaderToClassName(cr);
-                    classes.put(className, cr);
-                }
-            }
-
-        return classes;
-    }
-
-    private String classReaderToClassName(ClassReader classReader) {
-        if (classReader == null) {
-            return null;
-        } else {
-            return classReader.getClassName().replace('/', '.');
-        }
-    }
-
-    private class TestClassVisitor extends ClassVisitor {
-
-        boolean mInjectedClassFound = false;
-
-        TestClassVisitor() {
-            super(Opcodes.ASM4);
-        }
-
-        @Override
-        public void visit(int version, int access, String name, String signature,
-                String superName, String[] interfaces) {
-            assertTrue(!getBase(name).equals(JAVA_CLASS_NAME));
-            if (name.equals("com/android/tools/layoutlib/create/dataclass/JavaClass")) {
-                mInjectedClassFound = true;
-            }
-            super.visit(version, access, name, signature, superName, interfaces);
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc,
-                String signature, Object value) {
-            assertTrue(testType(Type.getType(desc)));
-            return super.visitField(access, name, desc, signature, value);
-        }
-
-        @SuppressWarnings("hiding")
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc,
-                String signature, String[] exceptions) {
-            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
-            return new MethodVisitor(Opcodes.ASM4, mv) {
-
-                @Override
-                public void visitFieldInsn(int opcode, String owner, String name,
-                        String desc) {
-                    assertTrue(!getBase(owner).equals(JAVA_CLASS_NAME));
-                    assertTrue(testType(Type.getType(desc)));
-                    super.visitFieldInsn(opcode, owner, name, desc);
-                }
-
-                @Override
-                public void visitLdcInsn(Object cst) {
-                    if (cst instanceof Type) {
-                        assertTrue(testType((Type)cst));
-                    }
-                    super.visitLdcInsn(cst);
-                }
-
-                @Override
-                public void visitTypeInsn(int opcode, String type) {
-                    assertTrue(!getBase(type).equals(JAVA_CLASS_NAME));
-                    super.visitTypeInsn(opcode, type);
-                }
-
-                @Override
-                public void visitMethodInsn(int opcode, String owner, String name,
-                        String desc) {
-                    assertTrue(!getBase(owner).equals(JAVA_CLASS_NAME));
-                    assertTrue(testType(Type.getType(desc)));
-                    super.visitMethodInsn(opcode, owner, name, desc);
-                }
-
-            };
-        }
-
-        private boolean testType(Type type) {
-            int sort = type.getSort();
-            if (sort == Type.OBJECT) {
-                assertTrue(!getBase(type.getInternalName()).equals(JAVA_CLASS_NAME));
-            } else if (sort == Type.ARRAY) {
-                assertTrue(!getBase(type.getElementType().getInternalName())
-                        .equals(JAVA_CLASS_NAME));
-            } else if (sort == Type.METHOD) {
-                boolean r = true;
-                for (Type t : type.getArgumentTypes()) {
-                    r &= testType(t);
-                }
-                return r & testType(type.getReturnType());
-            }
-            return true;
-        }
-
-        private String getBase(String className) {
-            if (className == null) {
-                return null;
-            }
-            int pos = className.indexOf('$');
-            if (pos > 0) {
-                return className.substring(0, pos);
-            }
-            return className;
-        }
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java
deleted file mode 100644
index 0135c40..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-
-/**
- * Tests {@link ClassHasNativeVisitor}.
- */
-public class ClassHasNativeVisitorTest {
-
-    @Test
-    public void testHasNative() throws IOException {
-        MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
-        String className =
-                this.getClass().getCanonicalName() + "$" + ClassWithNative.class.getSimpleName();
-        ClassReader cr = new ClassReader(className);
-
-        cr.accept(cv, 0 /* flags */);
-        assertArrayEquals(new String[] { "native_method" }, cv.getMethodsFound());
-        assertTrue(cv.hasNativeMethods());
-    }
-
-    @Test
-    public void testHasNoNative() throws IOException {
-        MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
-        String className =
-            this.getClass().getCanonicalName() + "$" + ClassWithoutNative.class.getSimpleName();
-        ClassReader cr = new ClassReader(className);
-
-        cr.accept(cv, 0 /* flags */);
-        assertArrayEquals(new String[0], cv.getMethodsFound());
-        assertFalse(cv.hasNativeMethods());
-    }
-
-    //-------
-
-    /**
-     * Overrides {@link ClassHasNativeVisitor} to collec the name of the native methods found.
-     */
-    private static class MockClassHasNativeVisitor extends ClassHasNativeVisitor {
-        private ArrayList<String> mMethodsFound = new ArrayList<String>();
-
-        public String[] getMethodsFound() {
-            return mMethodsFound.toArray(new String[mMethodsFound.size()]);
-        }
-
-        @Override
-        protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
-            if (hasNativeMethods) {
-                mMethodsFound.add(methodName);
-            }
-            super.setHasNativeMethods(hasNativeMethods, methodName);
-        }
-    }
-
-    /**
-     * Dummy test class with a native method.
-     */
-    public static class ClassWithNative {
-        public ClassWithNative() {
-        }
-
-        public void callTheNativeMethod() {
-            native_method();
-        }
-
-        private native void native_method();
-    }
-
-    /**
-     * Dummy test class with no native method.
-     */
-    public static class ClassWithoutNative {
-        public ClassWithoutNative() {
-        }
-
-        public void someMethod() {
-        }
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
deleted file mode 100644
index 6e120ce..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.tools.layoutlib.create.dataclass.ClassWithNative;
-import com.android.tools.layoutlib.create.dataclass.OuterClass;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-public class DelegateClassAdapterTest {
-
-    private MockLog mLog;
-
-    private static final String NATIVE_CLASS_NAME = ClassWithNative.class.getCanonicalName();
-    private static final String OUTER_CLASS_NAME = OuterClass.class.getCanonicalName();
-    private static final String INNER_CLASS_NAME = OuterClass.class.getCanonicalName() + "$" +
-                                                   InnerClass.class.getSimpleName();
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-        mLog.setVerbose(true); // capture debug error too
-    }
-
-    /**
-     * Tests that a class not being modified still works.
-     */
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testNoOp() throws Throwable {
-        // create an instance of the class that will be modified
-        // (load the class in a distinct class loader so that we can trash its definition later)
-        ClassLoader cl1 = new ClassLoader(this.getClass().getClassLoader()) { };
-        Class<ClassWithNative> clazz1 = (Class<ClassWithNative>) cl1.loadClass(NATIVE_CLASS_NAME);
-        ClassWithNative instance1 = clazz1.newInstance();
-        assertEquals(42, instance1.add(20, 22));
-        try {
-            instance1.callNativeInstance(10, 3.1415, new Object[0] );
-            fail("Test should have failed to invoke callTheNativeMethod [1]");
-        } catch (UnsatisfiedLinkError e) {
-            // This is expected to fail since the native method is not implemented.
-        }
-
-        // Now process it but tell the delegate to not modify any method
-        ClassWriter cw = new ClassWriter(0 /*flags*/);
-
-        HashSet<String> delegateMethods = new HashSet<String>();
-        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cv = new DelegateClassAdapter(
-                mLog, cw, internalClassName, delegateMethods);
-
-        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
-        cr.accept(cv, 0 /* flags */);
-
-        // Load the generated class in a different class loader and try it again
-
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-                    Class<?> clazz2 = loadClass(NATIVE_CLASS_NAME);
-                    Object i2 = clazz2.newInstance();
-                    assertNotNull(i2);
-                    assertEquals(42, callAdd(i2, 20, 22));
-
-                    try {
-                        callCallNativeInstance(i2, 10, 3.1415, new Object[0]);
-                        fail("Test should have failed to invoke callTheNativeMethod [2]");
-                    } catch (InvocationTargetException e) {
-                        // This is expected to fail since the native method has NOT been
-                        // overridden here.
-                        assertEquals(UnsatisfiedLinkError.class, e.getCause().getClass());
-                    }
-
-                    // Check that the native method does NOT have the new annotation
-                    Method[] m = clazz2.getDeclaredMethods();
-                    assertEquals("native_instance", m[2].getName());
-                    assertTrue(Modifier.isNative(m[2].getModifiers()));
-                    Annotation[] a = m[2].getAnnotations();
-                    assertEquals(0, a.length);
-                }
-            };
-            cl2.add(NATIVE_CLASS_NAME, cw);
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    /**
-     * {@link DelegateMethodAdapter2} does not support overriding constructors yet,
-     * so this should fail with an {@link UnsupportedOperationException}.
-     *
-     * Although not tested here, the message of the exception should contain the
-     * constructor signature.
-     */
-    @Test(expected=UnsupportedOperationException.class)
-    public void testConstructorsNotSupported() throws IOException {
-        ClassWriter cw = new ClassWriter(0 /*flags*/);
-
-        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
-
-        HashSet<String> delegateMethods = new HashSet<String>();
-        delegateMethods.add("<init>");
-        DelegateClassAdapter cv = new DelegateClassAdapter(
-                mLog, cw, internalClassName, delegateMethods);
-
-        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
-        cr.accept(cv, 0 /* flags */);
-    }
-
-    @Test
-    public void testDelegateNative() throws Throwable {
-        ClassWriter cw = new ClassWriter(0 /*flags*/);
-        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
-
-        HashSet<String> delegateMethods = new HashSet<String>();
-        delegateMethods.add(DelegateClassAdapter.ALL_NATIVES);
-        DelegateClassAdapter cv = new DelegateClassAdapter(
-                mLog, cw, internalClassName, delegateMethods);
-
-        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
-        cr.accept(cv, 0 /* flags */);
-
-        // Load the generated class in a different class loader and try it
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-                    Class<?> clazz2 = loadClass(NATIVE_CLASS_NAME);
-                    Object i2 = clazz2.newInstance();
-                    assertNotNull(i2);
-
-                    // Use reflection to access inner methods
-                    assertEquals(42, callAdd(i2, 20, 22));
-
-                     Object[] objResult = new Object[] { null };
-                     int result = callCallNativeInstance(i2, 10, 3.1415, objResult);
-                     assertEquals((int)(10 + 3.1415), result);
-                     assertSame(i2, objResult[0]);
-
-                     // Check that the native method now has the new annotation and is not native
-                     Method[] m = clazz2.getDeclaredMethods();
-                     assertEquals("native_instance", m[2].getName());
-                     assertFalse(Modifier.isNative(m[2].getModifiers()));
-                     Annotation[] a = m[2].getAnnotations();
-                     assertEquals("LayoutlibDelegate", a[0].annotationType().getSimpleName());
-                }
-            };
-            cl2.add(NATIVE_CLASS_NAME, cw);
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    @Test
-    public void testDelegateInner() throws Throwable {
-        // We'll delegate the "get" method of both the inner and outer class.
-        HashSet<String> delegateMethods = new HashSet<String>();
-        delegateMethods.add("get");
-        delegateMethods.add("privateMethod");
-
-        // Generate the delegate for the outer class.
-        ClassWriter cwOuter = new ClassWriter(0 /*flags*/);
-        String outerClassName = OUTER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvOuter = new DelegateClassAdapter(
-                mLog, cwOuter, outerClassName, delegateMethods);
-        ClassReader cr = new ClassReader(OUTER_CLASS_NAME);
-        cr.accept(cvOuter, 0 /* flags */);
-
-        // Generate the delegate for the inner class.
-        ClassWriter cwInner = new ClassWriter(0 /*flags*/);
-        String innerClassName = INNER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvInner = new DelegateClassAdapter(
-                mLog, cwInner, innerClassName, delegateMethods);
-        cr = new ClassReader(INNER_CLASS_NAME);
-        cr.accept(cvInner, 0 /* flags */);
-
-        // Load the generated classes in a different class loader and try them
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-
-                    // Check the outer class
-                    Class<?> outerClazz2 = loadClass(OUTER_CLASS_NAME);
-                    Object o2 = outerClazz2.newInstance();
-                    assertNotNull(o2);
-
-                    // The original Outer.get returns 1+10+20,
-                    // but the delegate makes it return 4+10+20
-                    assertEquals(4+10+20, callGet(o2, 10, 20));
-                    assertEquals(1+10+20, callGet_Original(o2, 10, 20));
-
-                    // The original Outer has a private method that is
-                    // delegated. We should be able to call both the delegate
-                    // and the original (which is now public).
-                    assertEquals("outerPrivateMethod",
-                                 callMethod(o2, "privateMethod_Original", false /*makePublic*/));
-
-                    // The original method is private, so by default we can't access it
-                    boolean gotIllegalAccessException = false;
-                    try {
-                         callMethod(o2, "privateMethod", false /*makePublic*/);
-                    } catch(IllegalAccessException e) {
-                        gotIllegalAccessException = true;
-                    }
-                    assertTrue(gotIllegalAccessException);
-                    // Try again, but now making it accessible
-                    assertEquals("outerPrivate_Delegate",
-                            callMethod(o2, "privateMethod", true /*makePublic*/));
-
-                    // Check the inner class. Since it's not a static inner class, we need
-                    // to use the hidden constructor that takes the outer class as first parameter.
-                    Class<?> innerClazz2 = loadClass(INNER_CLASS_NAME);
-                    Constructor<?> innerCons = innerClazz2.getConstructor(
-                                                                new Class<?>[] { outerClazz2 });
-                    Object i2 = innerCons.newInstance(new Object[] { o2 });
-                    assertNotNull(i2);
-
-                    // The original Inner.get returns 3+10+20,
-                    // but the delegate makes it return 6+10+20
-                    assertEquals(6+10+20, callGet(i2, 10, 20));
-                    assertEquals(3+10+20, callGet_Original(i2, 10, 20));
-                }
-            };
-            cl2.add(OUTER_CLASS_NAME, cwOuter.toByteArray());
-            cl2.add(INNER_CLASS_NAME, cwInner.toByteArray());
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    //-------
-
-    /**
-     * A class loader than can define and instantiate our modified classes.
-     * <p/>
-     * The trick here is that this class loader will test our <em>modified</em> version
-     * of the classes, the one with the delegate calls.
-     * <p/>
-     * Trying to do so in the original class loader generates all sort of link issues because
-     * there are 2 different definitions of the same class name. This class loader will
-     * define and load the class when requested by name and provide helpers to access the
-     * instance methods via reflection.
-     */
-    private abstract class ClassLoader2 extends ClassLoader {
-
-        private final Map<String, byte[]> mClassDefs = new HashMap<String, byte[]>();
-
-        public ClassLoader2() {
-            super(null);
-        }
-
-        public ClassLoader2 add(String className, byte[] definition) {
-            mClassDefs.put(className, definition);
-            return this;
-        }
-
-        public ClassLoader2 add(String className, ClassWriter rewrittenClass) {
-            mClassDefs.put(className, rewrittenClass.toByteArray());
-            return this;
-        }
-
-        private Set<Entry<String, byte[]>> getByteCode() {
-            return mClassDefs.entrySet();
-        }
-
-        @SuppressWarnings("unused")
-        @Override
-        protected Class<?> findClass(String name) throws ClassNotFoundException {
-            try {
-                return super.findClass(name);
-            } catch (ClassNotFoundException e) {
-
-                byte[] def = mClassDefs.get(name);
-                if (def != null) {
-                    // Load the modified ClassWithNative from its bytes representation.
-                    return defineClass(name, def, 0, def.length);
-                }
-
-                try {
-                    // Load everything else from the original definition into the new class loader.
-                    ClassReader cr = new ClassReader(name);
-                    ClassWriter cw = new ClassWriter(0);
-                    cr.accept(cw, 0);
-                    byte[] bytes = cw.toByteArray();
-                    return defineClass(name, bytes, 0, bytes.length);
-
-                } catch (IOException ioe) {
-                    throw new RuntimeException(ioe);
-                }
-            }
-        }
-
-        /**
-         * Accesses {@link OuterClass#get} or {@link InnerClass#get}via reflection.
-         */
-        public int callGet(Object instance, int a, long b) throws Exception {
-            Method m = instance.getClass().getMethod("get",
-                    new Class<?>[] { int.class, long.class } );
-
-            Object result = m.invoke(instance, new Object[] { a, b });
-            return ((Integer) result).intValue();
-        }
-
-        /**
-         * Accesses the "_Original" methods for {@link OuterClass#get}
-         * or {@link InnerClass#get}via reflection.
-         */
-        public int callGet_Original(Object instance, int a, long b) throws Exception {
-            Method m = instance.getClass().getMethod("get_Original",
-                    new Class<?>[] { int.class, long.class } );
-
-            Object result = m.invoke(instance, new Object[] { a, b });
-            return ((Integer) result).intValue();
-        }
-
-        /**
-         * Accesses the any declared method that takes no parameter via reflection.
-         */
-        @SuppressWarnings("unchecked")
-        public <T> T callMethod(Object instance, String methodName, boolean makePublic) throws Exception {
-            Method m = instance.getClass().getDeclaredMethod(methodName, (Class<?>[])null);
-
-            boolean wasAccessible = m.isAccessible();
-            if (makePublic && !wasAccessible) {
-                m.setAccessible(true);
-            }
-
-            Object result = m.invoke(instance, (Object[])null);
-
-            if (makePublic && !wasAccessible) {
-                m.setAccessible(false);
-            }
-
-            return (T) result;
-        }
-
-        /**
-         * Accesses {@link ClassWithNative#add(int, int)} via reflection.
-         */
-        public int callAdd(Object instance, int a, int b) throws Exception {
-            Method m = instance.getClass().getMethod("add",
-                    new Class<?>[] { int.class, int.class });
-
-            Object result = m.invoke(instance, new Object[] { a, b });
-            return ((Integer) result).intValue();
-        }
-
-        /**
-         * Accesses {@link ClassWithNative#callNativeInstance(int, double, Object[])}
-         * via reflection.
-         */
-        public int callCallNativeInstance(Object instance, int a, double d, Object[] o)
-                throws Exception {
-            Method m = instance.getClass().getMethod("callNativeInstance",
-                    new Class<?>[] { int.class, double.class, Object[].class });
-
-            Object result = m.invoke(instance, new Object[] { a, d, o });
-            return ((Integer) result).intValue();
-        }
-
-        public abstract void testModifiedInstance() throws Exception;
-    }
-
-    /**
-     * For debugging, it's useful to dump the content of the generated classes
-     * along with the exception that was generated.
-     *
-     * However to make it work you need to pull in the org.objectweb.asm.util.TraceClassVisitor
-     * class and associated utilities which are found in the ASM source jar. Since we don't
-     * want that dependency in the source code, we only put it manually for development and
-     * access the TraceClassVisitor via reflection if present.
-     *
-     * @param t The exception thrown by {@link ClassLoader2#testModifiedInstance()}
-     * @param cl2 The {@link ClassLoader2} instance with the generated bytecode.
-     * @return Either original {@code t} or a new wrapper {@link Throwable}
-     */
-    private Throwable dumpGeneratedClass(Throwable t, ClassLoader2 cl2) {
-        try {
-            // For debugging, dump the bytecode of the class in case of unexpected error
-            // if we can find the TraceClassVisitor class.
-            Class<?> tcvClass = Class.forName("org.objectweb.asm.util.TraceClassVisitor");
-
-            StringBuilder sb = new StringBuilder();
-            sb.append('\n').append(t.getClass().getCanonicalName());
-            if (t.getMessage() != null) {
-                sb.append(": ").append(t.getMessage());
-              }
-
-            for (Entry<String, byte[]> entry : cl2.getByteCode()) {
-                String className = entry.getKey();
-                byte[] bytes = entry.getValue();
-
-                StringWriter sw = new StringWriter();
-                PrintWriter pw = new PrintWriter(sw);
-                // next 2 lines do: TraceClassVisitor tcv = new TraceClassVisitor(pw);
-                Constructor<?> cons = tcvClass.getConstructor(new Class<?>[] { pw.getClass() });
-                Object tcv = cons.newInstance(new Object[] { pw });
-                ClassReader cr2 = new ClassReader(bytes);
-                cr2.accept((ClassVisitor) tcv, 0 /* flags */);
-
-                sb.append("\nBytecode dump: <").append(className).append(">:\n")
-                  .append(sw.toString());
-            }
-
-            // Re-throw exception with new message
-            RuntimeException ex = new RuntimeException(sb.toString(), t);
-            return ex;
-        } catch (Throwable ignore) {
-            // In case of problem, just throw the original exception as-is.
-            return t;
-        }
-    }
-
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java
deleted file mode 100644
index 1a5f653..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java
+++ /dev/null
@@ -1,88 +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 com.android.tools.layoutlib.create;
-
-import static org.junit.Assert.*;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class LogTest {
-
-    private MockLog mLog;
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        // pass
-    }
-
-    @Test
-    public void testDebug() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        mLog.setVerbose(false);
-        mLog.debug("Test %d", 42);
-        assertEquals("", mLog.getOut());
-
-        mLog.setVerbose(true);
-        mLog.debug("Test %d", 42);
-
-        assertEquals("Test 42\n", mLog.getOut());
-        assertEquals("", mLog.getErr());
-    }
-
-    @Test
-    public void testInfo() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        mLog.info("Test %d", 43);
-
-        assertEquals("Test 43\n", mLog.getOut());
-        assertEquals("", mLog.getErr());
-    }
-
-    @Test
-    public void testError() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        mLog.error("Test %d", 44);
-
-        assertEquals("", mLog.getOut());
-        assertEquals("Test 44\n", mLog.getErr());
-    }
-
-    @Test
-    public void testException() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        Exception e = new Exception("My Exception");
-        mLog.exception(e, "Test %d", 44);
-
-        assertEquals("", mLog.getOut());
-        assertTrue(mLog.getErr().startsWith("Test 44\njava.lang.Exception: My Exception"));
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java
deleted file mode 100644
index de750a3..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-
-public class MockLog extends Log {
-    StringBuilder mOut = new StringBuilder();
-    StringBuilder mErr = new StringBuilder();
-
-    public String getOut() {
-        return mOut.toString();
-    }
-
-    public String getErr() {
-        return mErr.toString();
-    }
-
-    @Override
-    protected void outPrintln(String msg) {
-        mOut.append(msg);
-        mOut.append('\n');
-    }
-
-    @Override
-    protected void errPrintln(String msg) {
-        mErr.append(msg);
-        mErr.append('\n');
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java
deleted file mode 100644
index 6211e73..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java
+++ /dev/null
@@ -1,116 +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 com.android.tools.layoutlib.create;
-
-import static org.junit.Assert.*;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- *
- */
-public class RenameClassAdapterTest {
-
-    private RenameClassAdapter mOuter;
-    private RenameClassAdapter mInner;
-
-    @Before
-    public void setUp() throws Exception {
-        mOuter = new RenameClassAdapter(null, // cv
-                                         "com.pack.Old",
-                                         "org.blah.New");
-
-        mInner = new RenameClassAdapter(null, // cv
-                                         "com.pack.Old$Inner",
-                                         "org.blah.New$Inner");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-    }
-
-    /**
-     * Renames a type, e.g. "Lcom.package.My;"
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     */
-    @Test
-    public void testRenameTypeDesc() {
-
-        // primitive types are left untouched
-        assertEquals("I", mOuter.renameTypeDesc("I"));
-        assertEquals("D", mOuter.renameTypeDesc("D"));
-        assertEquals("V", mOuter.renameTypeDesc("V"));
-
-        // object types that need no renaming are left untouched
-        assertEquals("Lcom.package.MyClass;", mOuter.renameTypeDesc("Lcom.package.MyClass;"));
-        assertEquals("Lcom.package.MyClass;", mInner.renameTypeDesc("Lcom.package.MyClass;"));
-
-        // object types that match the requirements
-        assertEquals("Lorg.blah.New;", mOuter.renameTypeDesc("Lcom.pack.Old;"));
-        assertEquals("Lorg.blah.New$Inner;", mInner.renameTypeDesc("Lcom.pack.Old$Inner;"));
-        // inner classes match the base type which is being renamed
-        assertEquals("Lorg.blah.New$Other;", mOuter.renameTypeDesc("Lcom.pack.Old$Other;"));
-        assertEquals("Lorg.blah.New$Other;", mInner.renameTypeDesc("Lcom.pack.Old$Other;"));
-
-        // arrays
-        assertEquals("[Lorg.blah.New;",  mOuter.renameTypeDesc("[Lcom.pack.Old;"));
-        assertEquals("[[Lorg.blah.New;", mOuter.renameTypeDesc("[[Lcom.pack.Old;"));
-
-        assertEquals("[Lorg.blah.New;",  mInner.renameTypeDesc("[Lcom.pack.Old;"));
-        assertEquals("[[Lorg.blah.New;", mInner.renameTypeDesc("[[Lcom.pack.Old;"));
-    }
-
-    /**
-     * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
-     * object element, e.g. "[Lcom.package.MyClass;"
-     * If the type doesn't need to be renamed, returns the internal name of the input type.
-     */
-    @Test
-    public void testRenameType() {
-        // Skip. This is actually tested by testRenameTypeDesc above.
-    }
-
-    /**
-     * Renames an internal type name, e.g. "com.package.MyClass".
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     */
-    @Test
-    public void testRenameInternalType() {
-        // an actual FQCN
-        assertEquals("org.blah.New", mOuter.renameInternalType("com.pack.Old"));
-        assertEquals("org.blah.New$Inner", mOuter.renameInternalType("com.pack.Old$Inner"));
-
-        assertEquals("org.blah.New$Other", mInner.renameInternalType("com.pack.Old$Other"));
-        assertEquals("org.blah.New$Other", mInner.renameInternalType("com.pack.Old$Other"));
-    }
-
-    /**
-     * Renames a method descriptor, i.e. applies renameType to all arguments and to the
-     * return value.
-     */
-    @Test
-    public void testRenameMethodDesc() {
-        assertEquals("(IDLorg.blah.New;[Lorg.blah.New$Inner;)Lorg.blah.New$Other;",
-               mOuter.renameMethodDesc("(IDLcom.pack.Old;[Lcom.pack.Old$Inner;)Lcom.pack.Old$Other;"));
-    }
-
-
-
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java
deleted file mode 100644
index c314853..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * Dummy test class with a native method.
- * The native method is not defined and any attempt to invoke it will
- * throw an {@link UnsatisfiedLinkError}.
- *
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class ClassWithNative {
-    public ClassWithNative() {
-    }
-
-    public int add(int a, int b) {
-        return a + b;
-    }
-
-    // Note: it's good to have a long or double for testing parameters since they take
-    // 2 slots in the stack/locals maps.
-
-    public int callNativeInstance(int a, double d, Object[] o) {
-        return native_instance(a, d, o);
-    }
-
-    private native int native_instance(int a, double d, Object[] o);
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java
deleted file mode 100644
index a3d4dc6..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * The delegate that receives the call to {@link ClassWithNative_Delegate}'s overridden methods.
- *
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class ClassWithNative_Delegate {
-    public static int native_instance(ClassWithNative instance, int a, double d, Object[] o) {
-        if (o != null && o.length > 0) {
-            o[0] = instance;
-        }
-        return (int)(a + d);
-    }
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java
deleted file mode 100644
index 9b5a918..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-public final class JavaClass {
-
-    public static final String test = "test";
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java
deleted file mode 100644
index f083e76..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java
+++ /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.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * Test class with an inner class.
- *
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass {
-    private int mOuterValue = 1;
-    public OuterClass() {
-    }
-
-    // Outer.get returns 1 + a + b
-    // Note: it's good to have a long or double for testing parameters since they take
-    // 2 slots in the stack/locals maps.
-    public int get(int a, long b) {
-        return mOuterValue + a + (int) b;
-    }
-
-    public class InnerClass {
-        public InnerClass() {
-        }
-
-        // Inner.get returns 2 + 1 + a + b
-        public int get(int a, long b) {
-            return 2 + mOuterValue + a + (int) b;
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private String privateMethod() {
-        return "outerPrivateMethod";
-    }
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java
deleted file mode 100644
index 774be8e..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java
+++ /dev/null
@@ -1,34 +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.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass_Delegate {
-    // The delegate override of Outer.get returns 4 + a + b
-    public static int get(OuterClass instance, int a, long b) {
-        return 4 + a + (int) b;
-    }
-
-    public static String privateMethod(OuterClass instance) {
-        return "outerPrivate_Delegate";
-    }
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java
deleted file mode 100644
index b472220..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass;
-
-/**
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass_InnerClass_Delegate {
-    // The delegate override of Inner.get return 6 + a + b
-    public static int get(OuterClass outer, InnerClass inner, int a, long b) {
-        return 6 + a + (int) b;
-    }
-}
diff --git a/tools/layoutlib/create/tests/data/mock_android.jar b/tools/layoutlib/create/tests/data/mock_android.jar
deleted file mode 100644
index 60d8efb..0000000
--- a/tools/layoutlib/create/tests/data/mock_android.jar
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java b/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java
deleted file mode 100644
index 59612e9..0000000
--- a/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-public class JavaClass {
-
-    public static String test = "test";
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java b/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java
deleted file mode 100644
index d3a1d05..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.dummy;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-public class InnerTest {
-
-    private int mSomeField;
-    private MyStaticInnerClass mInnerInstance;
-    private MyIntEnum mTheIntEnum;
-    private MyGenerics1<int[][], InnerTest, MyIntEnum, float[]> mGeneric1;
-
-    public class NotStaticInner2 extends NotStaticInner1 {
-
-    }
-
-    public class NotStaticInner1 {
-
-        public void someThing() {
-            mSomeField = 2;
-            mInnerInstance = null;
-        }
-
-    }
-
-    private static class MyStaticInnerClass {
-
-    }
-    
-    private static class DerivingClass extends InnerTest {
-        
-    }
-    
-    // enums are a kind of inner static class
-    public enum MyIntEnum {
-        VALUE0(0),
-        VALUE1(1),
-        VALUE2(2);
-
-        MyIntEnum(int myInt) {
-            this.myInt = myInt;
-        }
-        final int myInt;
-    }
-    
-    public static class MyGenerics1<T, U, V, W> {
-        public MyGenerics1() {
-            int a = 1;
-        }
-    }
-    
-    public <X> void genericMethod1(X a, X[] b) {
-    }
-
-    public <X, Y> void genericMethod2(X a, List<Y> b) {
-    }
-
-    public <X, Y extends InnerTest> void genericMethod3(X a, List<Y> b) {
-    }
-
-    public <T extends InnerTest> void genericMethod4(T[] a, Collection<T> b, Collection<?> c) {
-        Iterator<T> i = b.iterator();
-    }
-
-    public void someMethod(InnerTest self) {
-        mSomeField = self.mSomeField;
-        MyStaticInnerClass m = new MyStaticInnerClass();
-        mInnerInstance = m;
-        mTheIntEnum = null;
-        mGeneric1 = new MyGenerics1();
-        genericMethod4(new DerivingClass[0], new ArrayList<DerivingClass>(), new ArrayList<InnerTest>());
-    }
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java b/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java
deleted file mode 100644
index 84ec8a9..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.view;
-
-import java.lang.JavaClass;
-
-public class View {
-
-        String x = JavaClass.test;
-
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java b/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java
deleted file mode 100644
index 466470f..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.view;
-
-public class ViewGroup extends View {
-
-    public class MarginLayoutParams extends LayoutParams {
-
-    }
-
-    public class LayoutParams {
-
-    }
-
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java b/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java
deleted file mode 100644
index 3870a63..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.widget;
-
-import mock_android.view.ViewGroup;
-
-public class LinearLayout extends ViewGroup {
-
-    public class LayoutParams extends mock_android.view.ViewGroup.LayoutParams {
-
-    }
-
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java b/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java
deleted file mode 100644
index e455e7d..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.widget;
-
-import mock_android.view.ViewGroup;
-
-public class TableLayout extends ViewGroup {
-
-    public class LayoutParams extends MarginLayoutParams {
-
-    }
-
-}
diff --git a/tools/obbtool/Android.mk b/tools/obbtool/Android.mk
deleted file mode 100644
index 9ff56d6..0000000
--- a/tools/obbtool/Android.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Copyright 2010 The Android Open Source Project
-#
-# Opaque Binary Blob (OBB) Tool
-#
-
-# This tool is prebuilt if we're doing an app-only build.
-ifeq ($(TARGET_BUILD_APPS),)
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	Main.cpp
-
-LOCAL_CFLAGS := -Wall -Werror
-
-#LOCAL_C_INCLUDES +=
-
-LOCAL_STATIC_LIBRARIES := \
-	libandroidfw \
-	libutils \
-	libcutils \
-	liblog
-
-ifeq ($(HOST_OS),linux)
-LOCAL_LDLIBS += -ldl -lpthread
-endif
-
-LOCAL_MODULE := obbtool
-
-include $(BUILD_HOST_EXECUTABLE)
-
-#####################################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := pbkdf2gen
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SRC_FILES := pbkdf2gen.cpp
-LOCAL_LDLIBS += -ldl
-LOCAL_C_INCLUDES := external/openssl/include $(LOCAL_C_INCLUDES)
-LOCAL_STATIC_LIBRARIES := libcrypto_static
-
-include $(BUILD_HOST_EXECUTABLE)
-
-#######################################################
-endif # TARGET_BUILD_APPS
diff --git a/tools/obbtool/Main.cpp b/tools/obbtool/Main.cpp
deleted file mode 100644
index b2152e8..0000000
--- a/tools/obbtool/Main.cpp
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <androidfw/ObbFile.h>
-#include <utils/String8.h>
-
-#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-using namespace android;
-
-static const char* gProgName = "obbtool";
-static const char* gProgVersion = "1.0";
-
-static int wantUsage = 0;
-static int wantVersion = 0;
-
-#define SALT_LEN 8
-
-#define ADD_OPTS "n:v:os:"
-static const struct option longopts[] = {
-    {"help",       no_argument, &wantUsage,   1},
-    {"version",    no_argument, &wantVersion, 1},
-
-    /* Args for "add" */
-    {"name",       required_argument, NULL, 'n'},
-    {"version",    required_argument, NULL, 'v'},
-    {"overlay",    optional_argument, NULL, 'o'},
-    {"salt",       required_argument, NULL, 's'},
-
-    {NULL, 0, NULL, '\0'}
-};
-
-class PackageInfo {
-public:
-    PackageInfo()
-            : packageName(NULL)
-            , packageVersion(-1)
-            , overlay(false)
-            , salted(false)
-    {
-        memset(&salt, 0, sizeof(salt));
-    }
-
-    char* packageName;
-    int packageVersion;
-    bool overlay;
-    bool salted;
-    unsigned char salt[SALT_LEN];
-};
-
-/*
- * Print usage info.
- */
-void usage(void)
-{
-    fprintf(stderr, "Opaque Binary Blob (OBB) Tool\n\n");
-    fprintf(stderr, "Usage:\n");
-    fprintf(stderr,
-        " %s a[dd] [ OPTIONS ] FILENAME\n"
-        "   Adds an OBB signature to the file.\n\n", gProgName);
-    fprintf(stderr,
-        "   Options:\n"
-        "     -n <package name>      sets the OBB package name (required)\n"
-        "     -v <OBB version>       sets the OBB version (required)\n"
-        "     -o                     sets the OBB overlay flag\n"
-        "     -s <8 byte hex salt>   sets the crypto key salt (if encrypted)\n"
-        "\n");
-    fprintf(stderr,
-        " %s r[emove] FILENAME\n"
-        "   Removes the OBB signature from the file.\n\n", gProgName);
-    fprintf(stderr,
-        " %s i[nfo] FILENAME\n"
-        "   Prints the OBB signature information of a file.\n\n", gProgName);
-}
-
-void doAdd(const char* filename, struct PackageInfo* info) {
-    ObbFile *obb = new ObbFile();
-    if (obb->readFrom(filename)) {
-        fprintf(stderr, "ERROR: %s: OBB signature already present\n", filename);
-        return;
-    }
-
-    obb->setPackageName(String8(info->packageName));
-    obb->setVersion(info->packageVersion);
-    obb->setOverlay(info->overlay);
-    if (info->salted) {
-        obb->setSalt(info->salt, SALT_LEN);
-    }
-
-    if (!obb->writeTo(filename)) {
-        fprintf(stderr, "ERROR: %s: couldn't write OBB signature: %s\n",
-                filename, strerror(errno));
-        return;
-    }
-
-    fprintf(stderr, "OBB signature successfully written\n");
-}
-
-void doRemove(const char* filename) {
-    ObbFile *obb = new ObbFile();
-    if (!obb->readFrom(filename)) {
-        fprintf(stderr, "ERROR: %s: no OBB signature present\n", filename);
-        return;
-    }
-
-    if (!obb->removeFrom(filename)) {
-        fprintf(stderr, "ERROR: %s: couldn't remove OBB signature\n", filename);
-        return;
-    }
-
-    fprintf(stderr, "OBB signature successfully removed\n");
-}
-
-void doInfo(const char* filename) {
-    ObbFile *obb = new ObbFile();
-    if (!obb->readFrom(filename)) {
-        fprintf(stderr, "ERROR: %s: couldn't read OBB signature\n", filename);
-        return;
-    }
-
-    printf("OBB info for '%s':\n", filename);
-    printf("Package name: %s\n", obb->getPackageName().string());
-    printf("     Version: %d\n", obb->getVersion());
-    printf("       Flags: 0x%08x\n", obb->getFlags());
-    printf("     Overlay: %s\n", obb->isOverlay() ? "true" : "false");
-    printf("        Salt: ");
-
-    size_t saltLen;
-    const unsigned char* salt = obb->getSalt(&saltLen);
-    if (salt != NULL) {
-        for (int i = 0; i < SALT_LEN; i++) {
-            printf("%02x", salt[i]);
-        }
-        printf("\n");
-    } else {
-        printf("<empty>\n");
-    }
-}
-
-bool fromHex(char h, unsigned char *b) {
-    if (h >= '0' && h <= '9') {
-        *b = h - '0';
-        return true;
-    } else if (h >= 'a' && h <= 'f') {
-        *b = h - 'a' + 10;
-        return true;
-    } else if (h >= 'A' && h <= 'F') {
-        *b = h - 'A' + 10;
-        return true;
-    }
-    return false;
-}
-
-bool hexToByte(char h1, char h2, unsigned char* b) {
-    unsigned char first, second;
-    if (!fromHex(h1, &first)) return false;
-    if (!fromHex(h2, &second)) return false;
-    *b = (first << 4) | second;
-    return true;
-}
-
-/*
- * Parse args.
- */
-int main(int argc, char* const argv[])
-{
-    int opt;
-    int option_index = 0;
-    struct PackageInfo package_info;
-
-    int result = 1;    // pessimistically assume an error.
-
-    if (argc < 2) {
-        wantUsage = 1;
-        goto bail;
-    }
-
-    while ((opt = getopt_long(argc, argv, ADD_OPTS, longopts, &option_index)) != -1) {
-        switch (opt) {
-        case 0:
-            if (longopts[option_index].flag)
-                break;
-            fprintf(stderr, "'%s' requires an argument\n", longopts[option_index].name);
-            wantUsage = 1;
-            goto bail;
-        case 'n':
-            package_info.packageName = optarg;
-            break;
-        case 'v': {
-            char* end;
-            package_info.packageVersion = strtol(optarg, &end, 10);
-            if (*optarg == '\0' || *end != '\0') {
-                fprintf(stderr, "ERROR: invalid version; should be integer!\n\n");
-                wantUsage = 1;
-                goto bail;
-            }
-            break;
-        }
-        case 'o':
-            package_info.overlay = true;
-            break;
-        case 's':
-            if (strlen(optarg) != SALT_LEN * 2) {
-                fprintf(stderr, "ERROR: salt must be 8 bytes in hex (e.g., ABCD65031337D00D)\n\n");
-                wantUsage = 1;
-                goto bail;
-            }
-
-            package_info.salted = true;
-
-            unsigned char b;
-            for (int i = 0, j = 0; i < SALT_LEN; i++, j+=2) {
-                if (!hexToByte(optarg[j], optarg[j+1], &b)) {
-                    fprintf(stderr, "ERROR: salt must be in hex (e.g., ABCD65031337D00D)\n");
-                    wantUsage = 1;
-                    goto bail;
-                }
-                package_info.salt[i] = b;
-            }
-            break;
-        case '?':
-            wantUsage = 1;
-            goto bail;
-        }
-    }
-
-    if (wantVersion) {
-        fprintf(stderr, "%s %s\n", gProgName, gProgVersion);
-    }
-
-    if (wantUsage) {
-        goto bail;
-    }
-
-#define CHECK_OP(name) \
-    if (strncmp(op, name, opsize)) { \
-        fprintf(stderr, "ERROR: unknown function '%s'!\n\n", op); \
-        wantUsage = 1; \
-        goto bail; \
-    }
-
-    if (optind < argc) {
-        const char* op = argv[optind++];
-        const int opsize = strlen(op);
-
-        if (optind >= argc) {
-            fprintf(stderr, "ERROR: filename required!\n\n");
-            wantUsage = 1;
-            goto bail;
-        }
-
-        const char* filename = argv[optind++];
-
-        switch (op[0]) {
-        case 'a':
-            CHECK_OP("add");
-            if (package_info.packageName == NULL) {
-                fprintf(stderr, "ERROR: arguments required 'packageName' and 'version'\n");
-                goto bail;
-            }
-            doAdd(filename, &package_info);
-            break;
-        case 'r':
-            CHECK_OP("remove");
-            doRemove(filename);
-            break;
-        case 'i':
-            CHECK_OP("info");
-            doInfo(filename);
-            break;
-        default:
-            fprintf(stderr, "ERROR: unknown command '%s'!\n\n", op);
-            wantUsage = 1;
-            goto bail;
-        }
-    }
-
-bail:
-    if (wantUsage) {
-        usage();
-        result = 2;
-    }
-
-    return result;
-}
diff --git a/tools/obbtool/mkobb.sh b/tools/obbtool/mkobb.sh
deleted file mode 100755
index 725250d..0000000
--- a/tools/obbtool/mkobb.sh
+++ /dev/null
@@ -1,281 +0,0 @@
-#!/bin/bash
-#
-# 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.
-#
-
-# mkobb.sh - Creates OBB files on Linux machines
-
-# Directory where we should temporarily mount the OBB loopback to copy files
-MOUNTDIR=/tmp
-
-# Presets. Changing these will probably break your OBB on the device
-CRYPTO=twofish
-FS=vfat
-MKFS=mkfs.vfat
-LOSETUP=losetup
-BLOCK_SIZE=512
-SLOP=512 # Amount of filesystem slop in ${BLOCK_SIZE} blocks
-
-find_binaries() {
-    MKFSBIN=`which ${MKFS}`
-    LOSETUPBIN=`which ${LOSETUP}`
-    MOUNTBIN=`which mount`
-    UMOUNTBIN=`which umount`
-    DDBIN=`which dd`
-    RSYNCBIN=`which rsync`
-    PBKDF2GEN=`which pbkdf2gen`
-}
-
-check_prereqs() {
-    if [ "`uname -s`x" != "Linuxx" ]; then \
-        echo "ERROR: This script only works on Linux!"
-        exit 1
-    fi
-
-    if ! egrep -q "^cryptoloop " /proc/modules; then \
-        echo "ERROR: Could not find cryptoloop in the kernel."
-        echo "Perhaps you need to: modprobe cryptoloop"
-        exit 1
-    fi
-
-    if ! egrep -q "name\s*:\s*${CRYPTO}$" /proc/crypto; then \
-        echo "ERROR: Could not find crypto \`${CRYPTO}' in the kernel."
-        echo "Perhaps you need to: modprobe ${CRYPTO}"
-        exit 1
-    fi
-
-    if ! egrep -q "^\s*${FS}$" /proc/filesystems; then \
-        echo "ERROR: Could not find filesystem \`${FS}' in the kernel."
-        echo "Perhaps you need to: modprobe ${FS}"
-        exit 1
-    fi
-
-    if [ "${MKFSBIN}x" = "x" ]; then \
-        echo "ERROR: Could not find ${MKFS} in your path!"
-        exit 1
-    elif [ ! -x "${MKFSBIN}" ]; then \
-        echo "ERROR: ${MKFSBIN} is not executable!"
-        exit 1
-    fi
-
-    if [ "${LOSETUPBIN}x" = "x" ]; then \
-        echo "ERROR: Could not find ${LOSETUP} in your path!"
-        exit 1
-    elif [ ! -x "${LOSETUPBIN}" ]; then \
-        echo "ERROR: ${LOSETUPBIN} is not executable!"
-        exit 1
-    fi
-
-    if [ "${PBKDF2GEN}x" = "x" ]; then \
-        echo "ERROR: Could not find pbkdf2gen in your path!"
-        exit 1
-    fi
-}
-
-cleanup() {
-    if [ "${loopdev}x" != "x" ]; then \
-        ${LOSETUPBIN} -d ${loopdev}
-    fi
-}
-
-hidden_prompt() {
-    unset output
-    prompt="$1"
-    outvar="$2"
-    while read -s -n 1 -p "$prompt" c; do \
-        if [ "x$c" = "x" ]; then \
-            break
-        fi
-        prompt='*'
-        output="${output}${c}"
-    done
-    echo
-    eval $outvar="$output"
-    unset output
-}
-
-read_key() {
-    hidden_prompt "        Encryption key: " key
-
-    if [ "${key}x" = "x" ]; then \
-        echo "ERROR: An empty key is not allowed!"
-        exit 1
-    fi
-
-    hidden_prompt "Encryption key (again): " key2
-
-    if [ "${key}x" != "${key2}x" ]; then \
-        echo "ERROR: Encryption keys do not match!"
-        exit 1
-    fi
-}
-
-onexit() {
-    if [ "x${temp_mount}" != "x" ]; then \
-        ${UMOUNTBIN} ${temp_mount}
-        rmdir ${temp_mount}
-    fi
-    if [ "x${loop_dev}" != "x" ]; then \
-        if [ ${use_crypto} -eq 1 ]; then \
-            dmsetup remove -f ${loop_dev}
-            ${LOSETUPBIN} -d ${old_loop_dev}
-        else \
-            ${LOSETUPBIN} -d ${loop_dev}
-        fi
-    fi
-    if [ "x${tempfile}" != "x" -a -f "${tempfile}" ]; then \
-        rm -f ${tempfile}
-    fi
-    if [ "x${keyfile}" != "x" -a -f "${keyfile}" ]; then \
-        rm -f ${keyfile}
-    fi
-    echo "Fatal error."
-    exit 1
-}
-
-usage() {
-    echo "mkobb.sh -- Create OBB files for use on Android"
-    echo ""
-    echo " -d <directory> Use <directory> as input for OBB files"
-    echo " -k <key>       Use <key> to encrypt OBB file"
-    echo " -K             Prompt for key to encrypt OBB file"
-    echo " -o <filename>  Write OBB file out to <filename>"
-    echo " -v             Verbose mode"
-    echo " -h             Help; this usage screen"
-}
-
-find_binaries
-check_prereqs
-
-use_crypto=0
-
-args=`getopt -o d:hk:Ko:v -- "$@"`
-eval set -- "$args"
-
-while true; do \
-    case "$1" in
-        -d) directory=$2; shift 2;;
-        -h) usage; exit 1;;
-        -k) key=$2; use_crypto=1; shift 2;;
-        -K) prompt_key=1; use_crypto=1; shift;;
-        -v) verbose=1; shift;;
-        -o) filename=$2; shift 2;;
-        --) shift; break;;
-        *) echo "ERROR: Invalid argument in option parsing! Cannot recover. Ever."; exit 1;;
-    esac
-done
-
-if [ "${directory}x" = "x" -o ! -d "${directory}" ]; then \
-    echo "ERROR: Must specify valid input directory"
-    echo ""
-    usage
-    exit 1;
-fi
-
-if [ "${filename}x" = "x" ]; then \
-    echo "ERROR: Must specify filename"
-    echo ""
-    usage
-    exit 1;
-fi
-
-if [ ${use_crypto} -eq 1 -a "${key}x" = "x" -a 0${prompt_key} -eq 0 ]; then \
-    echo "ERROR: Crypto desired, but no key supplied or requested to prompt for."
-    exit 1
-fi
-
-if [ 0${prompt_key} -eq 1 ]; then \
-    read_key
-fi
-
-outdir=`dirname ${filename}`
-if [ ! -d "${outdir}" ]; then \
-    echo "ERROR: Output directory does not exist: ${outdir}"
-    exit 1
-fi
-
-# Make sure we clean up any stuff we create from here on during error conditions
-trap onexit ERR
-
-tempfile=$(tempfile -d ${outdir}) || ( echo "ERROR: couldn't create temporary file in ${outdir}"; exit 1 )
-
-block_count=`du -s --apparent-size --block-size=512 ${directory} | awk '{ print $1; }'`
-if [ $? -ne 0 ]; then \
-    echo "ERROR: Couldn't read size of input directory ${directory}"
-    exit 1
-fi
-
-echo "Creating temporary file..."
-${DDBIN} if=/dev/zero of=${tempfile} bs=${BLOCK_SIZE} count=$((${block_count} + ${SLOP})) > /dev/null 2>&1
-if [ $? -ne 0 ]; then \
-    echo "ERROR: creating temporary file: $?"
-fi
-
-loop_dev=$(${LOSETUPBIN} -f) || ( echo "ERROR: losetup wouldn't tell us the next unused device"; exit 1 )
-
-${LOSETUPBIN} ${loop_dev} ${tempfile} || ( echo "ERROR: couldn't create loopback device"; exit 1 )
-
-if [ ${use_crypto} -eq 1 ]; then \
-    eval `${PBKDF2GEN} ${key}`
-    unique_dm_name=`basename ${tempfile}`
-    echo "0 `blockdev --getsize ${loop_dev}` crypt ${CRYPTO} ${key} 0 ${loop_dev} 0" | dmsetup create ${unique_dm_name}
-    old_loop_dev=${loop_dev}
-    loop_dev=/dev/mapper/${unique_dm_name}
-fi
-
-#
-# Create the filesystem
-#
-echo ""
-${MKFSBIN} -I ${loop_dev}
-echo ""
-
-#
-# Make the temporary mount point and mount it
-#
-temp_mount="${MOUNTDIR}/${RANDOM}"
-mkdir ${temp_mount}
-${MOUNTBIN} -t ${FS} -o loop ${loop_dev} ${temp_mount}
-
-#
-# rsync the files!
-#
-echo "Copying files:"
-${RSYNCBIN} -av --no-owner --no-group ${directory}/ ${temp_mount}/
-echo ""
-
-echo "Successfully created \`${filename}'"
-
-if [ ${use_crypto} -eq 1 ]; then \
-    echo "salt for use with obbtool is:"
-    echo "${salt}"
-fi
-
-#
-# Undo all the temporaries
-#
-umount ${temp_mount}
-rmdir ${temp_mount}
-if [ ${use_crypto} -eq 1 ]; then \
-    dmsetup remove -f ${loop_dev}
-    ${LOSETUPBIN} -d ${old_loop_dev}
-else \
-    ${LOSETUPBIN} -d ${loop_dev}
-fi
-mv ${tempfile} ${filename}
-
-trap - ERR
-
-exit 0
diff --git a/tools/obbtool/pbkdf2gen.cpp b/tools/obbtool/pbkdf2gen.cpp
deleted file mode 100644
index 98d67c0..0000000
--- a/tools/obbtool/pbkdf2gen.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <openssl/evp.h>
-
-#include <sys/types.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-/**
- * Simple program to generate a key based on PBKDF2 with preset inputs.
- *
- * Will print out the salt and key in hex.
- */
-
-#define SALT_LEN 8
-#define ROUNDS 1024
-#define KEY_BITS 128
-
-int main(int argc, char* argv[])
-{
-    if (argc != 2) {
-        fprintf(stderr, "Usage: %s <password>\n", argv[0]);
-        exit(1);
-    }
-
-    int fd = open("/dev/urandom", O_RDONLY);
-    if (fd < 0) {
-        fprintf(stderr, "Could not open /dev/urandom: %s\n", strerror(errno));
-        close(fd);
-        exit(1);
-    }
-
-    unsigned char salt[SALT_LEN];
-
-    if (read(fd, &salt, SALT_LEN) != SALT_LEN) {
-        fprintf(stderr, "Could not read salt from /dev/urandom: %s\n", strerror(errno));
-        close(fd);
-        exit(1);
-    }
-    close(fd);
-
-    unsigned char rawKey[KEY_BITS];
-
-    if (PKCS5_PBKDF2_HMAC_SHA1(argv[1], strlen(argv[1]), salt, SALT_LEN,
-            ROUNDS, KEY_BITS, rawKey) != 1) {
-        fprintf(stderr, "Could not generate PBKDF2 output: %s\n", strerror(errno));
-        exit(1);
-    }
-
-    printf("salt=");
-    for (int i = 0; i < SALT_LEN; i++) {
-        printf("%02x", salt[i]);
-    }
-    printf("\n");
-
-    printf("key=");
-    for (int i = 0; i < (KEY_BITS / 8); i++) {
-        printf("%02x", rawKey[i]);
-    }
-    printf("\n");
-}
diff --git a/tools/orientationplot/README.txt b/tools/orientationplot/README.txt
deleted file mode 100644
index d53f65e..0000000
--- a/tools/orientationplot/README.txt
+++ /dev/null
@@ -1,87 +0,0 @@
-This directory contains a simple python script for visualizing
-the behavior of the WindowOrientationListener.
-
-
-PREREQUISITES
--------------
-
-1. Python 2.6
-2. numpy
-3. matplotlib
-
-
-USAGE
------
-
-The tool works by scaping the debug log output from WindowOrientationListener
-for interesting data and then plotting it.
-
-1. Plug in the device.  Ensure that it is the only device plugged in
-   since this script is of very little brain and will get confused otherwise.
-
-2. Enable the Window Orientation Listener debugging data log.
-   adb shell setprop debug.orientation.log true
-   adb shell stop
-   adb shell start
-
-3. Run "orientationplot.py".
-
-
-WHAT IT ALL MEANS
------------------
-
-The tool displays several time series graphs that plot the output of the
-WindowOrientationListener.  Here you can see the raw accelerometer data,
-filtered accelerometer data, measured tilt and orientation angle, confidence
-intervals for the proposed orientation and accelerometer latency.
-
-Things to look for:
-
-1. Ensure the filtering is not too aggressive.  If the filter cut-off frequency is
-   less than about 1Hz, then the filtered accelorometer data becomes too smooth
-   and the latency for orientation detection goes up.  One way to observe this
-   is by holding the device vertically in one orientation then sharply turning
-   it 90 degrees to a different orientation.  Compared the rapid changes in the
-   raw accelerometer data with the smoothed out filtered data.  If the filtering
-   is too aggressive, the filter response may lag by hundreds of milliseconds.
-
-2. Ensure that there is an appropriate gap between adjacent orientation angles
-   for hysteresis.  Try holding the device in one orientation and slowly turning
-   it 90 degrees.  Note that the confidence intervals will all drop to 0 at some
-   point in between the two orientations; that is the gap.  The gap should be
-   observed between all adjacent pairs of orientations when turning the device
-   in either direction.
-
-   Next try holding the device in one orientation and rapidly turning it end
-   over end to a midpoint about 45 degrees between two opposing orientations.
-   There should be no gap observed initially.  The algorithm should pick one
-   of the orientations and settle into it (since it is obviously quite
-   different from the original orientation of the device).  However, once it
-   settles, the confidence values should start trending to 0 again because
-   the measured orientation angle is now within the gap between the new
-   orientation and the adjacent orientation.
-
-   In other words, the hysteresis gap applies only when the measured orientation
-   angle (say, 45 degrees) is between the current orientation's ideal angle
-   (say, 0 degrees) and an adjacent orientation's ideal angle (say, 90 degrees).
-
-3. Accelerometer jitter.  The accelerometer latency graph displays the interval
-   between sensor events as reported by the SensorEvent.timestamp field.  It
-   should be a fairly constant 60ms.  If the latency jumps around wildly or
-   greatly exceeds 60ms then there is a problem with the accelerometer or the
-   sensor manager.
-
-4. The orientation angle is not measured when the tilt is too close to 90 or -90
-   degrees (refer to MAX_TILT constant).  Consequently, you should expect there
-   to be no data.  Likewise, all dependent calculations are suppressed in this case
-   so there will be no orientation proposal either.
-
-5. Each orientation has its own bound on allowable tilt angles.  It's a good idea to
-   verify that these limits are being enforced by gradually varying the tilt of
-   the device until it is inside/outside the limit for each orientation.
-
-6. Orientation changes should be significantly harder when the device is held
-   overhead.  People reading on tablets in bed often have their head turned
-   a little to the side, or they hold the device loosely so its orientation
-   can be a bit unusual.  The tilt is a good indicator of whether the device is
-   overhead.
diff --git a/tools/orientationplot/orientationplot.py b/tools/orientationplot/orientationplot.py
deleted file mode 100755
index 6fc3922..0000000
--- a/tools/orientationplot/orientationplot.py
+++ /dev/null
@@ -1,457 +0,0 @@
-#!/usr/bin/env python2.6
-#
-# 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.
-#
-
-#
-# Plots debug log output from WindowOrientationListener.
-# See README.txt for details.
-#
-
-import numpy as np
-import matplotlib.pyplot as plot
-import subprocess
-import re
-import fcntl
-import os
-import errno
-import bisect
-from datetime import datetime, timedelta
-
-# Parameters.
-timespan = 15 # seconds total span shown
-scrolljump = 5 # seconds jump when scrolling
-timeticks = 1 # seconds between each time tick
-
-# Non-blocking stream wrapper.
-class NonBlockingStream:
-  def __init__(self, stream):
-    fcntl.fcntl(stream, fcntl.F_SETFL, os.O_NONBLOCK)
-    self.stream = stream
-    self.buffer = ''
-    self.pos = 0
-
-  def readline(self):
-    while True:
-      index = self.buffer.find('\n', self.pos)
-      if index != -1:
-        result = self.buffer[self.pos:index]
-        self.pos = index + 1
-        return result
-
-      self.buffer = self.buffer[self.pos:]
-      self.pos = 0
-      try:
-        chunk = os.read(self.stream.fileno(), 4096)
-      except OSError, e:
-        if e.errno == errno.EAGAIN:
-          return None
-        raise e
-      if len(chunk) == 0:
-        if len(self.buffer) == 0:
-          raise(EOFError)
-        else:
-          result = self.buffer
-          self.buffer = ''
-          self.pos = 0
-          return result
-      self.buffer += chunk
-
-# Plotter
-class Plotter:
-  def __init__(self, adbout):
-    self.adbout = adbout
-
-    self.fig = plot.figure(1)
-    self.fig.suptitle('Window Orientation Listener', fontsize=12)
-    self.fig.set_dpi(96)
-    self.fig.set_size_inches(16, 12, forward=True)
-
-    self.raw_acceleration_x = self._make_timeseries()
-    self.raw_acceleration_y = self._make_timeseries()
-    self.raw_acceleration_z = self._make_timeseries()
-    self.raw_acceleration_magnitude = self._make_timeseries()
-    self.raw_acceleration_axes = self._add_timeseries_axes(
-        1, 'Raw Acceleration', 'm/s^2', [-20, 20],
-        yticks=range(-15, 16, 5))
-    self.raw_acceleration_line_x = self._add_timeseries_line(
-        self.raw_acceleration_axes, 'x', 'red')
-    self.raw_acceleration_line_y = self._add_timeseries_line(
-        self.raw_acceleration_axes, 'y', 'green')
-    self.raw_acceleration_line_z = self._add_timeseries_line(
-        self.raw_acceleration_axes, 'z', 'blue')
-    self.raw_acceleration_line_magnitude = self._add_timeseries_line(
-        self.raw_acceleration_axes, 'magnitude', 'orange', linewidth=2)
-    self._add_timeseries_legend(self.raw_acceleration_axes)
-
-    shared_axis = self.raw_acceleration_axes
-
-    self.filtered_acceleration_x = self._make_timeseries()
-    self.filtered_acceleration_y = self._make_timeseries()
-    self.filtered_acceleration_z = self._make_timeseries()
-    self.filtered_acceleration_magnitude = self._make_timeseries()
-    self.filtered_acceleration_axes = self._add_timeseries_axes(
-        2, 'Filtered Acceleration', 'm/s^2', [-20, 20],
-        sharex=shared_axis,
-        yticks=range(-15, 16, 5))
-    self.filtered_acceleration_line_x = self._add_timeseries_line(
-        self.filtered_acceleration_axes, 'x', 'red')
-    self.filtered_acceleration_line_y = self._add_timeseries_line(
-        self.filtered_acceleration_axes, 'y', 'green')
-    self.filtered_acceleration_line_z = self._add_timeseries_line(
-        self.filtered_acceleration_axes, 'z', 'blue')
-    self.filtered_acceleration_line_magnitude = self._add_timeseries_line(
-        self.filtered_acceleration_axes, 'magnitude', 'orange', linewidth=2)
-    self._add_timeseries_legend(self.filtered_acceleration_axes)
-
-    self.tilt_angle = self._make_timeseries()
-    self.tilt_angle_axes = self._add_timeseries_axes(
-        3, 'Tilt Angle', 'degrees', [-105, 105],
-        sharex=shared_axis,
-        yticks=range(-90, 91, 30))
-    self.tilt_angle_line = self._add_timeseries_line(
-        self.tilt_angle_axes, 'tilt', 'black')
-    self._add_timeseries_legend(self.tilt_angle_axes)
-
-    self.orientation_angle = self._make_timeseries()
-    self.orientation_angle_axes = self._add_timeseries_axes(
-        4, 'Orientation Angle', 'degrees', [-25, 375],
-        sharex=shared_axis,
-        yticks=range(0, 361, 45))
-    self.orientation_angle_line = self._add_timeseries_line(
-        self.orientation_angle_axes, 'orientation', 'black')
-    self._add_timeseries_legend(self.orientation_angle_axes)
-
-    self.current_rotation = self._make_timeseries()
-    self.proposed_rotation = self._make_timeseries()
-    self.predicted_rotation = self._make_timeseries()
-    self.orientation_axes = self._add_timeseries_axes(
-        5, 'Current / Proposed Orientation', 'rotation', [-1, 4],
-        sharex=shared_axis,
-        yticks=range(0, 4))
-    self.current_rotation_line = self._add_timeseries_line(
-        self.orientation_axes, 'current', 'black', linewidth=2)
-    self.predicted_rotation_line = self._add_timeseries_line(
-        self.orientation_axes, 'predicted', 'purple', linewidth=3)
-    self.proposed_rotation_line = self._add_timeseries_line(
-        self.orientation_axes, 'proposed', 'green', linewidth=3)
-    self._add_timeseries_legend(self.orientation_axes)
-
-    self.time_until_settled = self._make_timeseries()
-    self.time_until_flat_delay_expired = self._make_timeseries()
-    self.time_until_swing_delay_expired = self._make_timeseries()
-    self.time_until_acceleration_delay_expired = self._make_timeseries()
-    self.stability_axes = self._add_timeseries_axes(
-        6, 'Proposal Stability', 'ms', [-10, 600],
-        sharex=shared_axis,
-        yticks=range(0, 600, 100))
-    self.time_until_settled_line = self._add_timeseries_line(
-        self.stability_axes, 'time until settled', 'black', linewidth=2)
-    self.time_until_flat_delay_expired_line = self._add_timeseries_line(
-        self.stability_axes, 'time until flat delay expired', 'green')
-    self.time_until_swing_delay_expired_line = self._add_timeseries_line(
-        self.stability_axes, 'time until swing delay expired', 'blue')
-    self.time_until_acceleration_delay_expired_line = self._add_timeseries_line(
-        self.stability_axes, 'time until acceleration delay expired', 'red')
-    self._add_timeseries_legend(self.stability_axes)
-
-    self.sample_latency = self._make_timeseries()
-    self.sample_latency_axes = self._add_timeseries_axes(
-        7, 'Accelerometer Sampling Latency', 'ms', [-10, 500],
-        sharex=shared_axis,
-        yticks=range(0, 500, 100))
-    self.sample_latency_line = self._add_timeseries_line(
-        self.sample_latency_axes, 'latency', 'black')
-    self._add_timeseries_legend(self.sample_latency_axes)
-
-    self.fig.canvas.mpl_connect('button_press_event', self._on_click)
-    self.paused = False
-
-    self.timer = self.fig.canvas.new_timer(interval=100)
-    self.timer.add_callback(lambda: self.update())
-    self.timer.start()
-
-    self.timebase = None
-    self._reset_parse_state()
-
-  # Handle a click event to pause or restart the timer.
-  def _on_click(self, ev):
-    if not self.paused:
-      self.paused = True
-      self.timer.stop()
-    else:
-      self.paused = False
-      self.timer.start()
-
-  # Initialize a time series.
-  def _make_timeseries(self):
-    return [[], []]
-
-  # Add a subplot to the figure for a time series.
-  def _add_timeseries_axes(self, index, title, ylabel, ylim, yticks, sharex=None):
-    num_graphs = 7
-    height = 0.9 / num_graphs
-    top = 0.95 - height * index
-    axes = self.fig.add_axes([0.1, top, 0.8, height],
-        xscale='linear',
-        xlim=[0, timespan],
-        ylabel=ylabel,
-        yscale='linear',
-        ylim=ylim,
-        sharex=sharex)
-    axes.text(0.02, 0.02, title, transform=axes.transAxes, fontsize=10, fontweight='bold')
-    axes.set_xlabel('time (s)', fontsize=10, fontweight='bold')
-    axes.set_ylabel(ylabel, fontsize=10, fontweight='bold')
-    axes.set_xticks(range(0, timespan + 1, timeticks))
-    axes.set_yticks(yticks)
-    axes.grid(True)
-
-    for label in axes.get_xticklabels():
-      label.set_fontsize(9)
-    for label in axes.get_yticklabels():
-      label.set_fontsize(9)
-
-    return axes
-
-  # Add a line to the axes for a time series.
-  def _add_timeseries_line(self, axes, label, color, linewidth=1):
-    return axes.plot([], label=label, color=color, linewidth=linewidth)[0]
-
-  # Add a legend to a time series.
-  def _add_timeseries_legend(self, axes):
-    axes.legend(
-        loc='upper left',
-        bbox_to_anchor=(1.01, 1),
-        borderpad=0.1,
-        borderaxespad=0.1,
-        prop={'size': 10})
-
-  # Resets the parse state.
-  def _reset_parse_state(self):
-    self.parse_raw_acceleration_x = None
-    self.parse_raw_acceleration_y = None
-    self.parse_raw_acceleration_z = None
-    self.parse_raw_acceleration_magnitude = None
-    self.parse_filtered_acceleration_x = None
-    self.parse_filtered_acceleration_y = None
-    self.parse_filtered_acceleration_z = None
-    self.parse_filtered_acceleration_magnitude = None
-    self.parse_tilt_angle = None
-    self.parse_orientation_angle = None
-    self.parse_current_rotation = None
-    self.parse_proposed_rotation = None
-    self.parse_predicted_rotation = None
-    self.parse_time_until_settled = None
-    self.parse_time_until_flat_delay_expired = None
-    self.parse_time_until_swing_delay_expired = None
-    self.parse_time_until_acceleration_delay_expired = None
-    self.parse_sample_latency = None
-
-  # Update samples.
-  def update(self):
-    timeindex = 0
-    while True:
-      try:
-        line = self.adbout.readline()
-      except EOFError:
-        plot.close()
-        return
-      if line is None:
-        break
-      print line
-
-      try:
-        timestamp = self._parse_timestamp(line)
-      except ValueError, e:
-        continue
-      if self.timebase is None:
-        self.timebase = timestamp
-      delta = timestamp - self.timebase
-      timeindex = delta.seconds + delta.microseconds * 0.000001
-
-      if line.find('Raw acceleration vector:') != -1:
-        self.parse_raw_acceleration_x = self._get_following_number(line, 'x=')
-        self.parse_raw_acceleration_y = self._get_following_number(line, 'y=')
-        self.parse_raw_acceleration_z = self._get_following_number(line, 'z=')
-        self.parse_raw_acceleration_magnitude = self._get_following_number(line, 'magnitude=')
-
-      if line.find('Filtered acceleration vector:') != -1:
-        self.parse_filtered_acceleration_x = self._get_following_number(line, 'x=')
-        self.parse_filtered_acceleration_y = self._get_following_number(line, 'y=')
-        self.parse_filtered_acceleration_z = self._get_following_number(line, 'z=')
-        self.parse_filtered_acceleration_magnitude = self._get_following_number(line, 'magnitude=')
-
-      if line.find('tiltAngle=') != -1:
-        self.parse_tilt_angle = self._get_following_number(line, 'tiltAngle=')
-
-      if line.find('orientationAngle=') != -1:
-        self.parse_orientation_angle = self._get_following_number(line, 'orientationAngle=')
-
-      if line.find('Result:') != -1:
-        self.parse_current_rotation = self._get_following_number(line, 'currentRotation=')
-        self.parse_proposed_rotation = self._get_following_number(line, 'proposedRotation=')
-        self.parse_predicted_rotation = self._get_following_number(line, 'predictedRotation=')
-        self.parse_sample_latency = self._get_following_number(line, 'timeDeltaMS=')
-        self.parse_time_until_settled = self._get_following_number(line, 'timeUntilSettledMS=')
-        self.parse_time_until_flat_delay_expired = self._get_following_number(line, 'timeUntilFlatDelayExpiredMS=')
-        self.parse_time_until_swing_delay_expired = self._get_following_number(line, 'timeUntilSwingDelayExpiredMS=')
-        self.parse_time_until_acceleration_delay_expired = self._get_following_number(line, 'timeUntilAccelerationDelayExpiredMS=')
-
-        self._append(self.raw_acceleration_x, timeindex, self.parse_raw_acceleration_x)
-        self._append(self.raw_acceleration_y, timeindex, self.parse_raw_acceleration_y)
-        self._append(self.raw_acceleration_z, timeindex, self.parse_raw_acceleration_z)
-        self._append(self.raw_acceleration_magnitude, timeindex, self.parse_raw_acceleration_magnitude)
-        self._append(self.filtered_acceleration_x, timeindex, self.parse_filtered_acceleration_x)
-        self._append(self.filtered_acceleration_y, timeindex, self.parse_filtered_acceleration_y)
-        self._append(self.filtered_acceleration_z, timeindex, self.parse_filtered_acceleration_z)
-        self._append(self.filtered_acceleration_magnitude, timeindex, self.parse_filtered_acceleration_magnitude)
-        self._append(self.tilt_angle, timeindex, self.parse_tilt_angle)
-        self._append(self.orientation_angle, timeindex, self.parse_orientation_angle)
-        self._append(self.current_rotation, timeindex, self.parse_current_rotation)
-        if self.parse_proposed_rotation >= 0:
-          self._append(self.proposed_rotation, timeindex, self.parse_proposed_rotation)
-        else:
-          self._append(self.proposed_rotation, timeindex, None)
-        if self.parse_predicted_rotation >= 0:
-          self._append(self.predicted_rotation, timeindex, self.parse_predicted_rotation)
-        else:
-          self._append(self.predicted_rotation, timeindex, None)
-        self._append(self.time_until_settled, timeindex, self.parse_time_until_settled)
-        self._append(self.time_until_flat_delay_expired, timeindex, self.parse_time_until_flat_delay_expired)
-        self._append(self.time_until_swing_delay_expired, timeindex, self.parse_time_until_swing_delay_expired)
-        self._append(self.time_until_acceleration_delay_expired, timeindex, self.parse_time_until_acceleration_delay_expired)
-        self._append(self.sample_latency, timeindex, self.parse_sample_latency)
-        self._reset_parse_state()
-
-    # Scroll the plots.
-    if timeindex > timespan:
-      bottom = int(timeindex) - timespan + scrolljump
-      self.timebase += timedelta(seconds=bottom)
-      self._scroll(self.raw_acceleration_x, bottom)
-      self._scroll(self.raw_acceleration_y, bottom)
-      self._scroll(self.raw_acceleration_z, bottom)
-      self._scroll(self.raw_acceleration_magnitude, bottom)
-      self._scroll(self.filtered_acceleration_x, bottom)
-      self._scroll(self.filtered_acceleration_y, bottom)
-      self._scroll(self.filtered_acceleration_z, bottom)
-      self._scroll(self.filtered_acceleration_magnitude, bottom)
-      self._scroll(self.tilt_angle, bottom)
-      self._scroll(self.orientation_angle, bottom)
-      self._scroll(self.current_rotation, bottom)
-      self._scroll(self.proposed_rotation, bottom)
-      self._scroll(self.predicted_rotation, bottom)
-      self._scroll(self.time_until_settled, bottom)
-      self._scroll(self.time_until_flat_delay_expired, bottom)
-      self._scroll(self.time_until_swing_delay_expired, bottom)
-      self._scroll(self.time_until_acceleration_delay_expired, bottom)
-      self._scroll(self.sample_latency, bottom)
-
-    # Redraw the plots.
-    self.raw_acceleration_line_x.set_data(self.raw_acceleration_x)
-    self.raw_acceleration_line_y.set_data(self.raw_acceleration_y)
-    self.raw_acceleration_line_z.set_data(self.raw_acceleration_z)
-    self.raw_acceleration_line_magnitude.set_data(self.raw_acceleration_magnitude)
-    self.filtered_acceleration_line_x.set_data(self.filtered_acceleration_x)
-    self.filtered_acceleration_line_y.set_data(self.filtered_acceleration_y)
-    self.filtered_acceleration_line_z.set_data(self.filtered_acceleration_z)
-    self.filtered_acceleration_line_magnitude.set_data(self.filtered_acceleration_magnitude)
-    self.tilt_angle_line.set_data(self.tilt_angle)
-    self.orientation_angle_line.set_data(self.orientation_angle)
-    self.current_rotation_line.set_data(self.current_rotation)
-    self.proposed_rotation_line.set_data(self.proposed_rotation)
-    self.predicted_rotation_line.set_data(self.predicted_rotation)
-    self.time_until_settled_line.set_data(self.time_until_settled)
-    self.time_until_flat_delay_expired_line.set_data(self.time_until_flat_delay_expired)
-    self.time_until_swing_delay_expired_line.set_data(self.time_until_swing_delay_expired)
-    self.time_until_acceleration_delay_expired_line.set_data(self.time_until_acceleration_delay_expired)
-    self.sample_latency_line.set_data(self.sample_latency)
-
-    self.fig.canvas.draw_idle()
-
-  # Scroll a time series.
-  def _scroll(self, timeseries, bottom):
-    bottom_index = bisect.bisect_left(timeseries[0], bottom)
-    del timeseries[0][:bottom_index]
-    del timeseries[1][:bottom_index]
-    for i, timeindex in enumerate(timeseries[0]):
-      timeseries[0][i] = timeindex - bottom
-
-  # Extract a word following the specified prefix.
-  def _get_following_word(self, line, prefix):
-    prefix_index = line.find(prefix)
-    if prefix_index == -1:
-      return None
-    start_index = prefix_index + len(prefix)
-    delim_index = line.find(',', start_index)
-    if delim_index == -1:
-      return line[start_index:]
-    else:
-      return line[start_index:delim_index]
-
-  # Extract a number following the specified prefix.
-  def _get_following_number(self, line, prefix):
-    word = self._get_following_word(line, prefix)
-    if word is None:
-      return None
-    return float(word)
-
-  # Extract an array of numbers following the specified prefix.
-  def _get_following_array_of_numbers(self, line, prefix):
-    prefix_index = line.find(prefix + '[')
-    if prefix_index == -1:
-      return None
-    start_index = prefix_index + len(prefix) + 1
-    delim_index = line.find(']', start_index)
-    if delim_index == -1:
-      return None
-
-    result = []
-    while start_index < delim_index:
-      comma_index = line.find(', ', start_index, delim_index)
-      if comma_index == -1:
-        result.append(float(line[start_index:delim_index]))
-        break;
-      result.append(float(line[start_index:comma_index]))
-      start_index = comma_index + 2
-    return result
-
-  # Add a value to a time series.
-  def _append(self, timeseries, timeindex, number):
-    timeseries[0].append(timeindex)
-    timeseries[1].append(number)
-
-  # Parse the logcat timestamp.
-  # Timestamp has the form '01-21 20:42:42.930'
-  def _parse_timestamp(self, line):
-    return datetime.strptime(line[0:18], '%m-%d %H:%M:%S.%f')
-
-# Notice
-print "Window Orientation Listener plotting tool"
-print "-----------------------------------------\n"
-print "Please turn on the Window Orientation Listener logging in Development Settings."
-
-# Start adb.
-print "Starting adb logcat.\n"
-
-adb = subprocess.Popen(['adb', 'logcat', '-s', '-v', 'time', 'WindowOrientationListener:V'],
-    stdout=subprocess.PIPE)
-adbout = NonBlockingStream(adb.stdout)
-
-# Prepare plotter.
-plotter = Plotter(adbout)
-plotter.update()
-
-# Main loop.
-plot.show()
diff --git a/tools/preload/20080522.compiled b/tools/preload/20080522.compiled
deleted file mode 100644
index a2af422..0000000
--- a/tools/preload/20080522.compiled
+++ /dev/null
Binary files differ
diff --git a/tools/preload/20090811.compiled b/tools/preload/20090811.compiled
deleted file mode 100644
index 6dbeca0..0000000
--- a/tools/preload/20090811.compiled
+++ /dev/null
Binary files differ
diff --git a/tools/preload/20100223.compiled b/tools/preload/20100223.compiled
deleted file mode 100644
index 3056388..0000000
--- a/tools/preload/20100223.compiled
+++ /dev/null
Binary files differ
diff --git a/tools/preload/Android.mk b/tools/preload/Android.mk
deleted file mode 100644
index f325870..0000000
--- a/tools/preload/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	Compile.java  \
-	LoadedClass.java \
-	MemoryUsage.java \
-	Operation.java \
-	Policy.java \
-	PrintCsv.java \
-	PrintHtmlDiff.java \
-	PrintPsTree.java \
-	Proc.java \
-	Record.java \
-	Root.java \
-	WritePreloadedClassFile.java
-
-LOCAL_MODULE:= preload
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-include $(call all-subdir-makefiles)
diff --git a/tools/preload/Compile.java b/tools/preload/Compile.java
deleted file mode 100644
index 67258ef..0000000
--- a/tools/preload/Compile.java
+++ /dev/null
@@ -1,73 +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.
- */
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Parses and analyzes a log, pulling our PRELOAD information. If you have
- * an emulator or device running in the background, this class will use it
- * to measure and record the memory usage of each class.
- * 
- * TODO: Should analyze lines and select substring dynamically (instead of hardcoded 19)
- */
-public class Compile {
-
-    public static void main(String[] args) throws IOException {
-        if (args.length != 2) {
-            System.err.println("Usage: Compile [log file] [output file]");
-            System.exit(0);
-        }
-
-        Root root = new Root();
-
-        List<Record> records = new ArrayList<Record>();
-
-        BufferedReader in = new BufferedReader(new InputStreamReader(
-                new FileInputStream(args[0])));
-
-        String line;
-        int lineNumber = 0;
-        while ((line = in.readLine()) != null) {
-            lineNumber++;
-            if (line.startsWith("I/PRELOAD")) {
-                try {
-                    String clipped = line.substring(19);
-                    records.add(new Record(clipped, lineNumber));
-                } catch (RuntimeException e) {
-                    throw new RuntimeException(
-                            "Exception while recording line " + lineNumber + ": " + line, e);
-                }
-            }
-        }
-
-        for (Record record : records) {
-            root.indexProcess(record);
-        }
-
-        for (Record record : records) {
-            root.indexClassOperation(record);
-        }
-
-        in.close();
-
-        root.toFile(args[1]);
-    }
-}
diff --git a/tools/preload/LoadedClass.java b/tools/preload/LoadedClass.java
deleted file mode 100644
index 86e5dfc..0000000
--- a/tools/preload/LoadedClass.java
+++ /dev/null
@@ -1,130 +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.
- */
-
-import java.io.Serializable;
-import java.util.*;
-
-/**
- * A loaded class.
- */
-class LoadedClass implements Serializable, Comparable<LoadedClass> {
-
-    private static final long serialVersionUID = 0;
-
-    /** Class name. */
-    final String name;
-
-    /** Load operations. */
-    final List<Operation> loads = new ArrayList<Operation>();
-
-    /** Static initialization operations. */
-    final List<Operation> initializations = new ArrayList<Operation>();
-
-    /** Memory usage gathered by loading only this class in its own VM. */
-    MemoryUsage memoryUsage = MemoryUsage.NOT_AVAILABLE;
-
-    /**
-     * Whether or not this class was loaded in the system class loader.
-     */
-    final boolean systemClass;
-
-    /** Whether or not this class will be preloaded. */
-    boolean preloaded;
-
-    /** Constructs a new class. */
-    LoadedClass(String name, boolean systemClass) {
-        this.name = name;
-        this.systemClass = systemClass;
-    }
-
-    void measureMemoryUsage() {
-        this.memoryUsage = MemoryUsage.forClass(name);
-    }
-
-    int mlt = -1;
-
-    /** Median time to load this class. */
-    int medianLoadTimeMicros() {
-        if (mlt != -1) {
-            return mlt;
-        }
-
-        return mlt = calculateMedian(loads);
-    }
-
-    int mit = -1;
-
-    /** Median time to initialize this class. */
-    int medianInitTimeMicros() {
-        if (mit != -1) {
-            return mit;
-        }
-
-        return mit = calculateMedian(initializations);
-    }
-
-    int medianTimeMicros() {
-        return medianInitTimeMicros() + medianLoadTimeMicros();
-    }
-
-    /** Calculates the median duration for a list of operations. */
-    private static int calculateMedian(List<Operation> operations) {
-        int size = operations.size();
-        if (size == 0) {
-            return 0;
-        }
-
-        int[] times = new int[size];
-        for (int i = 0; i < size; i++) {
-            times[i] = operations.get(i).exclusiveTimeMicros();
-        }
-
-        Arrays.sort(times);
-        int middle = size / 2;
-        if (size % 2 == 1) {
-            // Odd
-            return times[middle];
-        } else {
-            // Even -- average the two.
-            return (times[middle - 1] + times[middle]) / 2;
-        }
-    }
-
-    /** Returns names of processes that loaded this class. */
-    Set<String> processNames() {
-        Set<String> names = new HashSet<String>();
-        addProcessNames(loads, names);
-        addProcessNames(initializations, names);
-        return names;
-    }
-
-    private void addProcessNames(List<Operation> ops, Set<String> names) {
-        for (Operation operation : ops) {
-            if (operation.process.fromZygote()) {
-                names.add(operation.process.name);
-            }
-        }
-    }
-
-    public int compareTo(LoadedClass o) {
-        return name.compareTo(o.name);
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
-}
diff --git a/tools/preload/MemoryUsage.java b/tools/preload/MemoryUsage.java
deleted file mode 100644
index d8f95f4..0000000
--- a/tools/preload/MemoryUsage.java
+++ /dev/null
@@ -1,298 +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.
- */
-
-import java.io.Serializable;
-import java.io.IOException;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * Memory usage information.
- */
-class MemoryUsage implements Serializable {
-
-    private static final long serialVersionUID = 0;
-
-    static final MemoryUsage NOT_AVAILABLE = new MemoryUsage();
-    
-    static int errorCount = 0;
-
-    // These values are in 1kB increments (not 4kB like you'd expect).
-    final int nativeSharedPages;
-    final int javaSharedPages;
-    final int otherSharedPages;
-    final int nativePrivatePages;
-    final int javaPrivatePages;
-    final int otherPrivatePages;
-
-    final int allocCount;
-    final int allocSize;
-    final int freedCount;
-    final int freedSize;
-    final long nativeHeapSize;
-
-    public MemoryUsage(String line) {
-        String[] parsed = line.split(",");
-
-        nativeSharedPages = Integer.parseInt(parsed[1]);
-        javaSharedPages = Integer.parseInt(parsed[2]);
-        otherSharedPages = Integer.parseInt(parsed[3]);
-        nativePrivatePages = Integer.parseInt(parsed[4]);
-        javaPrivatePages = Integer.parseInt(parsed[5]);
-        otherPrivatePages = Integer.parseInt(parsed[6]);
-        allocCount = Integer.parseInt(parsed[7]);
-        allocSize = Integer.parseInt(parsed[8]);
-        freedCount = Integer.parseInt(parsed[9]);
-        freedSize = Integer.parseInt(parsed[10]);
-        nativeHeapSize = Long.parseLong(parsed[11]);
-    }
-
-    MemoryUsage() {
-        nativeSharedPages = -1;
-        javaSharedPages = -1;
-        otherSharedPages = -1;
-        nativePrivatePages = -1;
-        javaPrivatePages = -1;
-        otherPrivatePages = -1;
-
-        allocCount = -1;
-        allocSize = -1;
-        freedCount = -1;
-        freedSize = -1;
-        nativeHeapSize = -1;
-    }
-
-    MemoryUsage(int nativeSharedPages,
-            int javaSharedPages,
-            int otherSharedPages,
-            int nativePrivatePages,
-            int javaPrivatePages,
-            int otherPrivatePages,
-            int allocCount,
-            int allocSize,
-            int freedCount,
-            int freedSize,
-            long nativeHeapSize) {
-        this.nativeSharedPages = nativeSharedPages;
-        this.javaSharedPages = javaSharedPages;
-        this.otherSharedPages = otherSharedPages;
-        this.nativePrivatePages = nativePrivatePages;
-        this.javaPrivatePages = javaPrivatePages;
-        this.otherPrivatePages = otherPrivatePages;
-        this.allocCount = allocCount;
-        this.allocSize = allocSize;
-        this.freedCount = freedCount;
-        this.freedSize = freedSize;
-        this.nativeHeapSize = nativeHeapSize;
-    }
-
-    MemoryUsage subtract(MemoryUsage baseline) {
-        return new MemoryUsage(
-                nativeSharedPages - baseline.nativeSharedPages,
-                javaSharedPages - baseline.javaSharedPages,
-                otherSharedPages - baseline.otherSharedPages,
-                nativePrivatePages - baseline.nativePrivatePages,
-                javaPrivatePages - baseline.javaPrivatePages,
-                otherPrivatePages - baseline.otherPrivatePages,
-                allocCount - baseline.allocCount,
-                allocSize - baseline.allocSize,
-                freedCount - baseline.freedCount,
-                freedSize - baseline.freedSize,
-                nativeHeapSize - baseline.nativeHeapSize);
-    }
-
-    int javaHeapSize() {
-        return allocSize - freedSize;
-    }
-
-    int totalHeap() {
-        return javaHeapSize() + (int) nativeHeapSize;
-    }
-
-    int javaPagesInK() {
-        return javaSharedPages + javaPrivatePages;
-    }
-
-    int nativePagesInK() {
-        return nativeSharedPages + nativePrivatePages;
-    }
-    int otherPagesInK() {
-        return otherSharedPages + otherPrivatePages;
-    }
-
-    int totalPages() {
-        return javaSharedPages + javaPrivatePages + nativeSharedPages +
-                nativePrivatePages + otherSharedPages + otherPrivatePages;
-    }
-
-    /**
-     * Was this information available?
-     */
-    boolean isAvailable() {
-        return nativeSharedPages != -1;
-    }
-
-    /**
-     * Measures baseline memory usage.
-     */
-    static MemoryUsage baseline() {
-        return forClass(null);
-    }
-
-    private static final String CLASS_PATH = "-Xbootclasspath"
-            + ":/system/framework/core.jar"
-            + ":/system/framework/ext.jar"
-            + ":/system/framework/framework.jar"
-            + ":/system/framework/framework-tests.jar"
-            + ":/system/framework/services.jar"
-            + ":/system/framework/loadclass.jar";
-
-    private static final String[] GET_DIRTY_PAGES = {
-        "adb", "shell", "dalvikvm", CLASS_PATH, "LoadClass" };
-
-    /**
-     * Measures memory usage for the given class.
-     */
-    static MemoryUsage forClass(String className) {
-        MeasureWithTimeout measurer = new MeasureWithTimeout(className);
-
-        new Thread(measurer).start();
-
-        synchronized (measurer) {
-            if (measurer.memoryUsage == null) {
-                // Wait up to 10s.
-                try {
-                    measurer.wait(30000);
-                } catch (InterruptedException e) {
-                    System.err.println("Interrupted waiting for measurement.");
-                    e.printStackTrace();
-                    return NOT_AVAILABLE;
-                }
-
-                // If it's still null.
-                if (measurer.memoryUsage == null) {
-                    System.err.println("Timed out while measuring "
-                            + className + ".");
-                    return NOT_AVAILABLE;
-                }
-            }
-
-            System.err.println("Got memory usage for " + className + ".");
-            return measurer.memoryUsage;
-        }
-    }
-
-    static class MeasureWithTimeout implements Runnable {
-
-        final String className;
-        MemoryUsage memoryUsage = null;
-
-        MeasureWithTimeout(String className) {
-            this.className = className;
-        }
-
-        public void run() {
-            MemoryUsage measured = measure();
-
-            synchronized (this) {
-                memoryUsage = measured;
-                notifyAll();
-            }
-        }
-
-        private MemoryUsage measure() {
-            String[] commands = GET_DIRTY_PAGES;
-            if (className != null) {
-                List<String> commandList = new ArrayList<String>(
-                        GET_DIRTY_PAGES.length + 1);
-                commandList.addAll(Arrays.asList(commands));
-                commandList.add(className);
-                commands = commandList.toArray(new String[commandList.size()]);
-            }
-
-            try {
-                final Process process = Runtime.getRuntime().exec(commands);
-
-                final InputStream err = process.getErrorStream();
-
-                // Send error output to stderr.
-                Thread errThread = new Thread() {
-                    @Override
-                    public void run() {
-                        copy(err, System.err);
-                    }
-                };
-                errThread.setDaemon(true);
-                errThread.start();
-
-                BufferedReader in = new BufferedReader(
-                        new InputStreamReader(process.getInputStream()));
-                String line = in.readLine();
-                if (line == null || !line.startsWith("DECAFBAD,")) {
-                    System.err.println("Got bad response for " + className
-                            + ": " + line + "; command was " + Arrays.toString(commands));
-                    errorCount += 1;
-                    return NOT_AVAILABLE;
-                }
-
-                in.close();
-                err.close();
-                process.destroy();                
-
-                return new MemoryUsage(line);
-            } catch (IOException e) {
-                System.err.println("Error getting stats for "
-                        + className + ".");                
-                e.printStackTrace();
-                return NOT_AVAILABLE;
-            }
-        }
-
-    }
-
-    /**
-     * Copies from one stream to another.
-     */
-    private static void copy(InputStream in, OutputStream out) {
-        byte[] buffer = new byte[1024];
-        int read;
-        try {
-            while ((read = in.read(buffer)) > -1) {
-                out.write(buffer, 0, read);
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    /** Measures memory usage information and stores it in the model. */
-    public static void main(String[] args) throws IOException,
-            ClassNotFoundException {
-        Root root = Root.fromFile(args[0]);
-        root.baseline = baseline();
-        for (LoadedClass loadedClass : root.loadedClasses.values()) {
-            if (loadedClass.systemClass) {
-                loadedClass.measureMemoryUsage();
-            }
-        }
-        root.toFile(args[0]);
-    }
-}
diff --git a/tools/preload/Operation.java b/tools/preload/Operation.java
deleted file mode 100644
index 4f1938e..0000000
--- a/tools/preload/Operation.java
+++ /dev/null
@@ -1,136 +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.
- */
-
-import java.util.List;
-import java.util.ArrayList;
-import java.io.Serializable;
-
-/**
- * An operation with a duration. Could represent a class load or initialization.
- */
-class Operation implements Serializable {
-
-    private static final long serialVersionUID = 0;
-    
-    /**
-     * Type of operation.
-     */
-    enum Type {
-        LOAD, INIT
-    }
-
-    /** Process this operation occurred in. */
-    final Proc process;
-
-    /** Start time for this operation. */
-    final long startTimeNanos;
-
-    /** Index of this operation relative to its process. */
-    final int index;
-
-    /** Type of operation. */
-    final Type type;
-
-    /** End time for this operation. */
-    long endTimeNanos = -1;
-
-    /** The class that this operation loaded or initialized. */
-    final LoadedClass loadedClass;
-
-    /** Other operations that occurred during this one. */
-    final List<Operation> subops = new ArrayList<Operation>();
-
-    /** Constructs a new operation. */
-    Operation(Proc process, LoadedClass loadedClass, long startTimeNanos,
-            int index, Type type) {
-        this.process = process;
-        this.loadedClass = loadedClass;
-        this.startTimeNanos = startTimeNanos;
-        this.index = index;
-        this.type = type;
-    }
-
-    /**
-     * Returns how long this class initialization and all the nested class
-     * initializations took.
-     */
-    private long inclusiveTimeNanos() {
-        if (endTimeNanos == -1) {
-            throw new IllegalStateException("End time hasn't been set yet: "
-                    + loadedClass.name);
-        }
-
-        return endTimeNanos - startTimeNanos;
-    }
-
-    /**
-     * Returns how long this class initialization took.
-     */
-    int exclusiveTimeMicros() {
-        long exclusive = inclusiveTimeNanos();
-
-        for (Operation child : subops) {
-            exclusive -= child.inclusiveTimeNanos();
-        }
-
-        if (exclusive < 0) {
-            throw new AssertionError(loadedClass.name);
-        }
-
-        return nanosToMicros(exclusive);
-    }
-
-    /** Gets the median time that this operation took across all processes. */
-    int medianExclusiveTimeMicros() {
-        switch (type) {
-            case LOAD: return loadedClass.medianLoadTimeMicros();
-            case INIT: return loadedClass.medianInitTimeMicros();
-            default: throw new AssertionError();
-        }
-    }
-
-    /**
-     * Converts nanoseconds to microseconds.
-     *
-     * @throws RuntimeException if overflow occurs
-     */
-    private static int nanosToMicros(long nanos) {
-        long micros = nanos / 1000;
-        int microsInt = (int) micros;
-        if (microsInt != micros) {
-            throw new RuntimeException("Integer overflow: " + nanos);
-        }
-        return microsInt;
-    }
-    
-    /**
-     * Primarily for debugger support
-     */
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(type.toString());
-        sb.append(' ');
-        sb.append(loadedClass.toString());
-        if (subops.size() > 0) {
-            sb.append(" (");
-            sb.append(subops.size());
-            sb.append(" sub ops)");
-        }
-        return sb.toString();
-    }
-
-}
diff --git a/tools/preload/Policy.java b/tools/preload/Policy.java
deleted file mode 100644
index af46820..0000000
--- a/tools/preload/Policy.java
+++ /dev/null
@@ -1,89 +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.
- */
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Policy that governs which classes are preloaded.
- */
-public class Policy {
-
-    /**
-     * No constructor - use static methods only
-     */
-    private Policy() {}
-
-    /**
-     * This location (in the build system) of the preloaded-classes file.
-     */
-    static final String PRELOADED_CLASS_FILE
-            = "frameworks/base/preloaded-classes";
-
-    /**
-     * Long running services. These are restricted in their contribution to the 
-     * preloader because their launch time is less critical.
-     */
-    // TODO: Generate this automatically from package manager.
-    private static final Set<String> SERVICES = new HashSet<String>(Arrays.asList(
-        "system_server",
-        "com.google.process.content",
-        "android.process.media",
-        "com.android.bluetooth",
-        "com.android.calendar",
-        "com.android.inputmethod.latin",
-        "com.android.phone",
-        "com.google.android.apps.maps.FriendService", // pre froyo
-        "com.google.android.apps.maps:FriendService", // froyo
-        "com.google.android.apps.maps.LocationFriendService",
-        "com.google.android.deskclock",
-        "com.google.process.gapps",
-        "android.tts"
-    ));
-
-    /**
-     * Classes which we shouldn't load from the Zygote.
-     */
-    private static final Set<String> EXCLUDED_CLASSES
-            = new HashSet<String>(Arrays.asList(
-        // Binders
-        "android.app.AlarmManager",
-        "android.app.SearchManager",
-        "android.os.FileObserver",
-        "com.android.server.PackageManagerService$AppDirObserver",
-
-        // Threads
-        "android.os.AsyncTask",
-        "android.pim.ContactsAsyncHelper",
-        "android.webkit.WebViewClassic$1",
-        "java.lang.ProcessManager"
-    ));
-
-    /**
-     * Returns true if the given process name is a "long running" process or
-     * service.
-     */
-    public static boolean isService(String processName) {
-        return SERVICES.contains(processName);
-    }
-
-    /** Reports if the given class should be preloaded. */
-    public static boolean isPreloadable(LoadedClass clazz) {
-        return clazz.systemClass && !EXCLUDED_CLASSES.contains(clazz.name)
-                && !clazz.name.endsWith("$NoPreloadHolder");
-    }
-}
diff --git a/tools/preload/PrintCsv.java b/tools/preload/PrintCsv.java
deleted file mode 100644
index 1820830..0000000
--- a/tools/preload/PrintCsv.java
+++ /dev/null
@@ -1,127 +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.
- */
-
-import java.io.IOException;
-import java.io.FileInputStream;
-import java.io.ObjectInputStream;
-import java.io.BufferedInputStream;
-import java.io.Writer;
-import java.io.PrintStream;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.TreeSet;
-import java.util.Iterator;
-
-/**
- * Prints raw information in CSV format.
- */
-public class PrintCsv {
-
-    public static void main(String[] args)
-            throws IOException, ClassNotFoundException {
-        if (args.length != 1) {
-            System.err.println("Usage: PrintCsv [compiled log file]");
-            System.exit(0);
-        }
-
-        Root root = Root.fromFile(args[0]);
-
-        printHeaders(System.out);
-
-        MemoryUsage baseline = MemoryUsage.baseline();
-
-        for (LoadedClass loadedClass : root.loadedClasses.values()) {
-            if (!loadedClass.systemClass) {
-                continue;
-            }
-
-            printRow(System.out, baseline, loadedClass);
-        }
-    }
-
-    static void printHeaders(PrintStream out) {
-        out.println("Name"
-                + ",Preloaded"
-                + ",Median Load Time (us)"
-                + ",Median Init Time (us)"
-                + ",Process Names"
-                + ",Load Count"
-                + ",Init Count"
-                + ",Managed Heap (B)"
-                + ",Native Heap (B)"
-                + ",Managed Pages (kB)"
-                + ",Native Pages (kB)"
-                + ",Other Pages (kB)");
-    }
-
-    static void printRow(PrintStream out, MemoryUsage baseline,
-            LoadedClass loadedClass) {
-        out.print(loadedClass.name);
-        out.print(',');
-        out.print(loadedClass.preloaded);
-        out.print(',');
-        out.print(loadedClass.medianLoadTimeMicros());
-        out.print(',');
-        out.print(loadedClass.medianInitTimeMicros());
-        out.print(',');
-        out.print('"');
-
-        Set<String> procNames = new TreeSet<String>();
-        for (Operation op : loadedClass.loads)
-            procNames.add(op.process.name);
-        for (Operation op : loadedClass.initializations)
-            procNames.add(op.process.name);
-
-        if (procNames.size() <= 3) {
-            for (String name : procNames) {
-                out.print(name + "\n");
-            }
-        } else {
-            Iterator<String> i = procNames.iterator();
-            out.print(i.next() + "\n");
-            out.print(i.next() + "\n");
-            out.print("...and " + (procNames.size() - 2)
-                    + " others.");
-        }
-
-        out.print('"');
-        out.print(',');
-        out.print(loadedClass.loads.size());
-        out.print(',');
-        out.print(loadedClass.initializations.size());
-
-        if (loadedClass.memoryUsage.isAvailable()) {
-            MemoryUsage subtracted
-                    = loadedClass.memoryUsage.subtract(baseline);
-
-            out.print(',');
-            out.print(subtracted.javaHeapSize());
-            out.print(',');
-            out.print(subtracted.nativeHeapSize);
-            out.print(',');
-            out.print(subtracted.javaPagesInK());
-            out.print(',');
-            out.print(subtracted.nativePagesInK());
-            out.print(',');
-            out.print(subtracted.otherPagesInK());
-
-        } else {
-            out.print(",n/a,n/a,n/a,n/a,n/a");
-        }
-
-        out.println();
-    }
-}
diff --git a/tools/preload/PrintHtmlDiff.java b/tools/preload/PrintHtmlDiff.java
deleted file mode 100644
index b101c85..0000000
--- a/tools/preload/PrintHtmlDiff.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.IOException;
-import java.io.FileReader;
-import java.io.BufferedReader;
-import java.io.PrintStream;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.HashSet;
-import java.util.Iterator;
-
-/**
- * Prints HTML containing removed and added files.
- */
-public class PrintHtmlDiff {
-
-    private static final String OLD_PRELOADED_CLASSES
-            = "old-preloaded-classes";
-
-    public static void main(String[] args) throws IOException,
-            ClassNotFoundException {
-        Root root = Root.fromFile(args[0]);
-
-        BufferedReader oldClasses = new BufferedReader(
-            new FileReader(OLD_PRELOADED_CLASSES));
-
-        // Classes loaded implicitly by the zygote.
-        Set<LoadedClass> zygote = new HashSet<LoadedClass>();
-        for (Proc proc : root.processes.values()) {
-            if (proc.name.equals("zygote")) {
-                for (Operation op : proc.operations) {
-                    zygote.add(op.loadedClass);
-                }
-                break;
-            }
-        }
-
-        Set<LoadedClass> removed = new TreeSet<LoadedClass>();
-        Set<LoadedClass> added = new TreeSet<LoadedClass>();
-
-        for (LoadedClass loadedClass : root.loadedClasses.values()) {
-            if (loadedClass.preloaded && !zygote.contains(loadedClass)) {
-                added.add(loadedClass);
-            }
-        }
-
-        String line;
-        while ((line = oldClasses.readLine()) != null) {
-            line = line.trim();
-            LoadedClass clazz = root.loadedClasses.get(line);
-            if (clazz != null) {
-                added.remove(clazz);
-                if (!clazz.preloaded) removed.add(clazz);
-            }
-        }
-
-        PrintStream out = System.out;
-
-        out.println("<html><body>");
-        out.println("<style>");
-        out.println("a, th, td, h2 { font-family: arial }");
-        out.println("th, td { font-size: small }");
-        out.println("</style>");
-        out.println("<script src=\"sorttable.js\"></script>");
-        out.println("<p><a href=\"#removed\">Removed</a>");
-        out.println("<a name=\"added\"/><h2>Added</h2>");
-        printTable(out, root.baseline, added);
-        out.println("<a name=\"removed\"/><h2>Removed</h2>");
-        printTable(out, root.baseline, removed);
-        out.println("</body></html>");
-    }
-
-    static void printTable(PrintStream out, MemoryUsage baseline,
-            Iterable<LoadedClass> classes) {
-        out.println("<table border=\"1\" cellpadding=\"5\""
-                + " class=\"sortable\">");
-
-        out.println("<thead><tr>");
-        out.println("<th>Name</th>");
-        out.println("<th>Load Time (us)</th>");
-        out.println("<th>Loaded By</th>");
-        out.println("<th>Heap (B)</th>");
-        out.println("<th>Pages</th>");
-        out.println("</tr></thead>");
-
-        for (LoadedClass clazz : classes) {
-            out.println("<tr>");
-            out.println("<td>" + clazz.name + "</td>");
-            out.println("<td>" + clazz.medianTimeMicros() + "</td>");
-
-            out.println("<td>");
-            Set<String> procNames = new TreeSet<String>();
-            for (Operation op : clazz.loads) procNames.add(op.process.name);
-            for (Operation op : clazz.initializations) {
-                procNames.add(op.process.name);
-            }
-            if (procNames.size() <= 3) {
-                for (String name : procNames) {
-                    out.print(name + "<br/>");
-                }
-            } else {
-                Iterator<String> i = procNames.iterator();
-                out.print(i.next() + "<br/>");
-                out.print(i.next() + "<br/>");
-                out.print("...and " + (procNames.size() - 2)
-                        + " others.");
-            }
-            out.println("</td>");
-
-            if (clazz.memoryUsage.isAvailable()) {
-                MemoryUsage subtracted
-                        = clazz.memoryUsage.subtract(baseline);
-
-                out.println("<td>" + (subtracted.javaHeapSize()
-                        + subtracted.nativeHeapSize) + "</td>");
-                out.println("<td>" + subtracted.totalPages() + "</td>");
-            } else {
-                for (int i = 0; i < 2; i++) {
-                    out.println("<td>n/a</td>");                    
-                }
-            }
-
-            out.println("</tr>");
-        }
-
-        out.println("</table>");
-    }
-}
diff --git a/tools/preload/PrintPsTree.java b/tools/preload/PrintPsTree.java
deleted file mode 100644
index 22701fa..0000000
--- a/tools/preload/PrintPsTree.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.IOException;
-import java.io.FileInputStream;
-import java.io.ObjectInputStream;
-import java.io.BufferedInputStream;
-
-/**
- * Prints raw information in CSV format.
- */
-public class PrintPsTree {
-
-    public static void main(String[] args)
-            throws IOException, ClassNotFoundException {
-        if (args.length != 1) {
-            System.err.println("Usage: PrintCsv [compiled log file]");
-            System.exit(0);
-        }
-
-        FileInputStream fin = new FileInputStream(args[0]);
-        ObjectInputStream oin = new ObjectInputStream(
-                new BufferedInputStream(fin));
-
-        Root root = (Root) oin.readObject();
-
-        for (Proc proc : root.processes.values()) {
-            if (proc.parent == null) {
-                proc.print();                                
-            }
-        }
-    }
-}
diff --git a/tools/preload/Proc.java b/tools/preload/Proc.java
deleted file mode 100644
index 2105021..0000000
--- a/tools/preload/Proc.java
+++ /dev/null
@@ -1,168 +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.
- */
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.HashMap;
-import java.io.Serializable;
-
-/**
- * A Dalvik process.
- */
-class Proc implements Serializable {
-
-    private static final long serialVersionUID = 0;
-
-    /** Parent process. */
-    final Proc parent;
-
-    /** Process ID. */
-    final int id;
-
-    /**
-     * Name of this process. We may not have the correct name at first, i.e.
-     * some classes could have been loaded before the process name was set.
-     */
-    String name;
-
-    /** Child processes. */
-    final List<Proc> children = new ArrayList<Proc>();
-
-    /** Maps thread ID to operation stack. */
-    transient final Map<Integer, LinkedList<Operation>> stacks
-            = new HashMap<Integer, LinkedList<Operation>>();
-
-    /** Number of operations. */
-    int operationCount;
-
-    /** Sequential list of operations that happened in this process. */
-    final List<Operation> operations = new ArrayList<Operation>();
-
-    /** List of past process names. */
-    final List<String> nameHistory = new ArrayList<String>();
-
-    /** Constructs a new process. */
-    Proc(Proc parent, int id) {
-        this.parent = parent;
-        this.id = id;
-    }
-
-    /** Sets name of this process. */
-    void setName(String name) {
-        if (!name.equals(this.name)) {
-            if (this.name != null) {
-                nameHistory.add(this.name);
-            }
-            this.name = name;
-        }
-    }
-
-    /**
-     * Returns true if this process comes from the zygote.
-     */
-    public boolean fromZygote() {
-        return parent != null && parent.name.equals("zygote")
-                && !name.equals("com.android.development");
-    }
-
-    /**
-     * Starts an operation.
-     *
-     * @param threadId thread the operation started in
-     * @param loadedClass class operation happened to
-     * @param time the operation started
-     */
-    void startOperation(int threadId, LoadedClass loadedClass, long time,
-            Operation.Type type) {
-        Operation o = new Operation(
-                this, loadedClass, time, operationCount++, type);
-        operations.add(o);
-
-        LinkedList<Operation> stack = stacks.get(threadId);
-        if (stack == null) {
-            stack = new LinkedList<Operation>();
-            stacks.put(threadId, stack);
-        }
-
-        if (!stack.isEmpty()) {
-            stack.getLast().subops.add(o);
-        }
-
-        stack.add(o);
-    }
-
-    /**
-     * Ends an operation.
-     *
-     * @param threadId thread the operation ended in
-     * @param loadedClass class operation happened to
-     * @param time the operation ended
-     */
-    Operation endOperation(int threadId, String className,
-            LoadedClass loadedClass, long time) {
-        LinkedList<Operation> stack = stacks.get(threadId);
-
-        if (stack == null || stack.isEmpty()) {
-            didNotStart(className);
-            return null;
-        }
-
-        Operation o = stack.getLast();
-        if (loadedClass != o.loadedClass) {
-            didNotStart(className);
-            return null;
-        }
-
-        stack.removeLast();
-
-        o.endTimeNanos = time;
-        return o;
-    }
-
-    /**
-     * Prints an error indicating that we saw the end of an operation but not
-     * the start. A bug in the logging framework which results in dropped logs
-     * causes this.
-     */
-    private static void didNotStart(String name) {
-        System.err.println("Warning: An operation ended on " + name
-            + " but it never started!");
-    }
-
-    /**
-     * Prints this process tree to stdout.
-     */
-    void print() {
-        print("");
-    }
-
-    /**
-     * Prints a child proc to standard out.
-     */
-    private void print(String prefix) {
-        System.out.println(prefix + "id=" + id + ", name=" + name);
-        for (Proc child : children) {
-            child.print(prefix + "    ");
-        }
-    }
-
-    @Override
-    public String toString() {
-        return this.name;
-    }
-}
diff --git a/tools/preload/Record.java b/tools/preload/Record.java
deleted file mode 100644
index d0a2af4..0000000
--- a/tools/preload/Record.java
+++ /dev/null
@@ -1,182 +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.
- */
-
-/**
- * One line from the loaded-classes file.
- */
-class Record {
-
-    /**
-     * The delimiter character we use, {@code :}, conflicts with some other
-     * names. In that case, manually replace the delimiter with something else.
-     */
-    private static final String[] REPLACE_CLASSES = {
-            "com.google.android.apps.maps:FriendService",
-            "com.google.android.apps.maps\\u003AFriendService",
-            "com.google.android.apps.maps:driveabout",
-            "com.google.android.apps.maps\\u003Adriveabout",
-            "com.google.android.apps.maps:GoogleLocationService",
-            "com.google.android.apps.maps\\u003AGoogleLocationService",
-            "com.google.android.apps.maps:LocationFriendService",
-            "com.google.android.apps.maps\\u003ALocationFriendService",
-            "com.google.android.apps.maps:MapsBackgroundService",
-            "com.google.android.apps.maps\\u003AMapsBackgroundService",
-            "com.google.android.apps.maps:NetworkLocationService",
-            "com.google.android.apps.maps\\u003ANetworkLocationService",
-            "com.android.chrome:sandboxed_process",
-            "com.android.chrome\\u003Asandboxed_process",
-            "com.android.fakeoemfeatures:background",
-            "com.android.fakeoemfeatures\\u003Abackground",
-            "com.android.fakeoemfeatures:core",
-            "com.android.fakeoemfeatures\\u003Acore",
-            "com.android.launcher:wallpaper_chooser",
-            "com.android.launcher\\u003Awallpaper_chooser",
-            "com.android.nfc:handover",
-            "com.android.nfc\\u003Ahandover",
-            "com.google.android.music:main",
-            "com.google.android.music\\u003Amain",
-            "com.google.android.music:ui",
-            "com.google.android.music\\u003Aui",
-            "com.google.android.setupwarlock:broker",
-            "com.google.android.setupwarlock\\u003Abroker",
-            "mobi.mgeek.TunnyBrowser:DolphinNotification",
-            "mobi.mgeek.TunnyBrowser\\u003ADolphinNotification",
-            "com.qo.android.sp.oem:Quickword",
-            "com.qo.android.sp.oem\\u003AQuickword",
-            "android:ui",
-            "android\\u003Aui",
-            "system:ui",
-            "system\\u003Aui",
-    };
-
-    enum Type {
-        /** Start of initialization. */
-        START_LOAD,
-
-        /** End of initialization. */
-        END_LOAD,
-
-        /** Start of initialization. */
-        START_INIT,
-
-        /** End of initialization. */
-        END_INIT
-    }
-
-    /** Parent process ID. */
-    final int ppid;
-
-    /** Process ID. */
-    final int pid;
-
-    /** Thread ID. */
-    final int tid;
-
-    /** Process name. */
-    final String processName;
-
-    /** Class loader pointer. */
-    final int classLoader;
-
-    /** Type of record. */
-    final Type type;
-
-    /** Name of loaded class. */
-    final String className;
-
-    /** Record time (ns). */
-    final long time;
-
-    /** Source file line# */
-    int sourceLineNumber;
-
-    /**
-     * Parses a line from the loaded-classes file.
-     */
-    Record(String line, int lineNum) {
-        char typeChar = line.charAt(0);
-        switch (typeChar) {
-            case '>': type = Type.START_LOAD; break;
-            case '<': type = Type.END_LOAD; break;
-            case '+': type = Type.START_INIT; break;
-            case '-': type = Type.END_INIT; break;
-            default: throw new AssertionError("Bad line: " + line);
-        }
-
-        sourceLineNumber = lineNum;
-
-        for (int i = 0; i < REPLACE_CLASSES.length; i+= 2) {
-            line = line.replace(REPLACE_CLASSES[i], REPLACE_CLASSES[i+1]);
-        }
-
-        line = line.substring(1);
-        String[] parts = line.split(":");
-
-        ppid = Integer.parseInt(parts[0]);
-        pid = Integer.parseInt(parts[1]);
-        tid = Integer.parseInt(parts[2]);
-
-        processName = decode(parts[3]).intern();
-
-        classLoader = Integer.parseInt(parts[4]);
-        className = vmTypeToLanguage(decode(parts[5])).intern();
-
-        time = Long.parseLong(parts[6]);
-    }
-
-    /**
-     * Decode any escaping that may have been written to the log line.
-     *
-     * Supports unicode-style escaping:  \\uXXXX = character in hex
-     *
-     * @param rawField the field as it was written into the log
-     * @result the same field with any escaped characters replaced
-     */
-    String decode(String rawField) {
-        String result = rawField;
-        int offset = result.indexOf("\\u");
-        while (offset >= 0) {
-            String before = result.substring(0, offset);
-            String escaped = result.substring(offset+2, offset+6);
-            String after = result.substring(offset+6);
-
-            result = String.format("%s%c%s", before, Integer.parseInt(escaped, 16), after);
-
-            // find another but don't recurse
-            offset = result.indexOf("\\u", offset + 1);
-        }
-        return result;
-    }
-
-    /**
-     * Converts a VM-style name to a language-style name.
-     */
-    String vmTypeToLanguage(String typeName) {
-        // if the typename is (null), just return it as-is.  This is probably in dexopt and
-        // will be discarded anyway.  NOTE: This corresponds to the case in dalvik/vm/oo/Class.c
-        // where dvmLinkClass() returns false and we clean up and exit.
-        if ("(null)".equals(typeName)) {
-            return typeName;
-        }
-
-        if (!typeName.startsWith("L") || !typeName.endsWith(";") ) {
-            throw new AssertionError("Bad name: " + typeName + " in line " + sourceLineNumber);
-        }
-
-        typeName = typeName.substring(1, typeName.length() - 1);
-        return typeName.replace("/", ".");
-    }
-}
diff --git a/tools/preload/Root.java b/tools/preload/Root.java
deleted file mode 100644
index 0bc29bf..0000000
--- a/tools/preload/Root.java
+++ /dev/null
@@ -1,163 +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.
- */
-
-import java.io.Serializable;
-import java.io.IOException;
-import java.io.Writer;
-import java.io.BufferedWriter;
-import java.io.OutputStreamWriter;
-import java.io.FileOutputStream;
-import java.io.FileInputStream;
-import java.io.ObjectInputStream;
-import java.io.BufferedInputStream;
-import java.io.ObjectOutputStream;
-import java.io.BufferedOutputStream;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.Arrays;
-import java.nio.charset.Charset;
-
-/**
- * Root of our data model.
- */
-public class Root implements Serializable {
-
-    private static final long serialVersionUID = 0;
-
-    /** pid -> Proc */
-    final Map<Integer, Proc> processes = new HashMap<Integer, Proc>();
-
-    /** Class name -> LoadedClass */
-    final Map<String, LoadedClass> loadedClasses
-            = new HashMap<String, LoadedClass>();
-
-    MemoryUsage baseline = MemoryUsage.baseline();
-
-    /**
-     * Records class loads and initializations.
-     */
-    void indexClassOperation(Record record) {
-        Proc process = processes.get(record.pid);
-
-        // Ignore dexopt output. It loads applications classes through the
-        // system class loader and messes us up.
-        if (record.processName.equals("dexopt")) {
-            return;
-        }
-
-        String name = record.className;
-        LoadedClass loadedClass = loadedClasses.get(name);
-        Operation o = null;
-
-        switch (record.type) {
-            case START_LOAD:
-            case START_INIT:
-                if (loadedClass == null) {
-                    loadedClass = new LoadedClass(
-                            name, record.classLoader == 0);
-                    if (loadedClass.systemClass) {
-                        // Only measure memory for classes in the boot
-                        // classpath.
-                        loadedClass.measureMemoryUsage();
-                    }
-                    loadedClasses.put(name, loadedClass);
-                }
-                break;
-
-            case END_LOAD:
-            case END_INIT:
-                o = process.endOperation(record.tid, record.className,
-                        loadedClass, record.time);
-                if (o == null) {
-                    return;
-                }
-        }
-
-        switch (record.type) {
-            case START_LOAD:
-                process.startOperation(record.tid, loadedClass, record.time,
-                        Operation.Type.LOAD);
-                break;
-
-            case START_INIT:
-                process.startOperation(record.tid, loadedClass, record.time,
-                        Operation.Type.INIT);
-                break;
-
-            case END_LOAD:
-                loadedClass.loads.add(o);
-                break;
-
-            case END_INIT:
-                loadedClass.initializations.add(o);
-                break;
-        }
-    }
-
-    /**
-     * Indexes information about the process from the given record.
-     */
-    void indexProcess(Record record) {
-        Proc proc = processes.get(record.pid);
-
-        if (proc == null) {
-            // Create a new process object.
-            Proc parent = processes.get(record.ppid);
-            proc = new Proc(parent, record.pid);
-            processes.put(proc.id, proc);
-            if (parent != null) {
-                parent.children.add(proc);
-            }
-        }
-
-        proc.setName(record.processName);
-    }
-
-    /**
-     * Writes this graph to a file.
-     */
-    void toFile(String fileName) throws IOException {
-        FileOutputStream out = new FileOutputStream(fileName);
-        ObjectOutputStream oout = new ObjectOutputStream(
-                new BufferedOutputStream(out));
-
-        System.err.println("Writing object model...");
-
-        oout.writeObject(this);
-
-        oout.close();
-
-        System.err.println("Done!");
-    }
-
-    /**
-     * Reads Root from a file.
-     */
-    static Root fromFile(String fileName)
-            throws IOException, ClassNotFoundException {
-        FileInputStream fin = new FileInputStream(fileName);
-        ObjectInputStream oin = new ObjectInputStream(
-                new BufferedInputStream(fin));
-
-        Root root = (Root) oin.readObject();
-
-        oin.close();
-
-        return root;
-    }
-}
diff --git a/tools/preload/WritePreloadedClassFile.java b/tools/preload/WritePreloadedClassFile.java
deleted file mode 100644
index b067bc2..0000000
--- a/tools/preload/WritePreloadedClassFile.java
+++ /dev/null
@@ -1,155 +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.
- */
-
-import java.io.BufferedWriter;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.nio.charset.Charset;
-import java.util.Set;
-import java.util.TreeSet;
-
-/**
- * Writes /frameworks/base/preloaded-classes. Also updates
- * {@link LoadedClass#preloaded} fields and writes over compiled log file.
- */
-public class WritePreloadedClassFile {
-
-    /**
-     * Preload any class that take longer to load than MIN_LOAD_TIME_MICROS us.
-     */
-    static final int MIN_LOAD_TIME_MICROS = 1250;
-
-    /**
-     * Preload any class that was loaded by at least MIN_PROCESSES processes.
-     */
-    static final int MIN_PROCESSES = 10;
-
-    public static void main(String[] args) throws IOException,
-            ClassNotFoundException {
-        if (args.length != 1) {
-            System.err.println("Usage: WritePreloadedClassFile [compiled log]");
-            System.exit(-1);
-        }
-        String rootFile = args[0];
-        Root root = Root.fromFile(rootFile);
-
-        // No classes are preloaded to start.
-        for (LoadedClass loadedClass : root.loadedClasses.values()) {
-            loadedClass.preloaded = false;
-        }
-
-        // Open preloaded-classes file for output.
-        Writer out = new BufferedWriter(new OutputStreamWriter(
-                new FileOutputStream(Policy.PRELOADED_CLASS_FILE),
-                Charset.forName("US-ASCII")));
-
-        out.write("# Classes which are preloaded by"
-                + " com.android.internal.os.ZygoteInit.\n");
-        out.write("# Automatically generated by frameworks/base/tools/preload/"
-            + WritePreloadedClassFile.class.getSimpleName() + ".java.\n");
-        out.write("# MIN_LOAD_TIME_MICROS=" + MIN_LOAD_TIME_MICROS + "\n");
-        out.write("# MIN_PROCESSES=" + MIN_PROCESSES + "\n");
-
-        /*
-         * The set of classes to preload. We preload a class if:
-         *
-         *  a) it's loaded in the bootclasspath (i.e., is a system class)
-         *  b) it takes > MIN_LOAD_TIME_MICROS us to load, and
-         *  c) it's loaded by more than one process, or it's loaded by an
-         *     application (i.e., not a long running service)
-         */
-        Set<LoadedClass> toPreload = new TreeSet<LoadedClass>();
-
-        // Preload classes that were loaded by at least 2 processes. Hopefully,
-        // the memory associated with these classes will be shared.
-        for (LoadedClass loadedClass : root.loadedClasses.values()) {
-            Set<String> names = loadedClass.processNames();
-            if (!Policy.isPreloadable(loadedClass)) {
-                continue;
-            }
-
-            if (names.size() >= MIN_PROCESSES ||
-                    (loadedClass.medianTimeMicros() > MIN_LOAD_TIME_MICROS && names.size() > 1)) {
-                toPreload.add(loadedClass);
-            }
-        }
-
-        int initialSize = toPreload.size();
-        System.out.println(initialSize
-                + " classses were loaded by more than one app.");
-
-        // Preload eligable classes from applications (not long-running
-        // services).
-        for (Proc proc : root.processes.values()) {
-            if (proc.fromZygote() && !Policy.isService(proc.name)) {
-                for (Operation operation : proc.operations) {
-                    LoadedClass loadedClass = operation.loadedClass;
-                    if (shouldPreload(loadedClass)) {
-                        toPreload.add(loadedClass);
-                    }
-                }
-            }
-        }
-
-        System.out.println("Added " + (toPreload.size() - initialSize)
-                + " more to speed up applications.");
-
-        System.out.println(toPreload.size()
-                + " total classes will be preloaded.");
-
-        // Make classes that were implicitly loaded by the zygote explicit.
-        // This adds minimal overhead but avoid confusion about classes not
-        // appearing in the list.
-        addAllClassesFrom("zygote", root, toPreload);
-
-        for (LoadedClass loadedClass : toPreload) {
-            out.write(loadedClass.name + "\n");
-        }
-
-        out.close();
-
-        // Update data to reflect LoadedClass.preloaded changes.
-        for (LoadedClass loadedClass : toPreload) {
-            loadedClass.preloaded = true;
-        }
-        root.toFile(rootFile);
-    }
-
-    private static void addAllClassesFrom(String processName, Root root,
-            Set<LoadedClass> toPreload) {
-        for (Proc proc : root.processes.values()) {
-            if (proc.name.equals(processName)) {
-                for (Operation operation : proc.operations) {
-                    boolean preloadable
-                            = Policy.isPreloadable(operation.loadedClass);
-                    if (preloadable) {
-                        toPreload.add(operation.loadedClass);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns true if the class should be preloaded.
-     */
-    private static boolean shouldPreload(LoadedClass clazz) {
-        return Policy.isPreloadable(clazz)
-                && clazz.medianTimeMicros() > MIN_LOAD_TIME_MICROS;
-    }
-}
diff --git a/tools/preload/loadclass/Android.mk b/tools/preload/loadclass/Android.mk
deleted file mode 100644
index 65828be..0000000
--- a/tools/preload/loadclass/Android.mk
+++ /dev/null
@@ -1,9 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_MODULE := loadclass
-
-include $(BUILD_JAVA_LIBRARY)
diff --git a/tools/preload/loadclass/LoadClass.java b/tools/preload/loadclass/LoadClass.java
deleted file mode 100644
index a71b6a8..0000000
--- a/tools/preload/loadclass/LoadClass.java
+++ /dev/null
@@ -1,84 +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.
- */
-
-import android.util.Log;
-import android.os.Debug;
-
-/**
- * Loads a class, runs the garbage collector, and prints showmap output.
- *
- * <p>Usage: dalvikvm LoadClass [class name]
- */
-class LoadClass {
-
-    public static void main(String[] args) {
-        System.loadLibrary("android_runtime");
-
-        if (registerNatives() < 0) {
-            throw new RuntimeException("Error registering natives.");    
-        }
-
-        Debug.startAllocCounting();
-
-        if (args.length > 0) {
-            try {
-                long start = System.currentTimeMillis();
-                Class.forName(args[0]);
-                long elapsed = System.currentTimeMillis() - start;
-                Log.i("LoadClass", "Loaded " + args[0] + " in " + elapsed
-                        + "ms.");
-            } catch (ClassNotFoundException e) {
-                Log.w("LoadClass", e);
-                return;
-            }
-        }
-
-        System.gc();
-
-        int allocCount = Debug.getGlobalAllocCount();
-        int allocSize = Debug.getGlobalAllocSize();
-        int freedCount = Debug.getGlobalFreedCount();
-        int freedSize = Debug.getGlobalFreedSize();
-        long nativeHeapSize = Debug.getNativeHeapSize();
-
-        Debug.stopAllocCounting();
-
-        StringBuilder response = new StringBuilder("DECAFBAD");
-
-        int[] pages = new int[6];
-        Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
-        Debug.getMemoryInfo(memoryInfo);
-        response.append(',').append(memoryInfo.nativeSharedDirty);
-        response.append(',').append(memoryInfo.dalvikSharedDirty);
-        response.append(',').append(memoryInfo.otherSharedDirty);
-        response.append(',').append(memoryInfo.nativePrivateDirty);
-        response.append(',').append(memoryInfo.dalvikPrivateDirty);
-        response.append(',').append(memoryInfo.otherPrivateDirty);
-
-        response.append(',').append(allocCount);
-        response.append(',').append(allocSize);
-        response.append(',').append(freedCount);
-        response.append(',').append(freedSize);
-        response.append(',').append(nativeHeapSize);
-        
-        System.out.println(response.toString());
-    }
-
-    /**
-     * Registers native functions. See AndroidRuntime.cpp.
-     */
-    static native int registerNatives();
-}
diff --git a/tools/preload/preload.iml b/tools/preload/preload.iml
deleted file mode 100644
index 2d87c55..0000000
--- a/tools/preload/preload.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module relativePaths="true" type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="false">
-    <output url="file:///tmp/preload" />
-    <output-test url="file:///tmp/preload" />
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>
-
diff --git a/tools/preload/preload.ipr b/tools/preload/preload.ipr
deleted file mode 100644
index 0c9621c..0000000
--- a/tools/preload/preload.ipr
+++ /dev/null
@@ -1,495 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project relativePaths="false" version="4">
-  <component name="AntConfiguration">
-    <defaultAnt bundledAnt="true" />
-  </component>
-  <component name="BuildJarProjectSettings">
-    <option name="BUILD_JARS_ON_MAKE" value="false" />
-  </component>
-  <component name="ChangeBrowserSettings">
-    <option name="MAIN_SPLITTER_PROPORTION" value="0.3" />
-    <option name="MESSAGES_SPLITTER_PROPORTION" value="0.8" />
-    <option name="USE_DATE_BEFORE_FILTER" value="false" />
-    <option name="USE_DATE_AFTER_FILTER" value="false" />
-    <option name="USE_CHANGE_BEFORE_FILTER" value="false" />
-    <option name="USE_CHANGE_AFTER_FILTER" value="false" />
-    <option name="DATE_BEFORE" value="" />
-    <option name="DATE_AFTER" value="" />
-    <option name="CHANGE_BEFORE" value="" />
-    <option name="CHANGE_AFTER" value="" />
-    <option name="USE_USER_FILTER" value="false" />
-    <option name="USER" value="" />
-  </component>
-  <component name="CodeStyleProjectProfileManger">
-    <option name="PROJECT_PROFILE" />
-    <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
-  </component>
-  <component name="CodeStyleSettingsManager">
-    <option name="PER_PROJECT_SETTINGS">
-      <value>
-        <ADDITIONAL_INDENT_OPTIONS fileType="java">
-          <option name="INDENT_SIZE" value="4" />
-          <option name="CONTINUATION_INDENT_SIZE" value="8" />
-          <option name="TAB_SIZE" value="4" />
-          <option name="USE_TAB_CHARACTER" value="false" />
-          <option name="SMART_TABS" value="false" />
-          <option name="LABEL_INDENT_SIZE" value="0" />
-          <option name="LABEL_INDENT_ABSOLUTE" value="false" />
-        </ADDITIONAL_INDENT_OPTIONS>
-        <ADDITIONAL_INDENT_OPTIONS fileType="xml">
-          <option name="INDENT_SIZE" value="4" />
-          <option name="CONTINUATION_INDENT_SIZE" value="8" />
-          <option name="TAB_SIZE" value="4" />
-          <option name="USE_TAB_CHARACTER" value="false" />
-          <option name="SMART_TABS" value="false" />
-          <option name="LABEL_INDENT_SIZE" value="0" />
-          <option name="LABEL_INDENT_ABSOLUTE" value="false" />
-        </ADDITIONAL_INDENT_OPTIONS>
-      </value>
-    </option>
-    <option name="USE_PER_PROJECT_SETTINGS" value="false" />
-  </component>
-  <component name="CompilerConfiguration">
-    <option name="DEFAULT_COMPILER" value="Javac" />
-    <option name="DEPLOY_AFTER_MAKE" value="0" />
-    <resourceExtensions>
-      <entry name=".+\.(properties|xml|html|dtd|tld)" />
-      <entry name=".+\.(gif|png|jpeg|jpg)" />
-    </resourceExtensions>
-    <wildcardResourcePatterns>
-      <entry name="?*.properties" />
-      <entry name="?*.xml" />
-      <entry name="?*.gif" />
-      <entry name="?*.png" />
-      <entry name="?*.jpeg" />
-      <entry name="?*.jpg" />
-      <entry name="?*.html" />
-      <entry name="?*.dtd" />
-      <entry name="?*.tld" />
-    </wildcardResourcePatterns>
-  </component>
-  <component name="Cvs2Configuration">
-    <option name="PRUNE_EMPTY_DIRECTORIES" value="true" />
-    <option name="MERGING_MODE" value="0" />
-    <option name="MERGE_WITH_BRANCH1_NAME" value="HEAD" />
-    <option name="MERGE_WITH_BRANCH2_NAME" value="HEAD" />
-    <option name="RESET_STICKY" value="false" />
-    <option name="CREATE_NEW_DIRECTORIES" value="true" />
-    <option name="DEFAULT_TEXT_FILE_SUBSTITUTION" value="kv" />
-    <option name="PROCESS_UNKNOWN_FILES" value="false" />
-    <option name="PROCESS_DELETED_FILES" value="false" />
-    <option name="PROCESS_IGNORED_FILES" value="false" />
-    <option name="RESERVED_EDIT" value="false" />
-    <option name="CHECKOUT_DATE_OR_REVISION_SETTINGS">
-      <value>
-        <option name="BRANCH" value="" />
-        <option name="DATE" value="" />
-        <option name="USE_BRANCH" value="false" />
-        <option name="USE_DATE" value="false" />
-      </value>
-    </option>
-    <option name="UPDATE_DATE_OR_REVISION_SETTINGS">
-      <value>
-        <option name="BRANCH" value="" />
-        <option name="DATE" value="" />
-        <option name="USE_BRANCH" value="false" />
-        <option name="USE_DATE" value="false" />
-      </value>
-    </option>
-    <option name="SHOW_CHANGES_REVISION_SETTINGS">
-      <value>
-        <option name="BRANCH" value="" />
-        <option name="DATE" value="" />
-        <option name="USE_BRANCH" value="false" />
-        <option name="USE_DATE" value="false" />
-      </value>
-    </option>
-    <option name="SHOW_OUTPUT" value="false" />
-    <option name="ADD_WATCH_INDEX" value="0" />
-    <option name="REMOVE_WATCH_INDEX" value="0" />
-    <option name="UPDATE_KEYWORD_SUBSTITUTION" />
-    <option name="MAKE_NEW_FILES_READONLY" value="false" />
-    <option name="SHOW_CORRUPTED_PROJECT_FILES" value="0" />
-    <option name="TAG_AFTER_PROJECT_COMMIT" value="false" />
-    <option name="OVERRIDE_EXISTING_TAG_FOR_PROJECT" value="true" />
-    <option name="TAG_AFTER_PROJECT_COMMIT_NAME" value="" />
-    <option name="CLEAN_COPY" value="false" />
-  </component>
-  <component name="DependenciesAnalyzeManager">
-    <option name="myForwardDirection" value="false" />
-  </component>
-  <component name="DependencyValidationManager">
-    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
-  </component>
-  <component name="EclipseCompilerSettings">
-    <option name="DEBUGGING_INFO" value="true" />
-    <option name="GENERATE_NO_WARNINGS" value="true" />
-    <option name="DEPRECATION" value="false" />
-    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
-    <option name="MAXIMUM_HEAP_SIZE" value="128" />
-  </component>
-  <component name="EclipseEmbeddedCompilerSettings">
-    <option name="DEBUGGING_INFO" value="true" />
-    <option name="GENERATE_NO_WARNINGS" value="true" />
-    <option name="DEPRECATION" value="false" />
-    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
-    <option name="MAXIMUM_HEAP_SIZE" value="128" />
-  </component>
-  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
-  <component name="EntryPointsManager">
-    <entry_points version="2.0" />
-  </component>
-  <component name="ExportToHTMLSettings">
-    <option name="PRINT_LINE_NUMBERS" value="false" />
-    <option name="OPEN_IN_BROWSER" value="false" />
-    <option name="OUTPUT_DIRECTORY" />
-  </component>
-  <component name="IdProvider" IDEtalkID="D171F99B9178C1675593DC9A76A5CC7E" />
-  <component name="InspectionProjectProfileManager">
-    <option name="PROJECT_PROFILE" value="Project Default" />
-    <option name="USE_PROJECT_PROFILE" value="true" />
-    <version value="1.0" />
-    <profiles>
-      <profile version="1.0" is_locked="false">
-        <option name="myName" value="Project Default" />
-        <option name="myLocal" value="false" />
-        <inspection_tool class="JavaDoc" enabled="false" level="WARNING" enabled_by_default="false">
-          <option name="TOP_LEVEL_CLASS_OPTIONS">
-            <value>
-              <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
-              <option name="REQUIRED_TAGS" value="" />
-            </value>
-          </option>
-          <option name="INNER_CLASS_OPTIONS">
-            <value>
-              <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
-              <option name="REQUIRED_TAGS" value="" />
-            </value>
-          </option>
-          <option name="METHOD_OPTIONS">
-            <value>
-              <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
-              <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
-            </value>
-          </option>
-          <option name="FIELD_OPTIONS">
-            <value>
-              <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
-              <option name="REQUIRED_TAGS" value="" />
-            </value>
-          </option>
-          <option name="IGNORE_DEPRECATED" value="false" />
-          <option name="IGNORE_JAVADOC_PERIOD" value="true" />
-          <option name="myAdditionalJavadocTags" value="" />
-        </inspection_tool>
-        <inspection_tool class="JavaLangImport" enabled="true" level="WARNING" enabled_by_default="true" />
-        <inspection_tool class="OnDemandImport" enabled="true" level="WARNING" enabled_by_default="true" />
-        <inspection_tool class="RedundantImport" enabled="true" level="WARNING" enabled_by_default="true" />
-        <inspection_tool class="SamePackageImport" enabled="true" level="WARNING" enabled_by_default="true" />
-        <inspection_tool class="UnusedImport" enabled="true" level="WARNING" enabled_by_default="true" />
-      </profile>
-    </profiles>
-    <list size="4">
-      <item index="0" class="java.lang.String" itemvalue="WARNING" />
-      <item index="1" class="java.lang.String" itemvalue="SERVER PROBLEM" />
-      <item index="2" class="java.lang.String" itemvalue="INFO" />
-      <item index="3" class="java.lang.String" itemvalue="ERROR" />
-    </list>
-  </component>
-  <component name="JavacSettings">
-    <option name="DEBUGGING_INFO" value="true" />
-    <option name="GENERATE_NO_WARNINGS" value="false" />
-    <option name="DEPRECATION" value="true" />
-    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
-    <option name="MAXIMUM_HEAP_SIZE" value="128" />
-  </component>
-  <component name="JavadocGenerationManager">
-    <option name="OUTPUT_DIRECTORY" />
-    <option name="OPTION_SCOPE" value="protected" />
-    <option name="OPTION_HIERARCHY" value="true" />
-    <option name="OPTION_NAVIGATOR" value="true" />
-    <option name="OPTION_INDEX" value="true" />
-    <option name="OPTION_SEPARATE_INDEX" value="true" />
-    <option name="OPTION_DOCUMENT_TAG_USE" value="false" />
-    <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
-    <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
-    <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
-    <option name="OPTION_DEPRECATED_LIST" value="true" />
-    <option name="OTHER_OPTIONS" value="" />
-    <option name="HEAP_SIZE" />
-    <option name="LOCALE" />
-    <option name="OPEN_IN_BROWSER" value="true" />
-  </component>
-  <component name="JikesSettings">
-    <option name="JIKES_PATH" value="" />
-    <option name="DEBUGGING_INFO" value="true" />
-    <option name="DEPRECATION" value="true" />
-    <option name="GENERATE_NO_WARNINGS" value="false" />
-    <option name="IS_EMACS_ERRORS_MODE" value="true" />
-    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
-  </component>
-  <component name="LogConsolePreferences">
-    <option name="FILTER_ERRORS" value="false" />
-    <option name="FILTER_WARNINGS" value="false" />
-    <option name="FILTER_INFO" value="true" />
-    <option name="CUSTOM_FILTER" />
-  </component>
-  <component name="Palette2">
-    <group name="Swing">
-      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
-      </item>
-      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
-      </item>
-      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
-      </item>
-      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
-        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
-      </item>
-      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
-        <initial-values>
-          <property name="text" value="Button" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
-        <initial-values>
-          <property name="text" value="RadioButton" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
-        <initial-values>
-          <property name="text" value="CheckBox" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
-        <initial-values>
-          <property name="text" value="Label" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
-          <preferred-size width="150" height="-1" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
-          <preferred-size width="150" height="-1" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
-          <preferred-size width="150" height="-1" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
-      </item>
-      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
-          <preferred-size width="200" height="200" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
-          <preferred-size width="200" height="200" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
-      </item>
-      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
-      </item>
-      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
-      </item>
-      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
-      </item>
-      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
-          <preferred-size width="-1" height="20" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
-      </item>
-      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
-      </item>
-    </group>
-  </component>
-  <component name="PerforceChangeBrowserSettings">
-    <option name="USE_CLIENT_FILTER" value="true" />
-    <option name="CLIENT" value="" />
-  </component>
-  <component name="ProjectDetails">
-    <option name="projectName" value="preload" />
-  </component>
-  <component name="ProjectFileVersion" converted="true" />
-  <component name="ProjectKey">
-    <option name="state" value="project:///Volumes/Android/donut/frameworks/base/tools/preload/preload.ipr" />
-  </component>
-  <component name="ProjectModuleManager">
-    <modules>
-      <module fileurl="file://$PROJECT_DIR$/preload.iml" filepath="$PROJECT_DIR$/preload.iml" />
-    </modules>
-  </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">
-    <output url="file:///tmp/preload" />
-  </component>
-  <component name="RmicSettings">
-    <option name="IS_EANABLED" value="false" />
-    <option name="DEBUGGING_INFO" value="true" />
-    <option name="GENERATE_NO_WARNINGS" value="false" />
-    <option name="GENERATE_IIOP_STUBS" value="false" />
-    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
-  </component>
-  <component name="StarteamConfiguration">
-    <option name="SERVER" value="" />
-    <option name="PORT" value="49201" />
-    <option name="USER" value="" />
-    <option name="PASSWORD" value="" />
-    <option name="PROJECT" value="" />
-    <option name="VIEW" value="" />
-    <option name="ALTERNATIVE_WORKING_PATH" value="" />
-    <option name="LOCK_ON_CHECKOUT" value="false" />
-    <option name="UNLOCK_ON_CHECKIN" value="false" />
-  </component>
-  <component name="Struts Assistant">
-    <option name="showInputs" value="true" />
-    <option name="resources">
-      <value>
-        <option name="strutsPath" />
-        <option name="strutsHelp" />
-      </value>
-    </option>
-    <option name="selectedTaglibs" />
-    <option name="selectedTaglibs" />
-    <option name="myStrutsValidationEnabled" value="true" />
-    <option name="myTilesValidationEnabled" value="true" />
-    <option name="myValidatorValidationEnabled" value="true" />
-    <option name="myReportErrorsAsWarnings" value="true" />
-  </component>
-  <component name="SvnBranchConfigurationManager">
-    <option name="mySupportsUserInfoFilter" value="true" />
-  </component>
-  <component name="SvnChangesBrowserSettings">
-    <option name="USE_AUTHOR_FIELD" value="true" />
-    <option name="AUTHOR" value="" />
-    <option name="LOCATION" value="" />
-    <option name="USE_PROJECT_SETTINGS" value="true" />
-    <option name="USE_ALTERNATE_LOCATION" value="false" />
-  </component>
-  <component name="VCS.FileViewConfiguration">
-    <option name="SELECTED_STATUSES" value="DEFAULT" />
-    <option name="SELECTED_COLUMNS" value="DEFAULT" />
-    <option name="SHOW_FILTERS" value="true" />
-    <option name="CUSTOMIZE_VIEW" value="true" />
-    <option name="SHOW_FILE_HISTORY_AS_TREE" value="true" />
-  </component>
-  <component name="VcsDirectoryMappings">
-    <mapping directory="" vcs="Perforce" />
-    <mapping directory="/Volumes/Android/donut/frameworks/base" vcs="Git" />
-  </component>
-  <component name="VssConfiguration">
-    <option name="CLIENT_PATH" value="" />
-    <option name="SRCSAFEINI_PATH" value="" />
-    <option name="USER_NAME" value="" />
-    <option name="PWD" value="" />
-    <option name="VSS_IS_INITIALIZED" value="false" />
-    <CheckoutOptions>
-      <option name="COMMENT" value="" />
-      <option name="DO_NOT_GET_LATEST_VERSION" value="false" />
-      <option name="REPLACE_WRITABLE" value="false" />
-      <option name="RECURSIVE" value="false" />
-    </CheckoutOptions>
-    <CheckinOptions>
-      <option name="COMMENT" value="" />
-      <option name="KEEP_CHECKED_OUT" value="false" />
-      <option name="RECURSIVE" value="false" />
-    </CheckinOptions>
-    <AddOptions>
-      <option name="STORE_ONLY_LATEST_VERSION" value="false" />
-      <option name="CHECK_OUT_IMMEDIATELY" value="false" />
-      <option name="FILE_TYPE" value="0" />
-    </AddOptions>
-    <UndocheckoutOptions>
-      <option name="MAKE_WRITABLE" value="false" />
-      <option name="REPLACE_LOCAL_COPY" value="0" />
-      <option name="RECURSIVE" value="false" />
-    </UndocheckoutOptions>
-    <GetOptions>
-      <option name="REPLACE_WRITABLE" value="0" />
-      <option name="MAKE_WRITABLE" value="false" />
-      <option name="ANSWER_NEGATIVELY" value="false" />
-      <option name="ANSWER_POSITIVELY" value="false" />
-      <option name="RECURSIVE" value="false" />
-      <option name="VERSION" />
-    </GetOptions>
-    <VssConfigurableExcludedFilesTag />
-  </component>
-  <component name="antWorkspaceConfiguration">
-    <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
-    <option name="FILTER_TARGETS" value="false" />
-  </component>
-  <component name="com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable" proportions="" version="1">
-    <option name="myLastEditedConfigurable" />
-  </component>
-  <component name="com.intellij.jsf.UserDefinedFacesConfigs">
-    <option name="USER_DEFINED_CONFIGS">
-      <value>
-        <list size="0" />
-      </value>
-    </option>
-  </component>
-  <component name="com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectRootMasterDetailsConfigurable" proportions="" version="1">
-    <option name="myPlainMode" value="false" />
-    <option name="myLastEditedConfigurable" />
-  </component>
-  <component name="com.intellij.profile.ui.ErrorOptionsConfigurable" proportions="" version="1">
-    <option name="myLastEditedConfigurable" />
-  </component>
-  <component name="uidesigner-configuration">
-    <option name="INSTRUMENT_CLASSES" value="true" />
-    <option name="COPY_FORMS_RUNTIME_TO_OUTPUT" value="true" />
-    <option name="DEFAULT_LAYOUT_MANAGER" value="GridLayoutManager" />
-  </component>
-</project>
-
diff --git a/tools/preload/sorttable.js b/tools/preload/sorttable.js
deleted file mode 100644
index 25bccb2..0000000
--- a/tools/preload/sorttable.js
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
-  SortTable
-  version 2
-  7th April 2007
-  Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/
-  
-  Instructions:
-  Download this file
-  Add <script src="sorttable.js"></script> to your HTML
-  Add class="sortable" to any table you'd like to make sortable
-  Click on the headers to sort
-  
-  Thanks to many, many people for contributions and suggestions.
-  Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
-  This basically means: do what you want with it.
-*/
-
- 
-var stIsIE = /*@cc_on!@*/false;
-
-sorttable = {
-  init: function() {
-    // quit if this function has already been called
-    if (arguments.callee.done) return;
-    // flag this function so we don't do the same thing twice
-    arguments.callee.done = true;
-    // kill the timer
-    if (_timer) clearInterval(_timer);
-    
-    if (!document.createElement || !document.getElementsByTagName) return;
-    
-    sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
-    
-    forEach(document.getElementsByTagName('table'), function(table) {
-      if (table.className.search(/\bsortable\b/) != -1) {
-        sorttable.makeSortable(table);
-      }
-    });
-    
-  },
-  
-  makeSortable: function(table) {
-    if (table.getElementsByTagName('thead').length == 0) {
-      // table doesn't have a tHead. Since it should have, create one and
-      // put the first table row in it.
-      the = document.createElement('thead');
-      the.appendChild(table.rows[0]);
-      table.insertBefore(the,table.firstChild);
-    }
-    // Safari doesn't support table.tHead, sigh
-    if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
-    
-    if (table.tHead.rows.length != 1) return; // can't cope with two header rows
-    
-    // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as
-    // "total" rows, for example). This is B&R, since what you're supposed
-    // to do is put them in a tfoot. So, if there are sortbottom rows,
-    // for backwards compatibility, move them to tfoot (creating it if needed).
-    sortbottomrows = [];
-    for (var i=0; i<table.rows.length; i++) {
-      if (table.rows[i].className.search(/\bsortbottom\b/) != -1) {
-        sortbottomrows[sortbottomrows.length] = table.rows[i];
-      }
-    }
-    if (sortbottomrows) {
-      if (table.tFoot == null) {
-        // table doesn't have a tfoot. Create one.
-        tfo = document.createElement('tfoot');
-        table.appendChild(tfo);
-      }
-      for (var i=0; i<sortbottomrows.length; i++) {
-        tfo.appendChild(sortbottomrows[i]);
-      }
-      delete sortbottomrows;
-    }
-    
-    // work through each column and calculate its type
-    headrow = table.tHead.rows[0].cells;
-    for (var i=0; i<headrow.length; i++) {
-      // manually override the type with a sorttable_type attribute
-      if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col
-        mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/);
-        if (mtch) { override = mtch[1]; }
-	      if (mtch && typeof sorttable["sort_"+override] == 'function') {
-	        headrow[i].sorttable_sortfunction = sorttable["sort_"+override];
-	      } else {
-	        headrow[i].sorttable_sortfunction = sorttable.guessType(table,i);
-	      }
-	      // make it clickable to sort
-	      headrow[i].sorttable_columnindex = i;
-	      headrow[i].sorttable_tbody = table.tBodies[0];
-	      dean_addEvent(headrow[i],"click", function(e) {
-
-          if (this.className.search(/\bsorttable_sorted\b/) != -1) {
-            // if we're already sorted by this column, just 
-            // reverse the table, which is quicker
-            sorttable.reverse(this.sorttable_tbody);
-            this.className = this.className.replace('sorttable_sorted',
-                                                    'sorttable_sorted_reverse');
-            this.removeChild(document.getElementById('sorttable_sortfwdind'));
-            sortrevind = document.createElement('span');
-            sortrevind.id = "sorttable_sortrevind";
-            sortrevind.innerHTML = stIsIE ? '&nbsp<font face="webdings">5</font>' : '&nbsp;&#x25B4;';
-            this.appendChild(sortrevind);
-            return;
-          }
-          if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
-            // if we're already sorted by this column in reverse, just 
-            // re-reverse the table, which is quicker
-            sorttable.reverse(this.sorttable_tbody);
-            this.className = this.className.replace('sorttable_sorted_reverse',
-                                                    'sorttable_sorted');
-            this.removeChild(document.getElementById('sorttable_sortrevind'));
-            sortfwdind = document.createElement('span');
-            sortfwdind.id = "sorttable_sortfwdind";
-            sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
-            this.appendChild(sortfwdind);
-            return;
-          }
-          
-          // remove sorttable_sorted classes
-          theadrow = this.parentNode;
-          forEach(theadrow.childNodes, function(cell) {
-            if (cell.nodeType == 1) { // an element
-              cell.className = cell.className.replace('sorttable_sorted_reverse','');
-              cell.className = cell.className.replace('sorttable_sorted','');
-            }
-          });
-          sortfwdind = document.getElementById('sorttable_sortfwdind');
-          if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); }
-          sortrevind = document.getElementById('sorttable_sortrevind');
-          if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); }
-          
-          this.className += ' sorttable_sorted';
-          sortfwdind = document.createElement('span');
-          sortfwdind.id = "sorttable_sortfwdind";
-          sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
-          this.appendChild(sortfwdind);
-
-	        // build an array to sort. This is a Schwartzian transform thing,
-	        // i.e., we "decorate" each row with the actual sort key,
-	        // sort based on the sort keys, and then put the rows back in order
-	        // which is a lot faster because you only do getInnerText once per row
-	        row_array = [];
-	        col = this.sorttable_columnindex;
-	        rows = this.sorttable_tbody.rows;
-	        for (var j=0; j<rows.length; j++) {
-	          row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]];
-	        }
-	        /* If you want a stable sort, uncomment the following line */
-	        //sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
-	        /* and comment out this one */
-	        row_array.sort(this.sorttable_sortfunction);
-	        
-	        tb = this.sorttable_tbody;
-	        for (var j=0; j<row_array.length; j++) {
-	          tb.appendChild(row_array[j][1]);
-	        }
-	        
-	        delete row_array;
-	      });
-	    }
-    }
-  },
-  
-  guessType: function(table, column) {
-    // guess the type of a column based on its first non-blank row
-    sortfn = sorttable.sort_alpha;
-    for (var i=0; i<table.tBodies[0].rows.length; i++) {
-      text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);
-      if (text != '') {
-        if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {
-          return sorttable.sort_numeric;
-        }
-        // check for a date: dd/mm/yyyy or dd/mm/yy 
-        // can have / or . or - as separator
-        // can be mm/dd as well
-        possdate = text.match(sorttable.DATE_RE)
-        if (possdate) {
-          // looks like a date
-          first = parseInt(possdate[1]);
-          second = parseInt(possdate[2]);
-          if (first > 12) {
-            // definitely dd/mm
-            return sorttable.sort_ddmm;
-          } else if (second > 12) {
-            return sorttable.sort_mmdd;
-          } else {
-            // looks like a date, but we can't tell which, so assume
-            // that it's dd/mm (English imperialism!) and keep looking
-            sortfn = sorttable.sort_ddmm;
-          }
-        }
-      }
-    }
-    return sortfn;
-  },
-  
-  getInnerText: function(node) {
-    // gets the text we want to use for sorting for a cell.
-    // strips leading and trailing whitespace.
-    // this is *not* a generic getInnerText function; it's special to sorttable.
-    // for example, you can override the cell text with a customkey attribute.
-    // it also gets .value for <input> fields.
-    
-    hasInputs = (typeof node.getElementsByTagName == 'function') &&
-                 node.getElementsByTagName('input').length;
-    
-    if (node.getAttribute("sorttable_customkey") != null) {
-      return node.getAttribute("sorttable_customkey");
-    }
-    else if (typeof node.textContent != 'undefined' && !hasInputs) {
-      return node.textContent.replace(/^\s+|\s+$/g, '');
-    }
-    else if (typeof node.innerText != 'undefined' && !hasInputs) {
-      return node.innerText.replace(/^\s+|\s+$/g, '');
-    }
-    else if (typeof node.text != 'undefined' && !hasInputs) {
-      return node.text.replace(/^\s+|\s+$/g, '');
-    }
-    else {
-      switch (node.nodeType) {
-        case 3:
-          if (node.nodeName.toLowerCase() == 'input') {
-            return node.value.replace(/^\s+|\s+$/g, '');
-          }
-        case 4:
-          return node.nodeValue.replace(/^\s+|\s+$/g, '');
-          break;
-        case 1:
-        case 11:
-          var innerText = '';
-          for (var i = 0; i < node.childNodes.length; i++) {
-            innerText += sorttable.getInnerText(node.childNodes[i]);
-          }
-          return innerText.replace(/^\s+|\s+$/g, '');
-          break;
-        default:
-          return '';
-      }
-    }
-  },
-  
-  reverse: function(tbody) {
-    // reverse the rows in a tbody
-    newrows = [];
-    for (var i=0; i<tbody.rows.length; i++) {
-      newrows[newrows.length] = tbody.rows[i];
-    }
-    for (var i=newrows.length-1; i>=0; i--) {
-       tbody.appendChild(newrows[i]);
-    }
-    delete newrows;
-  },
-  
-  /* sort functions
-     each sort function takes two parameters, a and b
-     you are comparing a[0] and b[0] */
-  sort_numeric: function(a,b) {
-    aa = parseFloat(a[0].replace(/[^0-9.-]/g,''));
-    if (isNaN(aa)) aa = 0;
-    bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); 
-    if (isNaN(bb)) bb = 0;
-    return aa-bb;
-  },
-  sort_alpha: function(a,b) {
-    if (a[0]==b[0]) return 0;
-    if (a[0]<b[0]) return -1;
-    return 1;
-  },
-  sort_ddmm: function(a,b) {
-    mtch = a[0].match(sorttable.DATE_RE);
-    y = mtch[3]; m = mtch[2]; d = mtch[1];
-    if (m.length == 1) m = '0'+m;
-    if (d.length == 1) d = '0'+d;
-    dt1 = y+m+d;
-    mtch = b[0].match(sorttable.DATE_RE);
-    y = mtch[3]; m = mtch[2]; d = mtch[1];
-    if (m.length == 1) m = '0'+m;
-    if (d.length == 1) d = '0'+d;
-    dt2 = y+m+d;
-    if (dt1==dt2) return 0;
-    if (dt1<dt2) return -1;
-    return 1;
-  },
-  sort_mmdd: function(a,b) {
-    mtch = a[0].match(sorttable.DATE_RE);
-    y = mtch[3]; d = mtch[2]; m = mtch[1];
-    if (m.length == 1) m = '0'+m;
-    if (d.length == 1) d = '0'+d;
-    dt1 = y+m+d;
-    mtch = b[0].match(sorttable.DATE_RE);
-    y = mtch[3]; d = mtch[2]; m = mtch[1];
-    if (m.length == 1) m = '0'+m;
-    if (d.length == 1) d = '0'+d;
-    dt2 = y+m+d;
-    if (dt1==dt2) return 0;
-    if (dt1<dt2) return -1;
-    return 1;
-  },
-  
-  shaker_sort: function(list, comp_func) {
-    // A stable sort function to allow multi-level sorting of data
-    // see: http://en.wikipedia.org/wiki/Cocktail_sort
-    // thanks to Joseph Nahmias
-    var b = 0;
-    var t = list.length - 1;
-    var swap = true;
-
-    while(swap) {
-        swap = false;
-        for(var i = b; i < t; ++i) {
-            if ( comp_func(list[i], list[i+1]) > 0 ) {
-                var q = list[i]; list[i] = list[i+1]; list[i+1] = q;
-                swap = true;
-            }
-        } // for
-        t--;
-
-        if (!swap) break;
-
-        for(var i = t; i > b; --i) {
-            if ( comp_func(list[i], list[i-1]) < 0 ) {
-                var q = list[i]; list[i] = list[i-1]; list[i-1] = q;
-                swap = true;
-            }
-        } // for
-        b++;
-
-    } // while(swap)
-  }  
-}
-
-/* ******************************************************************
-   Supporting functions: bundled here to avoid depending on a library
-   ****************************************************************** */
-
-// Dean Edwards/Matthias Miller/John Resig
-
-/* for Mozilla/Opera9 */
-if (document.addEventListener) {
-    document.addEventListener("DOMContentLoaded", sorttable.init, false);
-}
-
-/* for Internet Explorer */
-/*@cc_on @*/
-/*@if (@_win32)
-    document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
-    var script = document.getElementById("__ie_onload");
-    script.onreadystatechange = function() {
-        if (this.readyState == "complete") {
-            sorttable.init(); // call the onload handler
-        }
-    };
-/*@end @*/
-
-/* for Safari */
-if (/WebKit/i.test(navigator.userAgent)) { // sniff
-    var _timer = setInterval(function() {
-        if (/loaded|complete/.test(document.readyState)) {
-            sorttable.init(); // call the onload handler
-        }
-    }, 10);
-}
-
-/* for other browsers */
-window.onload = sorttable.init;
-
-// written by Dean Edwards, 2005
-// with input from Tino Zijdel, Matthias Miller, Diego Perini
-
-// http://dean.edwards.name/weblog/2005/10/add-event/
-
-function dean_addEvent(element, type, handler) {
-	if (element.addEventListener) {
-		element.addEventListener(type, handler, false);
-	} else {
-		// assign each event handler a unique ID
-		if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++;
-		// create a hash table of event types for the element
-		if (!element.events) element.events = {};
-		// create a hash table of event handlers for each element/event pair
-		var handlers = element.events[type];
-		if (!handlers) {
-			handlers = element.events[type] = {};
-			// store the existing event handler (if there is one)
-			if (element["on" + type]) {
-				handlers[0] = element["on" + type];
-			}
-		}
-		// store the event handler in the hash table
-		handlers[handler.$$guid] = handler;
-		// assign a global event handler to do all the work
-		element["on" + type] = handleEvent;
-	}
-};
-// a counter used to create unique IDs
-dean_addEvent.guid = 1;
-
-function removeEvent(element, type, handler) {
-	if (element.removeEventListener) {
-		element.removeEventListener(type, handler, false);
-	} else {
-		// delete the event handler from the hash table
-		if (element.events && element.events[type]) {
-			delete element.events[type][handler.$$guid];
-		}
-	}
-};
-
-function handleEvent(event) {
-	var returnValue = true;
-	// grab the event object (IE uses a global event object)
-	event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
-	// get a reference to the hash table of event handlers
-	var handlers = this.events[event.type];
-	// execute each event handler
-	for (var i in handlers) {
-		this.$$handleEvent = handlers[i];
-		if (this.$$handleEvent(event) === false) {
-			returnValue = false;
-		}
-	}
-	return returnValue;
-};
-
-function fixEvent(event) {
-	// add W3C standard event methods
-	event.preventDefault = fixEvent.preventDefault;
-	event.stopPropagation = fixEvent.stopPropagation;
-	return event;
-};
-fixEvent.preventDefault = function() {
-	this.returnValue = false;
-};
-fixEvent.stopPropagation = function() {
-  this.cancelBubble = true;
-}
-
-// Dean's forEach: http://dean.edwards.name/base/forEach.js
-/*
-	forEach, version 1.0
-	Copyright 2006, Dean Edwards
-	License: http://www.opensource.org/licenses/mit-license.php
-*/
-
-// array-like enumeration
-if (!Array.forEach) { // mozilla already supports this
-	Array.forEach = function(array, block, context) {
-		for (var i = 0; i < array.length; i++) {
-			block.call(context, array[i], i, array);
-		}
-	};
-}
-
-// generic enumeration
-Function.prototype.forEach = function(object, block, context) {
-	for (var key in object) {
-		if (typeof this.prototype[key] == "undefined") {
-			block.call(context, object[key], key, object);
-		}
-	}
-};
-
-// character enumeration
-String.forEach = function(string, block, context) {
-	Array.forEach(string.split(""), function(chr, index) {
-		block.call(context, chr, index, string);
-	});
-};
-
-// globally resolve forEach enumeration
-var forEach = function(object, block, context) {
-	if (object) {
-		var resolve = Object; // default
-		if (object instanceof Function) {
-			// functions have a "length" property
-			resolve = Function;
-		} else if (object.forEach instanceof Function) {
-			// the object implements a custom forEach method so use that
-			object.forEach(block, context);
-			return;
-		} else if (typeof object == "string") {
-			// the object is a string
-			resolve = String;
-		} else if (typeof object.length == "number") {
-			// the object is array-like
-			resolve = Array;
-		}
-		resolve.forEach(object, block, context);
-	}
-};
-
diff --git a/tools/validatekeymaps/Android.mk b/tools/validatekeymaps/Android.mk
deleted file mode 100644
index 9af721d..0000000
--- a/tools/validatekeymaps/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright 2010 The Android Open Source Project
-#
-# Keymap validation tool.
-#
-
-# This tool is prebuilt if we're doing an app-only build.
-ifeq ($(TARGET_BUILD_APPS),)
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	Main.cpp
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_STATIC_LIBRARIES := \
-	libinput \
-	libutils \
-	libcutils \
-	liblog
-
-ifeq ($(HOST_OS),linux)
-LOCAL_LDLIBS += -ldl -lpthread
-endif
-
-LOCAL_MODULE := validatekeymaps
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_EXECUTABLE)
-
-endif # TARGET_BUILD_APPS
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp
deleted file mode 100644
index 5b45c55..0000000
--- a/tools/validatekeymaps/Main.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <input/KeyCharacterMap.h>
-#include <input/KeyLayoutMap.h>
-#include <input/VirtualKeyMap.h>
-#include <utils/PropertyMap.h>
-#include <utils/String8.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-using namespace android;
-
-static const char* gProgName = "validatekeymaps";
-
-enum FileType {
-    FILETYPE_UNKNOWN,
-    FILETYPE_KEYLAYOUT,
-    FILETYPE_KEYCHARACTERMAP,
-    FILETYPE_VIRTUALKEYDEFINITION,
-    FILETYPE_INPUTDEVICECONFIGURATION,
-};
-
-
-static void usage() {
-    fprintf(stderr, "Keymap Validation Tool\n\n");
-    fprintf(stderr, "Usage:\n");
-    fprintf(stderr,
-        " %s [*.kl] [*.kcm] [*.idc] [virtualkeys.*] [...]\n"
-        "   Validates the specified key layouts, key character maps, \n"
-        "   input device configurations, or virtual key definitions.\n\n",
-        gProgName);
-}
-
-static FileType getFileType(const char* filename) {
-    const char *extension = strrchr(filename, '.');
-    if (extension) {
-        if (strcmp(extension, ".kl") == 0) {
-            return FILETYPE_KEYLAYOUT;
-        }
-        if (strcmp(extension, ".kcm") == 0) {
-            return FILETYPE_KEYCHARACTERMAP;
-        }
-        if (strcmp(extension, ".idc") == 0) {
-            return FILETYPE_INPUTDEVICECONFIGURATION;
-        }
-    }
-
-    if (strstr(filename, "virtualkeys.")) {
-        return FILETYPE_VIRTUALKEYDEFINITION;
-    }
-
-    return FILETYPE_UNKNOWN;
-}
-
-static bool validateFile(const char* filename) {
-    fprintf(stdout, "Validating file '%s'...\n", filename);
-
-    FileType fileType = getFileType(filename);
-    switch (fileType) {
-    case FILETYPE_UNKNOWN:
-        fprintf(stderr, "Supported file types: *.kl, *.kcm, virtualkeys.*\n\n");
-        return false;
-
-    case FILETYPE_KEYLAYOUT: {
-        sp<KeyLayoutMap> map;
-        status_t status = KeyLayoutMap::load(String8(filename), &map);
-        if (status) {
-            fprintf(stderr, "Error %d parsing key layout file.\n\n", status);
-            return false;
-        }
-        break;
-    }
-
-    case FILETYPE_KEYCHARACTERMAP: {
-        sp<KeyCharacterMap> map;
-        status_t status = KeyCharacterMap::load(String8(filename),
-                KeyCharacterMap::FORMAT_ANY, &map);
-        if (status) {
-            fprintf(stderr, "Error %d parsing key character map file.\n\n", status);
-            return false;
-        }
-        break;
-    }
-
-    case FILETYPE_INPUTDEVICECONFIGURATION: {
-        PropertyMap* map;
-        status_t status = PropertyMap::load(String8(filename), &map);
-        if (status) {
-            fprintf(stderr, "Error %d parsing input device configuration file.\n\n", status);
-            return false;
-        }
-        delete map;
-        break;
-    }
-
-    case FILETYPE_VIRTUALKEYDEFINITION: {
-        VirtualKeyMap* map;
-        status_t status = VirtualKeyMap::load(String8(filename), &map);
-        if (status) {
-            fprintf(stderr, "Error %d parsing virtual key definition file.\n\n", status);
-            return false;
-        }
-        delete map;
-        break;
-    }
-    }
-
-    fputs("No errors.\n\n", stdout);
-    return true;
-}
-
-int main(int argc, const char** argv) {
-    if (argc < 2) {
-        usage();
-        return 1;
-    }
-
-    int result = 0;
-    for (int i = 1; i < argc; i++) {
-        if (!validateFile(argv[i])) {
-            result = 1;
-        }
-    }
-
-    if (result) {
-        fputs("Failed!\n", stderr);
-    } else {
-        fputs("Success.\n", stdout);
-    }
-    return result;
-}
diff --git a/tools/velocityplot/velocityplot.py b/tools/velocityplot/velocityplot.py
deleted file mode 100755
index 421bed4..0000000
--- a/tools/velocityplot/velocityplot.py
+++ /dev/null
@@ -1,289 +0,0 @@
-#!/usr/bin/env python2.6
-#
-# 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.
-#
-
-#
-# Plots debug log output from VelocityTracker.
-# Enable DEBUG_VELOCITY to print the output.
-#
-# This code supports side-by-side comparison of two algorithms.
-# The old algorithm should be modified to emit debug log messages containing
-# the word "OLD".
-#
-
-import numpy as np
-import matplotlib.pyplot as plot
-import subprocess
-import re
-import fcntl
-import os
-import errno
-import bisect
-from datetime import datetime, timedelta
-
-# Parameters.
-timespan = 15 # seconds total span shown
-scrolljump = 5 # seconds jump when scrolling
-timeticks = 1 # seconds between each time tick
-
-# Non-blocking stream wrapper.
-class NonBlockingStream:
-  def __init__(self, stream):
-    fcntl.fcntl(stream, fcntl.F_SETFL, os.O_NONBLOCK)
-    self.stream = stream
-    self.buffer = ''
-    self.pos = 0
-
-  def readline(self):
-    while True:
-      index = self.buffer.find('\n', self.pos)
-      if index != -1:
-        result = self.buffer[self.pos:index]
-        self.pos = index + 1
-        return result
-
-      self.buffer = self.buffer[self.pos:]
-      self.pos = 0
-      try:
-        chunk = os.read(self.stream.fileno(), 4096)
-      except OSError, e:
-        if e.errno == errno.EAGAIN:
-          return None
-        raise e
-      if len(chunk) == 0:
-        if len(self.buffer) == 0:
-          raise(EOFError)
-        else:
-          result = self.buffer
-          self.buffer = ''
-          self.pos = 0
-          return result
-      self.buffer += chunk
-
-# Plotter
-class Plotter:
-  def __init__(self, adbout):
-    self.adbout = adbout
-
-    self.fig = plot.figure(1)
-    self.fig.suptitle('Velocity Tracker', fontsize=12)
-    self.fig.set_dpi(96)
-    self.fig.set_size_inches(16, 12, forward=True)
-
-    self.velocity_x = self._make_timeseries()
-    self.velocity_y = self._make_timeseries()
-    self.velocity_magnitude = self._make_timeseries()
-    self.velocity_axes = self._add_timeseries_axes(
-        1, 'Velocity', 'px/s', [-5000, 5000],
-        yticks=range(-5000, 5000, 1000))
-    self.velocity_line_x = self._add_timeseries_line(
-        self.velocity_axes, 'vx', 'red')
-    self.velocity_line_y = self._add_timeseries_line(
-        self.velocity_axes, 'vy', 'green')
-    self.velocity_line_magnitude = self._add_timeseries_line(
-        self.velocity_axes, 'magnitude', 'blue')
-    self._add_timeseries_legend(self.velocity_axes)
-
-    shared_axis = self.velocity_axes
-
-    self.old_velocity_x = self._make_timeseries()
-    self.old_velocity_y = self._make_timeseries()
-    self.old_velocity_magnitude = self._make_timeseries()
-    self.old_velocity_axes = self._add_timeseries_axes(
-        2, 'Old Algorithm Velocity', 'px/s', [-5000, 5000],
-        sharex=shared_axis,
-        yticks=range(-5000, 5000, 1000))
-    self.old_velocity_line_x = self._add_timeseries_line(
-        self.old_velocity_axes, 'vx', 'red')
-    self.old_velocity_line_y = self._add_timeseries_line(
-        self.old_velocity_axes, 'vy', 'green')
-    self.old_velocity_line_magnitude = self._add_timeseries_line(
-        self.old_velocity_axes, 'magnitude', 'blue')
-    self._add_timeseries_legend(self.old_velocity_axes)
-
-    self.timer = self.fig.canvas.new_timer(interval=100)
-    self.timer.add_callback(lambda: self.update())
-    self.timer.start()
-
-    self.timebase = None
-    self._reset_parse_state()
-
-  # Initialize a time series.
-  def _make_timeseries(self):
-    return [[], []]
-
-  # Add a subplot to the figure for a time series.
-  def _add_timeseries_axes(self, index, title, ylabel, ylim, yticks, sharex=None):
-    num_graphs = 2
-    height = 0.9 / num_graphs
-    top = 0.95 - height * index
-    axes = self.fig.add_axes([0.1, top, 0.8, height],
-        xscale='linear',
-        xlim=[0, timespan],
-        ylabel=ylabel,
-        yscale='linear',
-        ylim=ylim,
-        sharex=sharex)
-    axes.text(0.02, 0.02, title, transform=axes.transAxes, fontsize=10, fontweight='bold')
-    axes.set_xlabel('time (s)', fontsize=10, fontweight='bold')
-    axes.set_ylabel(ylabel, fontsize=10, fontweight='bold')
-    axes.set_xticks(range(0, timespan + 1, timeticks))
-    axes.set_yticks(yticks)
-    axes.grid(True)
-
-    for label in axes.get_xticklabels():
-      label.set_fontsize(9)
-    for label in axes.get_yticklabels():
-      label.set_fontsize(9)
-
-    return axes
-
-  # Add a line to the axes for a time series.
-  def _add_timeseries_line(self, axes, label, color, linewidth=1):
-    return axes.plot([], label=label, color=color, linewidth=linewidth)[0]
-
-  # Add a legend to a time series.
-  def _add_timeseries_legend(self, axes):
-    axes.legend(
-        loc='upper left',
-        bbox_to_anchor=(1.01, 1),
-        borderpad=0.1,
-        borderaxespad=0.1,
-        prop={'size': 10})
-
-  # Resets the parse state.
-  def _reset_parse_state(self):
-    self.parse_velocity_x = None
-    self.parse_velocity_y = None
-    self.parse_velocity_magnitude = None
-    self.parse_old_velocity_x = None
-    self.parse_old_velocity_y = None
-    self.parse_old_velocity_magnitude = None
-
-  # Update samples.
-  def update(self):
-    timeindex = 0
-    while True:
-      try:
-        line = self.adbout.readline()
-      except EOFError:
-        plot.close()
-        return
-      if line is None:
-        break
-      print line
-
-      try:
-        timestamp = self._parse_timestamp(line)
-      except ValueError, e:
-        continue
-      if self.timebase is None:
-        self.timebase = timestamp
-      delta = timestamp - self.timebase
-      timeindex = delta.seconds + delta.microseconds * 0.000001
-
-      if line.find(': position') != -1:
-        self.parse_velocity_x = self._get_following_number(line, 'vx=')
-        self.parse_velocity_y = self._get_following_number(line, 'vy=')
-        self.parse_velocity_magnitude = self._get_following_number(line, 'speed=')
-        self._append(self.velocity_x, timeindex, self.parse_velocity_x)
-        self._append(self.velocity_y, timeindex, self.parse_velocity_y)
-        self._append(self.velocity_magnitude, timeindex, self.parse_velocity_magnitude)
-
-      if line.find(': OLD') != -1:
-        self.parse_old_velocity_x = self._get_following_number(line, 'vx=')
-        self.parse_old_velocity_y = self._get_following_number(line, 'vy=')
-        self.parse_old_velocity_magnitude = self._get_following_number(line, 'speed=')
-        self._append(self.old_velocity_x, timeindex, self.parse_old_velocity_x)
-        self._append(self.old_velocity_y, timeindex, self.parse_old_velocity_y)
-        self._append(self.old_velocity_magnitude, timeindex, self.parse_old_velocity_magnitude)
-
-    # Scroll the plots.
-    if timeindex > timespan:
-      bottom = int(timeindex) - timespan + scrolljump
-      self.timebase += timedelta(seconds=bottom)
-      self._scroll(self.velocity_x, bottom)
-      self._scroll(self.velocity_y, bottom)
-      self._scroll(self.velocity_magnitude, bottom)
-      self._scroll(self.old_velocity_x, bottom)
-      self._scroll(self.old_velocity_y, bottom)
-      self._scroll(self.old_velocity_magnitude, bottom)
-
-    # Redraw the plots.
-    self.velocity_line_x.set_data(self.velocity_x)
-    self.velocity_line_y.set_data(self.velocity_y)
-    self.velocity_line_magnitude.set_data(self.velocity_magnitude)
-    self.old_velocity_line_x.set_data(self.old_velocity_x)
-    self.old_velocity_line_y.set_data(self.old_velocity_y)
-    self.old_velocity_line_magnitude.set_data(self.old_velocity_magnitude)
-
-    self.fig.canvas.draw_idle()
-
-  # Scroll a time series.
-  def _scroll(self, timeseries, bottom):
-    bottom_index = bisect.bisect_left(timeseries[0], bottom)
-    del timeseries[0][:bottom_index]
-    del timeseries[1][:bottom_index]
-    for i, timeindex in enumerate(timeseries[0]):
-      timeseries[0][i] = timeindex - bottom
-
-  # Extract a word following the specified prefix.
-  def _get_following_word(self, line, prefix):
-    prefix_index = line.find(prefix)
-    if prefix_index == -1:
-      return None
-    start_index = prefix_index + len(prefix)
-    delim_index = line.find(',', start_index)
-    if delim_index == -1:
-      return line[start_index:]
-    else:
-      return line[start_index:delim_index]
-
-  # Extract a number following the specified prefix.
-  def _get_following_number(self, line, prefix):
-    word = self._get_following_word(line, prefix)
-    if word is None:
-      return None
-    return float(word)
-
-  # Add a value to a time series.
-  def _append(self, timeseries, timeindex, number):
-    timeseries[0].append(timeindex)
-    timeseries[1].append(number)
-
-  # Parse the logcat timestamp.
-  # Timestamp has the form '01-21 20:42:42.930'
-  def _parse_timestamp(self, line):
-    return datetime.strptime(line[0:18], '%m-%d %H:%M:%S.%f')
-
-# Notice
-print "Velocity Tracker plotting tool"
-print "-----------------------------------------\n"
-print "Please enable debug logging and recompile the code."
-
-# Start adb.
-print "Starting adb logcat.\n"
-
-adb = subprocess.Popen(['adb', 'logcat', '-s', '-v', 'time', 'Input:*', 'VelocityTracker:*'],
-    stdout=subprocess.PIPE)
-adbout = NonBlockingStream(adb.stdout)
-
-# Prepare plotter.
-plotter = Plotter(adbout)
-plotter.update()
-
-# Main loop.
-plot.show()
diff --git a/wifi/java/android/net/wifi/BatchedScanResult.java b/wifi/java/android/net/wifi/BatchedScanResult.java
index eb4e0276..7598b92 100644
--- a/wifi/java/android/net/wifi/BatchedScanResult.java
+++ b/wifi/java/android/net/wifi/BatchedScanResult.java
@@ -20,7 +20,6 @@
 import android.os.Parcel;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 
 /**
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 149bda6..4a6b1ff 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -111,8 +111,6 @@
 
     String getConfigFile();
 
-    void captivePortalCheckComplete();
-
     void enableTdls(String remoteIPAddress, boolean enable);
 
     void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable);
diff --git a/wifi/java/android/net/wifi/WifiApConfigStore.java b/wifi/java/android/net/wifi/WifiApConfigStore.java
index 0531ca3..e675ad4 100644
--- a/wifi/java/android/net/wifi/WifiApConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiApConfigStore.java
@@ -36,7 +36,6 @@
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.net.InetAddress;
 import java.util.UUID;
 
 /**
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index a6ae215..e45c2e7 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -30,12 +30,15 @@
 import android.net.wifi.WifiConfiguration.Status;
 import android.net.wifi.NetworkUpdateResult;
 import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
+
 import android.os.Environment;
 import android.os.FileObserver;
-import android.os.Message;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.Process;
 import android.os.UserHandle;
+import android.security.Credentials;
+import android.security.KeyChain;
 import android.security.KeyStore;
 import android.text.TextUtils;
 import android.util.LocalLog;
@@ -56,15 +59,14 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.security.PublicKey;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
 import java.util.ArrayList;
 import java.util.BitSet;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * This class provides the API to manage configured
@@ -155,6 +157,61 @@
     private static final String EXCLUSION_LIST_KEY = "exclusionList";
     private static final String EOS = "eos";
 
+
+    /* Enterprise configuration keys */
+    /**
+     * In old configurations, the "private_key" field was used. However, newer
+     * configurations use the key_id field with the engine_id set to "keystore".
+     * If this field is found in the configuration, the migration code is
+     * triggered.
+     */
+    public static final String OLD_PRIVATE_KEY_NAME = "private_key";
+
+    /**
+     * String representing the keystore OpenSSL ENGINE's ID.
+     */
+    public static final String ENGINE_ID_KEYSTORE = "keystore";
+
+    /**
+     * String representing the keystore URI used for wpa_supplicant.
+     */
+    public static final String KEYSTORE_URI = "keystore://";
+
+    /**
+     * String to set the engine value to when it should be enabled.
+     */
+    public static final String ENGINE_ENABLE = "1";
+
+    /**
+     * String to set the engine value to when it should be disabled.
+     */
+    public static final String ENGINE_DISABLE = "0";
+
+    public static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE;
+    public static final String CLIENT_CERT_PREFIX = KEYSTORE_URI + Credentials.USER_CERTIFICATE;
+    public static final String EAP_KEY             = "eap";
+    public static final String PHASE2_KEY          = "phase2";
+    public static final String IDENTITY_KEY        = "identity";
+    public static final String ANON_IDENTITY_KEY   = "anonymous_identity";
+    public static final String PASSWORD_KEY        = "password";
+    public static final String CLIENT_CERT_KEY     = "client_cert";
+    public static final String CA_CERT_KEY         = "ca_cert";
+    public static final String SUBJECT_MATCH_KEY   = "subject_match";
+    public static final String ENGINE_KEY          = "engine";
+    public static final String ENGINE_ID_KEY       = "engine_id";
+    public static final String PRIVATE_KEY_ID_KEY  = "key_id";
+    public static final String OPP_KEY_CACHING     = "proactive_key_caching";
+
+    /** This represents an empty value of an enterprise field.
+     * NULL is used at wpa_supplicant to indicate an empty value
+     */
+    static final String EMPTY_VALUE = "NULL";
+
+    /** Internal use only */
+    private static final String[] ENTERPRISE_CONFIG_SUPPLICANT_KEYS = new String[] { EAP_KEY,
+            PHASE2_KEY, IDENTITY_KEY, ANON_IDENTITY_KEY, PASSWORD_KEY, CLIENT_CERT_KEY,
+            CA_CERT_KEY, SUBJECT_MATCH_KEY, ENGINE_KEY, ENGINE_ID_KEY, PRIVATE_KEY_ID_KEY };
+
     private final LocalLog mLocalLog;
     private final WpaConfigFileObserver mFileObserver;
 
@@ -390,7 +447,7 @@
         if (config != null) {
             // Remove any associated keys
             if (config.enterpriseConfig != null) {
-                config.enterpriseConfig.removeKeys(mKeyStore);
+                removeKeys(config.enterpriseConfig);
             }
             mConfiguredNetworks.remove(netId);
             mNetworkIds.remove(configKey(config));
@@ -754,7 +811,7 @@
             if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP)
                     && config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
 
-                if (config.enterpriseConfig.needsSoftwareBackedKeyStore()) {
+                if (needsSoftwareBackedKeyStore(config.enterpriseConfig)) {
                     return true;
                 }
             }
@@ -1239,7 +1296,7 @@
 
                 WifiEnterpriseConfig enterpriseConfig = config.enterpriseConfig;
 
-                if (enterpriseConfig.needsKeyStore()) {
+                if (needsKeyStore(enterpriseConfig)) {
                     /**
                      * Keyguard settings may eventually be controlled by device policy.
                      * We check here if keystore is unlocked before installing
@@ -1259,7 +1316,7 @@
                         WifiConfiguration currentConfig = mConfiguredNetworks.get(netId);
                         String keyId = config.getKeyIdForCredentials(currentConfig);
 
-                        if (!enterpriseConfig.installKeys(mKeyStore, keyId)) {
+                        if (!installKeys(enterpriseConfig, keyId)) {
                             loge(config.SSID + ": failed to install keys");
                             break setVariables;
                         }
@@ -1276,7 +1333,7 @@
                                     netId,
                                     key,
                                     value)) {
-                            enterpriseConfig.removeKeys(mKeyStore);
+                            removeKeys(enterpriseConfig);
                             loge(config.SSID + ": failed to set " + key +
                                     ": " + value);
                             break setVariables;
@@ -1589,21 +1646,21 @@
             config.enterpriseConfig = new WifiEnterpriseConfig();
         }
         HashMap<String, String> enterpriseFields = config.enterpriseConfig.getFields();
-        for (String key : WifiEnterpriseConfig.getSupplicantKeys()) {
+        for (String key : ENTERPRISE_CONFIG_SUPPLICANT_KEYS) {
             value = mWifiNative.getNetworkVariable(netId, key);
             if (!TextUtils.isEmpty(value)) {
                 enterpriseFields.put(key, removeDoubleQuotes(value));
             } else {
-                enterpriseFields.put(key, WifiEnterpriseConfig.EMPTY_VALUE);
+                enterpriseFields.put(key, EMPTY_VALUE);
             }
         }
 
-        if (config.enterpriseConfig.migrateOldEapTlsNative(mWifiNative, netId)) {
+        if (migrateOldEapTlsNative(config.enterpriseConfig, netId)) {
             saveConfig();
         }
 
-        config.enterpriseConfig.migrateCerts(mKeyStore);
-        config.enterpriseConfig.initializeSoftwareKeystoreFlag(mKeyStore);
+        migrateCerts(config.enterpriseConfig);
+        // initializeSoftwareKeystoreFlag(config.enterpriseConfig, mKeyStore);
     }
 
     private String removeDoubleQuotes(String string) {
@@ -1725,4 +1782,241 @@
         }
     }
 
+    // Certificate and privake key management for EnterpriseConfig
+    boolean needsKeyStore(WifiEnterpriseConfig config) {
+        // Has no keys to be installed
+        if (config.getClientCertificate() == null && config.getCaCertificate() == null)
+            return false;
+        return true;
+    }
+
+    static boolean isHardwareBackedKey(PrivateKey key) {
+        return KeyChain.isBoundKeyAlgorithm(key.getAlgorithm());
+    }
+
+    static boolean hasHardwareBackedKey(Certificate certificate) {
+        return KeyChain.isBoundKeyAlgorithm(certificate.getPublicKey().getAlgorithm());
+    }
+
+    boolean needsSoftwareBackedKeyStore(WifiEnterpriseConfig config) {
+        String client = config.getClientCertificateAlias();
+        if (!TextUtils.isEmpty(client)) {
+            // a valid client certificate is configured
+
+            // BUGBUG: keyStore.get() never returns certBytes; because it is not
+            // taking WIFI_UID as a parameter. It always looks for certificate
+            // with SYSTEM_UID, and never finds any Wifi certificates. Assuming that
+            // all certificates need software keystore until we get the get() API
+            // fixed.
+
+            return true;
+        }
+
+        /*
+        try {
+
+            if (DBG) Slog.d(TAG, "Loading client certificate " + Credentials
+                    .USER_CERTIFICATE + client);
+
+            CertificateFactory factory = CertificateFactory.getInstance("X.509");
+            if (factory == null) {
+                Slog.e(TAG, "Error getting certificate factory");
+                return;
+            }
+
+            byte[] certBytes = keyStore.get(Credentials.USER_CERTIFICATE + client);
+            if (certBytes != null) {
+                Certificate cert = (X509Certificate) factory.generateCertificate(
+                        new ByteArrayInputStream(certBytes));
+
+                if (cert != null) {
+                    mNeedsSoftwareKeystore = hasHardwareBackedKey(cert);
+
+                    if (DBG) Slog.d(TAG, "Loaded client certificate " + Credentials
+                            .USER_CERTIFICATE + client);
+                    if (DBG) Slog.d(TAG, "It " + (mNeedsSoftwareKeystore ? "needs" :
+                            "does not need" ) + " software key store");
+                } else {
+                    Slog.d(TAG, "could not generate certificate");
+                }
+            } else {
+                Slog.e(TAG, "Could not load client certificate " + Credentials
+                        .USER_CERTIFICATE + client);
+                mNeedsSoftwareKeystore = true;
+            }
+
+        } catch(CertificateException e) {
+            Slog.e(TAG, "Could not read certificates");
+            mCaCert = null;
+            mClientCertificate = null;
+        }
+        */
+
+        return false;
+    }
+
+    boolean installKeys(WifiEnterpriseConfig config, String name) {
+        boolean ret = true;
+        String privKeyName = Credentials.USER_PRIVATE_KEY + name;
+        String userCertName = Credentials.USER_CERTIFICATE + name;
+        String caCertName = Credentials.CA_CERTIFICATE + name;
+        if (config.getClientCertificate() != null) {
+            byte[] privKeyData = config.getClientPrivateKey().getEncoded();
+            if (isHardwareBackedKey(config.getClientPrivateKey())) {
+                // Hardware backed key store is secure enough to store keys un-encrypted, this
+                // removes the need for user to punch a PIN to get access to these keys
+                if (DBG) Log.d(TAG, "importing keys " + name + " in hardware backed store");
+                ret = mKeyStore.importKey(privKeyName, privKeyData, android.os.Process.WIFI_UID,
+                        KeyStore.FLAG_NONE);
+            } else {
+                // Software backed key store is NOT secure enough to store keys un-encrypted.
+                // Save keys encrypted so they are protected with user's PIN. User will
+                // have to unlock phone before being able to use these keys and connect to
+                // networks.
+                if (DBG) Log.d(TAG, "importing keys " + name + " in software backed store");
+                ret = mKeyStore.importKey(privKeyName, privKeyData, Process.WIFI_UID,
+                        KeyStore.FLAG_ENCRYPTED);
+            }
+            if (ret == false) {
+                return ret;
+            }
+
+            ret = putCertInKeyStore(userCertName, config.getClientCertificate());
+            if (ret == false) {
+                // Remove private key installed
+                mKeyStore.delKey(privKeyName, Process.WIFI_UID);
+                return ret;
+            }
+        }
+
+        if (config.getCaCertificate() != null) {
+            ret = putCertInKeyStore(caCertName, config.getCaCertificate());
+            if (ret == false) {
+                if (config.getClientCertificate() != null) {
+                    // Remove client key+cert
+                    mKeyStore.delKey(privKeyName, Process.WIFI_UID);
+                    mKeyStore.delete(userCertName, Process.WIFI_UID);
+                }
+                return ret;
+            }
+        }
+
+        // Set alias names
+        if (config.getClientCertificate() != null) {
+            config.setClientCertificateAlias(name);
+            config.resetClientKeyEntry();
+        }
+
+        if (config.getCaCertificate() != null) {
+            config.setCaCertificateAlias(name);
+            config.resetCaCertificate();
+        }
+
+        return ret;
+    }
+
+    private boolean putCertInKeyStore(String name, Certificate cert) {
+        try {
+            byte[] certData = Credentials.convertToPem(cert);
+            if (DBG) Log.d(TAG, "putting certificate " + name + " in keystore");
+            return mKeyStore.put(name, certData, Process.WIFI_UID, KeyStore.FLAG_NONE);
+
+        } catch (IOException e1) {
+            return false;
+        } catch (CertificateException e2) {
+            return false;
+        }
+    }
+
+    void removeKeys(WifiEnterpriseConfig config) {
+        String client = config.getClientCertificateAlias();
+        // a valid client certificate is configured
+        if (!TextUtils.isEmpty(client)) {
+            if (DBG) Log.d(TAG, "removing client private key and user cert");
+            mKeyStore.delKey(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID);
+            mKeyStore.delete(Credentials.USER_CERTIFICATE + client, Process.WIFI_UID);
+        }
+
+        String ca = config.getCaCertificateAlias();
+        // a valid ca certificate is configured
+        if (!TextUtils.isEmpty(ca)) {
+            if (DBG) Log.d(TAG, "removing CA cert");
+            mKeyStore.delete(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID);
+        }
+    }
+
+
+    /** Migrates the old style TLS config to the new config style. This should only be used
+     * when restoring an old wpa_supplicant.conf or upgrading from a previous
+     * platform version.
+     * @return true if the config was updated
+     * @hide
+     */
+    boolean migrateOldEapTlsNative(WifiEnterpriseConfig config, int netId) {
+        String oldPrivateKey = mWifiNative.getNetworkVariable(netId, OLD_PRIVATE_KEY_NAME);
+        /*
+         * If the old configuration value is not present, then there is nothing
+         * to do.
+         */
+        if (TextUtils.isEmpty(oldPrivateKey)) {
+            return false;
+        } else {
+            // Also ignore it if it's empty quotes.
+            oldPrivateKey = removeDoubleQuotes(oldPrivateKey);
+            if (TextUtils.isEmpty(oldPrivateKey)) {
+                return false;
+            }
+        }
+
+        config.setFieldValue(ENGINE_KEY, ENGINE_ENABLE);
+        config.setFieldValue(ENGINE_ID_KEY, ENGINE_ID_KEYSTORE);
+
+        /*
+        * The old key started with the keystore:// URI prefix, but we don't
+        * need that anymore. Trim it off if it exists.
+        */
+        final String keyName;
+        if (oldPrivateKey.startsWith(KEYSTORE_URI)) {
+            keyName = new String(oldPrivateKey.substring(KEYSTORE_URI.length()));
+        } else {
+            keyName = oldPrivateKey;
+        }
+        config.setFieldValue(PRIVATE_KEY_ID_KEY, keyName);
+
+        mWifiNative.setNetworkVariable(netId, ENGINE_KEY, config.getFieldValue(ENGINE_KEY, ""));
+
+        mWifiNative.setNetworkVariable(netId, ENGINE_ID_KEY,
+                config.getFieldValue(ENGINE_ID_KEY, ""));
+
+        mWifiNative.setNetworkVariable(netId, PRIVATE_KEY_ID_KEY,
+                config.getFieldValue(PRIVATE_KEY_ID_KEY, ""));
+
+        // Remove old private_key string so we don't run this again.
+        mWifiNative.setNetworkVariable(netId, OLD_PRIVATE_KEY_NAME, EMPTY_VALUE);
+
+        return true;
+    }
+
+    /** Migrate certs from global pool to wifi UID if not already done */
+    void migrateCerts(WifiEnterpriseConfig config) {
+        String client = config.getClientCertificateAlias();
+        // a valid client certificate is configured
+        if (!TextUtils.isEmpty(client)) {
+            if (!mKeyStore.contains(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID)) {
+                mKeyStore.duplicate(Credentials.USER_PRIVATE_KEY + client, -1,
+                        Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID);
+                mKeyStore.duplicate(Credentials.USER_CERTIFICATE + client, -1,
+                        Credentials.USER_CERTIFICATE + client, Process.WIFI_UID);
+            }
+        }
+
+        String ca = config.getCaCertificateAlias();
+        // a valid ca certificate is configured
+        if (!TextUtils.isEmpty(ca)) {
+            if (!mKeyStore.contains(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID)) {
+                mKeyStore.duplicate(Credentials.CA_CERTIFICATE + ca, -1,
+                        Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID);
+            }
+        }
+    }
 }
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index c7ebecb..452d84b 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -17,19 +17,13 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Process;
 import android.security.Credentials;
-import android.security.KeyChain;
-import android.security.KeyStore;
 import android.text.TextUtils;
-import android.util.Slog;
 
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
 import java.security.KeyFactory;
 import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
-import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
@@ -44,62 +38,11 @@
  * and any associated credentials.
  */
 public class WifiEnterpriseConfig implements Parcelable {
-    private static final String TAG = "WifiEnterpriseConfig";
-    private static final boolean DBG = false;
-    /**
-     * In old configurations, the "private_key" field was used. However, newer
-     * configurations use the key_id field with the engine_id set to "keystore".
-     * If this field is found in the configuration, the migration code is
-     * triggered.
-     */
-    private static final String OLD_PRIVATE_KEY_NAME = "private_key";
-
-    /**
-     * String representing the keystore OpenSSL ENGINE's ID.
-     */
-    private static final String ENGINE_ID_KEYSTORE = "keystore";
-
-    /**
-     * String representing the keystore URI used for wpa_supplicant.
-     */
-    private static final String KEYSTORE_URI = "keystore://";
-
-    /**
-     * String to set the engine value to when it should be enabled.
-     */
-    private static final String ENGINE_ENABLE = "1";
-
-    /**
-     * String to set the engine value to when it should be disabled.
-     */
-    private static final String ENGINE_DISABLE = "0";
-
-    private static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE;
-    private static final String CLIENT_CERT_PREFIX = KEYSTORE_URI + Credentials.USER_CERTIFICATE;
-
-    private static final String EAP_KEY             = "eap";
-    private static final String PHASE2_KEY          = "phase2";
-    private static final String IDENTITY_KEY        = "identity";
-    private static final String ANON_IDENTITY_KEY   = "anonymous_identity";
-    private static final String PASSWORD_KEY        = "password";
-    private static final String CLIENT_CERT_KEY     = "client_cert";
-    private static final String CA_CERT_KEY         = "ca_cert";
-    private static final String SUBJECT_MATCH_KEY   = "subject_match";
-    private static final String ENGINE_KEY          = "engine";
-    private static final String ENGINE_ID_KEY       = "engine_id";
-    private static final String PRIVATE_KEY_ID_KEY  = "key_id";
-    private static final String OPP_KEY_CACHING     = "proactive_key_caching";
 
     private HashMap<String, String> mFields = new HashMap<String, String>();
     private X509Certificate mCaCert;
     private PrivateKey mClientPrivateKey;
     private X509Certificate mClientCertificate;
-    private boolean mNeedsSoftwareKeystore = false;
-
-    /** This represents an empty value of an enterprise field.
-     * NULL is used at wpa_supplicant to indicate an empty value
-     */
-    static final String EMPTY_VALUE = "NULL";
 
     public WifiEnterpriseConfig() {
         // Do not set defaults so that the enterprise fields that are not changed
@@ -246,7 +189,8 @@
         public static final int GTC         = 4;
         private static final String PREFIX = "auth=";
         /** @hide */
-        public static final String[] strings = {EMPTY_VALUE, "PAP", "MSCHAP", "MSCHAPV2", "GTC" };
+        public static final String[] strings = {WifiConfigStore.EMPTY_VALUE, "PAP", "MSCHAP",
+                "MSCHAPV2", "GTC" };
 
         /** Prevent initialization */
         private Phase2() {}
@@ -257,13 +201,6 @@
         return mFields;
     }
 
-    /** Internal use only */
-    static String[] getSupplicantKeys() {
-        return new String[] { EAP_KEY, PHASE2_KEY, IDENTITY_KEY, ANON_IDENTITY_KEY, PASSWORD_KEY,
-                CLIENT_CERT_KEY, CA_CERT_KEY, SUBJECT_MATCH_KEY, ENGINE_KEY, ENGINE_ID_KEY,
-                PRIVATE_KEY_ID_KEY };
-    }
-
     /**
      * Set the EAP authentication method.
      * @param  eapMethod is one {@link Eap#PEAP}, {@link Eap#TLS}, {@link Eap#TTLS} or
@@ -277,8 +214,8 @@
             case Eap.PWD:
             case Eap.TLS:
             case Eap.TTLS:
-                mFields.put(EAP_KEY, Eap.strings[eapMethod]);
-                mFields.put(OPP_KEY_CACHING, "1");
+                mFields.put(WifiConfigStore.EAP_KEY, Eap.strings[eapMethod]);
+                mFields.put(WifiConfigStore.OPP_KEY_CACHING, "1");
                 break;
             default:
                 throw new IllegalArgumentException("Unknown EAP method");
@@ -290,7 +227,7 @@
      * @return eap method configured
      */
     public int getEapMethod() {
-        String eapMethod  = mFields.get(EAP_KEY);
+        String eapMethod  = mFields.get(WifiConfigStore.EAP_KEY);
         return getStringIndex(Eap.strings, eapMethod, Eap.NONE);
     }
 
@@ -306,14 +243,14 @@
     public void setPhase2Method(int phase2Method) {
         switch (phase2Method) {
             case Phase2.NONE:
-                mFields.put(PHASE2_KEY, EMPTY_VALUE);
+                mFields.put(WifiConfigStore.PHASE2_KEY, WifiConfigStore.EMPTY_VALUE);
                 break;
             /** Valid methods */
             case Phase2.PAP:
             case Phase2.MSCHAP:
             case Phase2.MSCHAPV2:
             case Phase2.GTC:
-                mFields.put(PHASE2_KEY, convertToQuotedString(
+                mFields.put(WifiConfigStore.PHASE2_KEY, convertToQuotedString(
                         Phase2.PREFIX + Phase2.strings[phase2Method]));
                 break;
             default:
@@ -326,7 +263,7 @@
      * @return a phase 2 method defined at {@link Phase2}
      * */
     public int getPhase2Method() {
-        String phase2Method = removeDoubleQuotes(mFields.get(PHASE2_KEY));
+        String phase2Method = removeDoubleQuotes(mFields.get(WifiConfigStore.PHASE2_KEY));
         // Remove auth= prefix
         if (phase2Method.startsWith(Phase2.PREFIX)) {
             phase2Method = phase2Method.substring(Phase2.PREFIX.length());
@@ -339,7 +276,7 @@
      * @param identity
      */
     public void setIdentity(String identity) {
-        setFieldValue(IDENTITY_KEY, identity, "");
+        setFieldValue(WifiConfigStore.IDENTITY_KEY, identity, "");
     }
 
     /**
@@ -347,7 +284,7 @@
      * @return the identity
      */
     public String getIdentity() {
-        return getFieldValue(IDENTITY_KEY, "");
+        return getFieldValue(WifiConfigStore.IDENTITY_KEY, "");
     }
 
     /**
@@ -356,14 +293,14 @@
      * @param anonymousIdentity the anonymous identity
      */
     public void setAnonymousIdentity(String anonymousIdentity) {
-        setFieldValue(ANON_IDENTITY_KEY, anonymousIdentity, "");
+        setFieldValue(WifiConfigStore.ANON_IDENTITY_KEY, anonymousIdentity, "");
     }
 
     /** Get the anonymous identity
      * @return anonymous identity
      */
     public String getAnonymousIdentity() {
-        return getFieldValue(ANON_IDENTITY_KEY, "");
+        return getFieldValue(WifiConfigStore.ANON_IDENTITY_KEY, "");
     }
 
     /**
@@ -371,7 +308,7 @@
      * @param password the password
      */
     public void setPassword(String password) {
-        setFieldValue(PASSWORD_KEY, password, "");
+        setFieldValue(WifiConfigStore.PASSWORD_KEY, password, "");
     }
 
     /**
@@ -381,7 +318,7 @@
      * framework, returns "*".
      */
     public String getPassword() {
-        return getFieldValue(PASSWORD_KEY, "");
+        return getFieldValue(WifiConfigStore.PASSWORD_KEY, "");
     }
 
     /**
@@ -394,7 +331,7 @@
      * @hide
      */
     public void setCaCertificateAlias(String alias) {
-        setFieldValue(CA_CERT_KEY, alias, CA_CERT_PREFIX);
+        setFieldValue(WifiConfigStore.CA_CERT_KEY, alias, WifiConfigStore.CA_CERT_PREFIX);
     }
 
     /**
@@ -403,7 +340,7 @@
      * @hide
      */
     public String getCaCertificateAlias() {
-        return getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX);
+        return getFieldValue(WifiConfigStore.CA_CERT_KEY, WifiConfigStore.CA_CERT_PREFIX);
     }
 
     /**
@@ -431,7 +368,6 @@
 
     /**
      * Get CA certificate
-     *
      * @return X.509 CA certificate
      */
     public X509Certificate getCaCertificate() {
@@ -439,6 +375,13 @@
     }
 
     /**
+     * @hide
+     */
+    public void resetCaCertificate() {
+        mCaCert = null;
+    }
+
+    /**
      * Set Client certificate alias.
      *
      * <p> See the {@link android.security.KeyChain} for details on installing or choosing
@@ -448,15 +391,16 @@
      * @hide
      */
     public void setClientCertificateAlias(String alias) {
-        setFieldValue(CLIENT_CERT_KEY, alias, CLIENT_CERT_PREFIX);
-        setFieldValue(PRIVATE_KEY_ID_KEY, alias, Credentials.USER_PRIVATE_KEY);
+        setFieldValue(WifiConfigStore.CLIENT_CERT_KEY, alias, WifiConfigStore.CLIENT_CERT_PREFIX);
+        setFieldValue(WifiConfigStore.PRIVATE_KEY_ID_KEY, alias, Credentials.USER_PRIVATE_KEY);
         // Also, set engine parameters
         if (TextUtils.isEmpty(alias)) {
-            mFields.put(ENGINE_KEY, ENGINE_DISABLE);
-            mFields.put(ENGINE_ID_KEY, EMPTY_VALUE);
+            mFields.put(WifiConfigStore.ENGINE_KEY, WifiConfigStore.ENGINE_DISABLE);
+            mFields.put(WifiConfigStore.ENGINE_ID_KEY, WifiConfigStore.EMPTY_VALUE);
         } else {
-            mFields.put(ENGINE_KEY, ENGINE_ENABLE);
-            mFields.put(ENGINE_ID_KEY, convertToQuotedString(ENGINE_ID_KEYSTORE));
+            mFields.put(WifiConfigStore.ENGINE_KEY, WifiConfigStore.ENGINE_ENABLE);
+            mFields.put(WifiConfigStore.ENGINE_ID_KEY,
+                    convertToQuotedString(WifiConfigStore.ENGINE_ID_KEYSTORE));
         }
     }
 
@@ -466,7 +410,7 @@
      * @hide
      */
     public String getClientCertificateAlias() {
-        return getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
+        return getFieldValue(WifiConfigStore.CLIENT_CERT_KEY, WifiConfigStore.CLIENT_CERT_PREFIX);
     }
 
     /**
@@ -507,116 +451,19 @@
         return mClientCertificate;
     }
 
-    boolean needsKeyStore() {
-        // Has no keys to be installed
-        if (mClientCertificate == null && mCaCert == null) return false;
-        return true;
+    /**
+     * @hide
+     */
+    public void resetClientKeyEntry() {
+        mClientPrivateKey = null;
+        mClientCertificate = null;
     }
 
-    static boolean isHardwareBackedKey(PrivateKey key) {
-        return KeyChain.isBoundKeyAlgorithm(key.getAlgorithm());
-    }
-
-    static boolean hasHardwareBackedKey(Certificate certificate) {
-        return KeyChain.isBoundKeyAlgorithm(certificate.getPublicKey().getAlgorithm());
-    }
-
-    boolean needsSoftwareBackedKeyStore() {
-        return mNeedsSoftwareKeystore;
-    }
-
-    boolean installKeys(android.security.KeyStore keyStore, String name) {
-        boolean ret = true;
-        String privKeyName = Credentials.USER_PRIVATE_KEY + name;
-        String userCertName = Credentials.USER_CERTIFICATE + name;
-        String caCertName = Credentials.CA_CERTIFICATE + name;
-        if (mClientCertificate != null) {
-            byte[] privKeyData = mClientPrivateKey.getEncoded();
-            if (isHardwareBackedKey(mClientPrivateKey)) {
-                // Hardware backed key store is secure enough to store keys un-encrypted, this
-                // removes the need for user to punch a PIN to get access to these keys
-                if (DBG) Slog.d(TAG, "importing keys " + name + " in hardware backed " +
-                        "store");
-                ret = keyStore.importKey(privKeyName, privKeyData, Process.WIFI_UID,
-                                KeyStore.FLAG_NONE);
-            } else {
-                // Software backed key store is NOT secure enough to store keys un-encrypted.
-                // Save keys encrypted so they are protected with user's PIN. User will
-                // have to unlock phone before being able to use these keys and connect to
-                // networks.
-                if (DBG) Slog.d(TAG, "importing keys " + name + " in software backed store");
-                ret = keyStore.importKey(privKeyName, privKeyData, Process.WIFI_UID,
-                        KeyStore.FLAG_ENCRYPTED);
-                mNeedsSoftwareKeystore = true;
-            }
-            if (ret == false) {
-                return ret;
-            }
-
-            ret = putCertInKeyStore(keyStore, userCertName, mClientCertificate);
-            if (ret == false) {
-                // Remove private key installed
-                keyStore.delKey(privKeyName, Process.WIFI_UID);
-                return ret;
-            }
-        }
-
-        if (mCaCert != null) {
-            ret = putCertInKeyStore(keyStore, caCertName, mCaCert);
-            if (ret == false) {
-                if (mClientCertificate != null) {
-                    // Remove client key+cert
-                    keyStore.delKey(privKeyName, Process.WIFI_UID);
-                    keyStore.delete(userCertName, Process.WIFI_UID);
-                }
-                return ret;
-            }
-        }
-
-        // Set alias names
-        if (mClientCertificate != null) {
-            setClientCertificateAlias(name);
-            mClientPrivateKey = null;
-            mClientCertificate = null;
-        }
-
-        if (mCaCert != null) {
-            setCaCertificateAlias(name);
-            mCaCert = null;
-        }
-
-        return ret;
-    }
-
-    private boolean putCertInKeyStore(android.security.KeyStore keyStore, String name,
-            Certificate cert) {
-        try {
-            byte[] certData = Credentials.convertToPem(cert);
-            if (DBG) Slog.d(TAG, "putting certificate " + name + " in keystore");
-            return keyStore.put(name, certData, Process.WIFI_UID, KeyStore.FLAG_NONE);
-
-        } catch (IOException e1) {
-            return false;
-        } catch (CertificateException e2) {
-            return false;
-        }
-    }
-
-    void removeKeys(KeyStore keyStore) {
-        String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
-        // a valid client certificate is configured
-        if (!TextUtils.isEmpty(client)) {
-            if (DBG) Slog.d(TAG, "removing client private key and user cert");
-            keyStore.delKey(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID);
-            keyStore.delete(Credentials.USER_CERTIFICATE + client, Process.WIFI_UID);
-        }
-
-        String ca = getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX);
-        // a valid ca certificate is configured
-        if (!TextUtils.isEmpty(ca)) {
-            if (DBG) Slog.d(TAG, "removing CA cert");
-            keyStore.delete(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID);
-        }
+    /**
+     * @hide
+     */
+    public PrivateKey getClientPrivateKey() {
+        return mClientPrivateKey;
     }
 
     /**
@@ -625,7 +472,7 @@
      * @param subjectMatch substring to be matched
      */
     public void setSubjectMatch(String subjectMatch) {
-        setFieldValue(SUBJECT_MATCH_KEY, subjectMatch, "");
+        setFieldValue(WifiConfigStore.SUBJECT_MATCH_KEY, subjectMatch, "");
     }
 
     /**
@@ -633,147 +480,24 @@
      * @return the subject match string
      */
     public String getSubjectMatch() {
-        return getFieldValue(SUBJECT_MATCH_KEY, "");
+        return getFieldValue(WifiConfigStore.SUBJECT_MATCH_KEY, "");
     }
 
     /** See {@link WifiConfiguration#getKeyIdForCredentials} @hide */
     String getKeyId(WifiEnterpriseConfig current) {
-        String eap = mFields.get(EAP_KEY);
-        String phase2 = mFields.get(PHASE2_KEY);
+        String eap = mFields.get(WifiConfigStore.EAP_KEY);
+        String phase2 = mFields.get(WifiConfigStore.PHASE2_KEY);
 
         // If either eap or phase2 are not initialized, use current config details
         if (TextUtils.isEmpty((eap))) {
-            eap = current.mFields.get(EAP_KEY);
+            eap = current.mFields.get(WifiConfigStore.EAP_KEY);
         }
         if (TextUtils.isEmpty(phase2)) {
-            phase2 = current.mFields.get(PHASE2_KEY);
+            phase2 = current.mFields.get(WifiConfigStore.PHASE2_KEY);
         }
         return eap + "_" + phase2;
     }
 
-    /** Migrates the old style TLS config to the new config style. This should only be used
-     * when restoring an old wpa_supplicant.conf or upgrading from a previous
-     * platform version.
-     * @return true if the config was updated
-     * @hide
-     */
-    boolean migrateOldEapTlsNative(WifiNative wifiNative, int netId) {
-        String oldPrivateKey = wifiNative.getNetworkVariable(netId, OLD_PRIVATE_KEY_NAME);
-        /*
-         * If the old configuration value is not present, then there is nothing
-         * to do.
-         */
-        if (TextUtils.isEmpty(oldPrivateKey)) {
-            return false;
-        } else {
-            // Also ignore it if it's empty quotes.
-            oldPrivateKey = removeDoubleQuotes(oldPrivateKey);
-            if (TextUtils.isEmpty(oldPrivateKey)) {
-                return false;
-            }
-        }
-
-        mFields.put(ENGINE_KEY, ENGINE_ENABLE);
-        mFields.put(ENGINE_ID_KEY, convertToQuotedString(ENGINE_ID_KEYSTORE));
-
-        /*
-        * The old key started with the keystore:// URI prefix, but we don't
-        * need that anymore. Trim it off if it exists.
-        */
-        final String keyName;
-        if (oldPrivateKey.startsWith(KEYSTORE_URI)) {
-            keyName = new String(oldPrivateKey.substring(KEYSTORE_URI.length()));
-        } else {
-            keyName = oldPrivateKey;
-        }
-        mFields.put(PRIVATE_KEY_ID_KEY, convertToQuotedString(keyName));
-
-        wifiNative.setNetworkVariable(netId, ENGINE_KEY, mFields.get(ENGINE_KEY));
-        wifiNative.setNetworkVariable(netId, ENGINE_ID_KEY, mFields.get(ENGINE_ID_KEY));
-        wifiNative.setNetworkVariable(netId, PRIVATE_KEY_ID_KEY, mFields.get(PRIVATE_KEY_ID_KEY));
-        // Remove old private_key string so we don't run this again.
-        wifiNative.setNetworkVariable(netId, OLD_PRIVATE_KEY_NAME, EMPTY_VALUE);
-        return true;
-    }
-
-    /** Migrate certs from global pool to wifi UID if not already done */
-    void migrateCerts(android.security.KeyStore keyStore) {
-        String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
-        // a valid client certificate is configured
-        if (!TextUtils.isEmpty(client)) {
-            if (!keyStore.contains(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID)) {
-                keyStore.duplicate(Credentials.USER_PRIVATE_KEY + client, -1,
-                        Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID);
-                keyStore.duplicate(Credentials.USER_CERTIFICATE + client, -1,
-                        Credentials.USER_CERTIFICATE + client, Process.WIFI_UID);
-            }
-        }
-
-        String ca = getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX);
-        // a valid ca certificate is configured
-        if (!TextUtils.isEmpty(ca)) {
-            if (!keyStore.contains(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID)) {
-                keyStore.duplicate(Credentials.CA_CERTIFICATE + ca, -1,
-                        Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID);
-            }
-        }
-    }
-
-    void initializeSoftwareKeystoreFlag(android.security.KeyStore keyStore) {
-        String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
-        if (!TextUtils.isEmpty(client)) {
-            // a valid client certificate is configured
-
-            // BUGBUG: keyStore.get() never returns certBytes; because it is not
-            // taking WIFI_UID as a parameter. It always looks for certificate
-            // with SYSTEM_UID, and never finds any Wifi certificates. Assuming that
-            // all certificates need software keystore until we get the get() API
-            // fixed.
-
-            mNeedsSoftwareKeystore = true;
-
-            /*
-            try {
-
-                if (DBG) Slog.d(TAG, "Loading client certificate " + Credentials
-                        .USER_CERTIFICATE + client);
-
-                CertificateFactory factory = CertificateFactory.getInstance("X.509");
-                if (factory == null) {
-                    Slog.e(TAG, "Error getting certificate factory");
-                    return;
-                }
-
-                byte[] certBytes = keyStore.get(Credentials.USER_CERTIFICATE + client);
-                if (certBytes != null) {
-                    Certificate cert = (X509Certificate) factory.generateCertificate(
-                            new ByteArrayInputStream(certBytes));
-
-                    if (cert != null) {
-                        mNeedsSoftwareKeystore = hasHardwareBackedKey(cert);
-
-                        if (DBG) Slog.d(TAG, "Loaded client certificate " + Credentials
-                                .USER_CERTIFICATE + client);
-                        if (DBG) Slog.d(TAG, "It " + (mNeedsSoftwareKeystore ? "needs" :
-                                "does not need" ) + " software key store");
-                    } else {
-                        Slog.d(TAG, "could not generate certificate");
-                    }
-                } else {
-                    Slog.e(TAG, "Could not load client certificate " + Credentials
-                            .USER_CERTIFICATE + client);
-                    mNeedsSoftwareKeystore = true;
-                }
-
-            } catch(CertificateException e) {
-                Slog.e(TAG, "Could not read certificates");
-                mCaCert = null;
-                mClientCertificate = null;
-            }
-            */
-        }
-    }
-
     private String removeDoubleQuotes(String string) {
         if (TextUtils.isEmpty(string)) return "";
         int length = string.length();
@@ -806,11 +530,12 @@
      * @param key into the hash
      * @param prefix is the prefix that the value may have
      * @return value
+     * @hide
      */
-    private String getFieldValue(String key, String prefix) {
+    String getFieldValue(String key, String prefix) {
         String value = mFields.get(key);
         // Uninitialized or known to be empty after reading from supplicant
-        if (TextUtils.isEmpty(value) || EMPTY_VALUE.equals(value)) return "";
+        if (TextUtils.isEmpty(value) || WifiConfigStore.EMPTY_VALUE.equals(value)) return "";
 
         value = removeDoubleQuotes(value);
         if (value.startsWith(prefix)) {
@@ -827,12 +552,27 @@
      */
     private void setFieldValue(String key, String value, String prefix) {
         if (TextUtils.isEmpty(value)) {
-            mFields.put(key, EMPTY_VALUE);
+            mFields.put(key, WifiConfigStore.EMPTY_VALUE);
         } else {
             mFields.put(key, convertToQuotedString(prefix + value));
         }
     }
 
+
+    /** Set a value with an optional prefix at key
+     * @param key into the hash
+     * @param value to be set
+     * @param prefix an optional value to be prefixed to actual value
+     * @hide
+     */
+    public void setFieldValue(String key, String value) {
+        if (TextUtils.isEmpty(value)) {
+           mFields.put(key, WifiConfigStore.EMPTY_VALUE);
+        } else {
+            mFields.put(key, convertToQuotedString(value));
+        }
+    }
+
     @Override
     public String toString() {
         StringBuffer sb = new StringBuffer();
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 5d130c6..dea0c6c 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -62,7 +62,6 @@
     private String mBSSID;
     private WifiSsid mWifiSsid;
     private int mNetworkId;
-    private boolean mHiddenSSID;
     /** Received Signal Strength Indicator */
     private int mRssi;
 
@@ -86,7 +85,6 @@
         mSupplicantState = SupplicantState.UNINITIALIZED;
         mRssi = -9999;
         mLinkSpeed = -1;
-        mHiddenSSID = false;
     }
 
     /**
@@ -99,7 +97,6 @@
             mBSSID = source.mBSSID;
             mWifiSsid = source.mWifiSsid;
             mNetworkId = source.mNetworkId;
-            mHiddenSSID = source.mHiddenSSID;
             mRssi = source.mRssi;
             mLinkSpeed = source.mLinkSpeed;
             mIpAddress = source.mIpAddress;
@@ -110,8 +107,6 @@
 
     void setSSID(WifiSsid wifiSsid) {
         mWifiSsid = wifiSsid;
-        // network is considered not hidden by default
-        mHiddenSSID = false;
     }
 
     /**
@@ -244,12 +239,7 @@
      * SSID-specific probe request must be used for scans.
      */
     public boolean getHiddenSSID() {
-        return mHiddenSSID;
-    }
-
-    /** {@hide} */
-    public void setHiddenSSID(boolean hiddenSSID) {
-        mHiddenSSID = hiddenSSID;
+        return mWifiSsid.isHidden();
     }
 
    /**
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 3b47e63..ae1fbf7 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -35,7 +35,6 @@
 import java.net.InetAddress;
 import java.util.concurrent.CountDownLatch;
 
-import com.android.internal.R;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
 
@@ -2163,13 +2162,6 @@
         }
     }
 
-    /** @hide */
-    public void captivePortalCheckComplete() {
-        try {
-            mService.captivePortalCheckComplete();
-        } catch (RemoteException e) {}
-    }
-
     protected void finalize() throws Throwable {
         try {
             synchronized (sThreadRefLock) {
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index 6817777..a18954c 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -20,24 +20,19 @@
 import android.net.wifi.p2p.WifiP2pConfig;
 import android.net.wifi.p2p.WifiP2pDevice;
 import android.net.wifi.p2p.WifiP2pGroup;
-import android.net.wifi.p2p.WifiP2pService;
-import android.net.wifi.p2p.WifiP2pService.P2pStatus;
 import android.net.wifi.p2p.WifiP2pProvDiscEvent;
+import android.net.wifi.p2p.WifiP2pService.P2pStatus;
 import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
-import android.net.wifi.StateChangeResult;
 import android.os.Message;
 import android.util.Log;
 
-
 import com.android.internal.util.Protocol;
 import com.android.internal.util.StateMachine;
 
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
 import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Listens for events from the wpa_supplicant server, and passes them on
@@ -337,10 +332,6 @@
 
     /* Indicates assoc reject event */
     public static final int ASSOCIATION_REJECTION_EVENT          = BASE + 43;
-    /**
-     * This indicates the supplicant connection for the monitor is closed
-     */
-    private static final String MONITOR_SOCKET_CLOSED_STR = "connection closed";
 
     /**
      * This indicates a read error on the monitor socket conenction
@@ -354,56 +345,57 @@
 
     private final String mInterfaceName;
     private final WifiNative mWifiNative;
-    private final StateMachine mWifiStateMachine;
+    private final StateMachine mStateMachine;
     private boolean mMonitoring;
 
+    // This is a global counter, since it's not monitor specific. However, the existing
+    // implementation forwards all "global" control events like CTRL-EVENT-TERMINATING
+    // to the p2p0 monitor. Is that expected ? It seems a bit surprising.
+    //
+    // TODO: If the p2p0 monitor isn't registered, the behaviour is even more surprising.
+    // The event will be dispatched to all monitors, and each of them will end up incrementing
+    // it in their dispatchXXX method. If we have 5 registered monitors (say), 2 consecutive
+    // recv errors will cause us to disconnect from the supplicant (instead of the intended 10).
+    //
+    // This variable is always accessed and modified under a WifiMonitorSingleton lock.
+    private static int sRecvErrors;
+
     public WifiMonitor(StateMachine wifiStateMachine, WifiNative wifiNative) {
         if (DBG) Log.d(TAG, "Creating WifiMonitor");
         mWifiNative = wifiNative;
         mInterfaceName = wifiNative.mInterfaceName;
-        mWifiStateMachine = wifiStateMachine;
+        mStateMachine = wifiStateMachine;
         mMonitoring = false;
 
-        WifiMonitorSingleton.getMonitor().registerInterfaceMonitor(mInterfaceName, this);
+        WifiMonitorSingleton.sInstance.registerInterfaceMonitor(mInterfaceName, this);
     }
 
     public void startMonitoring() {
-        WifiMonitorSingleton.getMonitor().startMonitoring(mInterfaceName);
+        WifiMonitorSingleton.sInstance.startMonitoring(mInterfaceName);
     }
 
     public void stopMonitoring() {
-        WifiMonitorSingleton.getMonitor().stopMonitoring(mInterfaceName);
+        WifiMonitorSingleton.sInstance.stopMonitoring(mInterfaceName);
     }
 
     public void stopSupplicant() {
-        WifiMonitorSingleton.getMonitor().stopSupplicant();
+        WifiMonitorSingleton.sInstance.stopSupplicant();
     }
 
     public void killSupplicant(boolean p2pSupported) {
-        WifiMonitorSingleton.getMonitor().killSupplicant(p2pSupported);
+        WifiMonitorSingleton.sInstance.killSupplicant(p2pSupported);
     }
 
     private static class WifiMonitorSingleton {
-        private static Object sSingletonLock = new Object();
-        private static WifiMonitorSingleton sWifiMonitorSingleton = null;
-        private HashMap<String, WifiMonitor> mIfaceMap = new HashMap<String, WifiMonitor>();
+        private static final WifiMonitorSingleton sInstance = new WifiMonitorSingleton();
+
+        private final HashMap<String, WifiMonitor> mIfaceMap = new HashMap<String, WifiMonitor>();
         private boolean mConnected = false;
         private WifiNative mWifiNative;
 
         private WifiMonitorSingleton() {
         }
 
-        static WifiMonitorSingleton getMonitor() {
-            if (DBG) Log.d(TAG, "WifiMonitorSingleton gotten");
-            synchronized (sSingletonLock) {
-                if (sWifiMonitorSingleton == null) {
-                    if (DBG) Log.d(TAG, "WifiMonitorSingleton created");
-                    sWifiMonitorSingleton = new WifiMonitorSingleton();
-                }
-            }
-            return sWifiMonitorSingleton;
-        }
-
         public synchronized void startMonitoring(String iface) {
             WifiMonitor m = mIfaceMap.get(iface);
             if (m == null) {
@@ -415,14 +407,14 @@
 
             if (mConnected) {
                 m.mMonitoring = true;
-                m.mWifiStateMachine.sendMessage(SUP_CONNECTION_EVENT);
+                m.mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
             } else {
                 if (DBG) Log.d(TAG, "connecting to supplicant");
                 int connectTries = 0;
                 while (true) {
                     if (mWifiNative.connectToSupplicant()) {
                         m.mMonitoring = true;
-                        m.mWifiStateMachine.sendMessage(SUP_CONNECTION_EVENT);
+                        m.mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
                         new MonitorThread(mWifiNative, this).start();
                         mConnected = true;
                         break;
@@ -434,7 +426,7 @@
                         }
                     } else {
                         mIfaceMap.remove(iface);
-                        m.mWifiStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
+                        m.mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
                         Log.e(TAG, "startMonitoring(" + iface + ") failed!");
                         break;
                     }
@@ -444,13 +436,13 @@
 
         public synchronized void stopMonitoring(String iface) {
             WifiMonitor m = mIfaceMap.get(iface);
-            if (DBG) Log.d(TAG, "stopMonitoring(" + iface + ") = " + m.mWifiStateMachine);
+            if (DBG) Log.d(TAG, "stopMonitoring(" + iface + ") = " + m.mStateMachine);
             m.mMonitoring = false;
-            m.mWifiStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
+            m.mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
         }
 
         public synchronized void registerInterfaceMonitor(String iface, WifiMonitor m) {
-            if (DBG) Log.d(TAG, "registerInterface(" + iface + "+" + m.mWifiStateMachine + ")");
+            if (DBG) Log.d(TAG, "registerInterface(" + iface + "+" + m.mStateMachine + ")");
             mIfaceMap.put(iface, m);
             if (mWifiNative == null) {
                 mWifiNative = m.mWifiNative;
@@ -462,7 +454,7 @@
             // objects will remain in the mIfaceMap; and won't ever get deleted
 
             WifiMonitor m = mIfaceMap.remove(iface);
-            if (DBG) Log.d(TAG, "unregisterInterface(" + iface + "+" + m.mWifiStateMachine + ")");
+            if (DBG) Log.d(TAG, "unregisterInterface(" + iface + "+" + m.mStateMachine + ")");
         }
 
         public synchronized void stopSupplicant() {
@@ -470,26 +462,74 @@
         }
 
         public synchronized void killSupplicant(boolean p2pSupported) {
-            mWifiNative.killSupplicant(p2pSupported);
+            WifiNative.killSupplicant(p2pSupported);
             mConnected = false;
-            Iterator<Map.Entry<String, WifiMonitor>> it = mIfaceMap.entrySet().iterator();
-            while (it.hasNext()) {
-                Map.Entry<String, WifiMonitor> e = it.next();
-                WifiMonitor m = e.getValue();
+            for (WifiMonitor m : mIfaceMap.values()) {
                 m.mMonitoring = false;
             }
         }
 
-        private synchronized WifiMonitor getMonitor(String iface) {
-            return mIfaceMap.get(iface);
+        private synchronized boolean dispatchEvent(String eventStr) {
+            String iface;
+            if (eventStr.startsWith("IFNAME=")) {
+                int space = eventStr.indexOf(' ');
+                if (space != -1) {
+                    iface = eventStr.substring(7, space);
+                    if (!mIfaceMap.containsKey(iface) && iface.startsWith("p2p-")) {
+                        // p2p interfaces are created dynamically, but we have
+                        // only one P2p state machine monitoring all of them; look
+                        // for it explicitly, and send messages there ..
+                        iface = "p2p0";
+                    }
+                    eventStr = eventStr.substring(space + 1);
+                } else {
+                    // No point dispatching this event to any interface, the dispatched
+                    // event string will begin with "IFNAME=" which dispatchEvent can't really
+                    // do anything about.
+                    Log.e(TAG, "Dropping malformed event (unparsable iface): " + eventStr);
+                    return false;
+                }
+            } else {
+                // events without prefix belong to p2p0 monitor
+                iface = "p2p0";
+            }
+
+            if (DBG) Log.d(TAG, "Dispatching event to interface: " + iface);
+
+            WifiMonitor m = mIfaceMap.get(iface);
+            if (m != null) {
+                if (m.mMonitoring) {
+                    if (m.dispatchEvent(eventStr)) {
+                        mConnected = false;
+                        return true;
+                    }
+
+                    return false;
+                } else {
+                    if (DBG) Log.d(TAG, "Dropping event because (" + iface + ") is stopped");
+                    return false;
+                }
+            } else {
+                if (DBG) Log.d(TAG, "Sending to all monitors because there's no matching iface");
+                boolean done = false;
+                for (WifiMonitor monitor : mIfaceMap.values()) {
+                    if (monitor.mMonitoring && monitor.dispatchEvent(eventStr)) {
+                        done = true;
+                    }
+                }
+
+                if (done) {
+                    mConnected = false;
+                }
+
+                return done;
+            }
         }
     }
 
     private static class MonitorThread extends Thread {
         private final WifiNative mWifiNative;
         private final WifiMonitorSingleton mWifiMonitorSingleton;
-        private int mRecvErrors = 0;
-        private StateMachine mStateMachine = null;
 
         public MonitorThread(WifiNative wifiNative, WifiMonitorSingleton wifiMonitorSingleton) {
             super("WifiMonitor");
@@ -507,445 +547,390 @@
                     Log.d(TAG, "Event [" + eventStr + "]");
                 }
 
-                String iface = "p2p0";
-                WifiMonitor m = null;
-                mStateMachine = null;
-
-                if (eventStr.startsWith("IFNAME=")) {
-                    int space = eventStr.indexOf(' ');
-                    if (space != -1) {
-                        iface = eventStr.substring(7,space);
-                        m = mWifiMonitorSingleton.getMonitor(iface);
-                        if (m == null && iface.startsWith("p2p-")) {
-                            // p2p interfaces are created dynamically, but we have
-                            // only one P2p state machine monitoring all of them; look
-                            // for it explicitly, and send messages there ..
-                            m = mWifiMonitorSingleton.getMonitor("p2p0");
-                        }
-                        eventStr = eventStr.substring(space + 1);
-                    }
-                } else {
-                    // events without prefix belong to p2p0 monitor
-                    m = mWifiMonitorSingleton.getMonitor("p2p0");
-                }
-
-                if (m != null) {
-                    if (m.mMonitoring) {
-                        mStateMachine = m.mWifiStateMachine;
-                    } else {
-                        if (DBG) Log.d(TAG, "Dropping event because monitor (" + iface +
-                                            ") is stopped");
-                        continue;
-                    }
-                }
-
-                if (mStateMachine != null) {
-                    if (dispatchEvent(eventStr)) {
-                        break;
-                    }
-                } else {
-                    if (DBG) Log.d(TAG, "Sending to all monitors because there's no interface id");
-                    boolean done = false;
-                    Iterator<Map.Entry<String, WifiMonitor>> it =
-                            mWifiMonitorSingleton.mIfaceMap.entrySet().iterator();
-                    while (it.hasNext()) {
-                        Map.Entry<String, WifiMonitor> e = it.next();
-                        m = e.getValue();
-                        mStateMachine = m.mWifiStateMachine;
-                        if (dispatchEvent(eventStr)) {
-                            done = true;
-                        }
-                    }
-
-                    if (done) {
-                        // After this thread terminates, we'll no longer
-                        // be connected to the supplicant
-                        if (DBG) Log.d(TAG, "Disconnecting from the supplicant, no more events");
-                        mWifiMonitorSingleton.mConnected = false;
-                        break;
-                    }
+                if (mWifiMonitorSingleton.dispatchEvent(eventStr)) {
+                    if (DBG) Log.d(TAG, "Disconnecting from the supplicant, no more events");
+                    break;
                 }
             }
         }
+    }
 
-        /* @return true if the event was supplicant disconnection */
-        private boolean dispatchEvent(String eventStr) {
+    /* @return true if the event was supplicant disconnection */
+    private boolean dispatchEvent(String eventStr) {
 
-            if (!eventStr.startsWith(EVENT_PREFIX_STR)) {
-                if (eventStr.startsWith(WPA_EVENT_PREFIX_STR) &&
-                        0 < eventStr.indexOf(PASSWORD_MAY_BE_INCORRECT_STR)) {
-                    mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
-                } else if (eventStr.startsWith(WPS_SUCCESS_STR)) {
-                    mStateMachine.sendMessage(WPS_SUCCESS_EVENT);
-                } else if (eventStr.startsWith(WPS_FAIL_STR)) {
-                    handleWpsFailEvent(eventStr);
-                } else if (eventStr.startsWith(WPS_OVERLAP_STR)) {
-                    mStateMachine.sendMessage(WPS_OVERLAP_EVENT);
-                } else if (eventStr.startsWith(WPS_TIMEOUT_STR)) {
-                    mStateMachine.sendMessage(WPS_TIMEOUT_EVENT);
-                } else if (eventStr.startsWith(P2P_EVENT_PREFIX_STR)) {
-                    handleP2pEvents(eventStr);
-                } else if (eventStr.startsWith(HOST_AP_EVENT_PREFIX_STR)) {
-                    handleHostApEvents(eventStr);
-                }
-                else {
-                    if (DBG) Log.w(TAG, "couldn't identify event type - " + eventStr);
-                }
-                return false;
+        if (!eventStr.startsWith(EVENT_PREFIX_STR)) {
+            if (eventStr.startsWith(WPA_EVENT_PREFIX_STR) &&
+                    0 < eventStr.indexOf(PASSWORD_MAY_BE_INCORRECT_STR)) {
+                mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
+            } else if (eventStr.startsWith(WPS_SUCCESS_STR)) {
+                mStateMachine.sendMessage(WPS_SUCCESS_EVENT);
+            } else if (eventStr.startsWith(WPS_FAIL_STR)) {
+                handleWpsFailEvent(eventStr);
+            } else if (eventStr.startsWith(WPS_OVERLAP_STR)) {
+                mStateMachine.sendMessage(WPS_OVERLAP_EVENT);
+            } else if (eventStr.startsWith(WPS_TIMEOUT_STR)) {
+                mStateMachine.sendMessage(WPS_TIMEOUT_EVENT);
+            } else if (eventStr.startsWith(P2P_EVENT_PREFIX_STR)) {
+                handleP2pEvents(eventStr);
+            } else if (eventStr.startsWith(HOST_AP_EVENT_PREFIX_STR)) {
+                handleHostApEvents(eventStr);
             }
-
-            String eventName = eventStr.substring(EVENT_PREFIX_LEN_STR);
-            int nameEnd = eventName.indexOf(' ');
-            if (nameEnd != -1)
-                eventName = eventName.substring(0, nameEnd);
-            if (eventName.length() == 0) {
-                if (DBG) Log.i(TAG, "Received wpa_supplicant event with empty event name");
-                return false;
+            else {
+                if (DBG) Log.w(TAG, "couldn't identify event type - " + eventStr);
             }
-            /*
-             * Map event name into event enum
-             */
-            int event;
-            if (eventName.equals(CONNECTED_STR))
-                event = CONNECTED;
-            else if (eventName.equals(DISCONNECTED_STR))
-                event = DISCONNECTED;
-            else if (eventName.equals(STATE_CHANGE_STR))
-                event = STATE_CHANGE;
-            else if (eventName.equals(SCAN_RESULTS_STR))
-                event = SCAN_RESULTS;
-            else if (eventName.equals(LINK_SPEED_STR))
-                event = LINK_SPEED;
-            else if (eventName.equals(TERMINATING_STR))
-                event = TERMINATING;
-            else if (eventName.equals(DRIVER_STATE_STR))
-                event = DRIVER_STATE;
-            else if (eventName.equals(EAP_FAILURE_STR))
-                event = EAP_FAILURE;
-            else if (eventName.equals(ASSOC_REJECT_STR))
-                event = ASSOC_REJECT;
-            else
-                event = UNKNOWN;
-
-            String eventData = eventStr;
-            if (event == DRIVER_STATE || event == LINK_SPEED)
-                eventData = eventData.split(" ")[1];
-            else if (event == STATE_CHANGE || event == EAP_FAILURE) {
-                int ind = eventStr.indexOf(" ");
-                if (ind != -1) {
-                    eventData = eventStr.substring(ind + 1);
-                }
-            } else {
-                int ind = eventStr.indexOf(" - ");
-                if (ind != -1) {
-                    eventData = eventStr.substring(ind + 3);
-                }
-            }
-
-            if (event == STATE_CHANGE) {
-                handleSupplicantStateChange(eventData);
-            } else if (event == DRIVER_STATE) {
-                handleDriverEvent(eventData);
-            } else if (event == TERMINATING) {
-                /**
-                 * Close the supplicant connection if we see
-                 * too many recv errors
-                 */
-                if (eventData.startsWith(WPA_RECV_ERROR_STR)) {
-                    if (++mRecvErrors > MAX_RECV_ERRORS) {
-                        if (DBG) {
-                            Log.d(TAG, "too many recv errors, closing connection");
-                        }
-                    } else {
-                        return false;
-                    }
-                }
-
-                // notify and exit
-                mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
-                return true;
-            } else if (event == EAP_FAILURE) {
-                if (eventData.startsWith(EAP_AUTH_FAILURE_STR)) {
-                    mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
-                }
-            } else if (event == ASSOC_REJECT) {
-                mStateMachine.sendMessage(ASSOCIATION_REJECTION_EVENT);
-            } else {
-                handleEvent(event, eventData);
-            }
-            mRecvErrors = 0;
             return false;
         }
 
-        private void handleDriverEvent(String state) {
-            if (state == null) {
-                return;
+        String eventName = eventStr.substring(EVENT_PREFIX_LEN_STR);
+        int nameEnd = eventName.indexOf(' ');
+        if (nameEnd != -1)
+            eventName = eventName.substring(0, nameEnd);
+        if (eventName.length() == 0) {
+            if (DBG) Log.i(TAG, "Received wpa_supplicant event with empty event name");
+            return false;
+        }
+        /*
+        * Map event name into event enum
+        */
+        int event;
+        if (eventName.equals(CONNECTED_STR))
+            event = CONNECTED;
+        else if (eventName.equals(DISCONNECTED_STR))
+            event = DISCONNECTED;
+        else if (eventName.equals(STATE_CHANGE_STR))
+            event = STATE_CHANGE;
+        else if (eventName.equals(SCAN_RESULTS_STR))
+            event = SCAN_RESULTS;
+        else if (eventName.equals(LINK_SPEED_STR))
+            event = LINK_SPEED;
+        else if (eventName.equals(TERMINATING_STR))
+            event = TERMINATING;
+        else if (eventName.equals(DRIVER_STATE_STR))
+            event = DRIVER_STATE;
+        else if (eventName.equals(EAP_FAILURE_STR))
+            event = EAP_FAILURE;
+        else if (eventName.equals(ASSOC_REJECT_STR))
+            event = ASSOC_REJECT;
+        else
+            event = UNKNOWN;
+
+        String eventData = eventStr;
+        if (event == DRIVER_STATE || event == LINK_SPEED)
+            eventData = eventData.split(" ")[1];
+        else if (event == STATE_CHANGE || event == EAP_FAILURE) {
+            int ind = eventStr.indexOf(" ");
+            if (ind != -1) {
+                eventData = eventStr.substring(ind + 1);
             }
-            if (state.equals("HANGED")) {
-                mStateMachine.sendMessage(DRIVER_HUNG_EVENT);
+        } else {
+            int ind = eventStr.indexOf(" - ");
+            if (ind != -1) {
+                eventData = eventStr.substring(ind + 3);
             }
         }
 
-        /**
-         * Handle all supplicant events except STATE-CHANGE
-         * @param event the event type
-         * @param remainder the rest of the string following the
-         * event name and &quot;&#8195;&#8212;&#8195;&quot;
-         */
-        void handleEvent(int event, String remainder) {
-            switch (event) {
-                case DISCONNECTED:
-                    handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED, remainder);
-                    break;
-
-                case CONNECTED:
-                    handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder);
-                    break;
-
-                case SCAN_RESULTS:
-                    mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
-                    break;
-
-                case UNKNOWN:
-                    break;
-            }
-        }
-
-        private void handleWpsFailEvent(String dataString) {
-            final Pattern p = Pattern.compile(WPS_FAIL_PATTERN);
-            Matcher match = p.matcher(dataString);
-            if (match.find()) {
-                String cfgErr = match.group(1);
-                String reason = match.group(2);
-
-                if (reason != null) {
-                    switch(Integer.parseInt(reason)) {
-                        case REASON_TKIP_ONLY_PROHIBITED:
-                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
-                                    WifiManager.WPS_TKIP_ONLY_PROHIBITED, 0));
-                            return;
-                        case REASON_WEP_PROHIBITED:
-                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
-                                    WifiManager.WPS_WEP_PROHIBITED, 0));
-                            return;
+        if (event == STATE_CHANGE) {
+            handleSupplicantStateChange(eventData);
+        } else if (event == DRIVER_STATE) {
+            handleDriverEvent(eventData);
+        } else if (event == TERMINATING) {
+            /**
+             * Close the supplicant connection if we see
+             * too many recv errors
+             */
+            if (eventData.startsWith(WPA_RECV_ERROR_STR)) {
+                if (++sRecvErrors > MAX_RECV_ERRORS) {
+                    if (DBG) {
+                        Log.d(TAG, "too many recv errors, closing connection");
                     }
-                }
-                if (cfgErr != null) {
-                    switch(Integer.parseInt(cfgErr)) {
-                        case CONFIG_AUTH_FAILURE:
-                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
-                                    WifiManager.WPS_AUTH_FAILURE, 0));
-                            return;
-                        case CONFIG_MULTIPLE_PBC_DETECTED:
-                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
-                                    WifiManager.WPS_OVERLAP_ERROR, 0));
-                            return;
-                    }
-                }
-            }
-            //For all other errors, return a generic internal error
-            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
-                    WifiManager.ERROR, 0));
-        }
-
-        /* <event> status=<err> and the special case of <event> reason=FREQ_CONFLICT */
-        private P2pStatus p2pError(String dataString) {
-            P2pStatus err = P2pStatus.UNKNOWN;
-            String[] tokens = dataString.split(" ");
-            if (tokens.length < 2) return err;
-            String[] nameValue = tokens[1].split("=");
-            if (nameValue.length != 2) return err;
-
-            /* Handle the special case of reason=FREQ+CONFLICT */
-            if (nameValue[1].equals("FREQ_CONFLICT")) {
-                return P2pStatus.NO_COMMON_CHANNEL;
-            }
-            try {
-                err = P2pStatus.valueOf(Integer.parseInt(nameValue[1]));
-            } catch (NumberFormatException e) {
-                e.printStackTrace();
-            }
-            return err;
-        }
-
-        /**
-         * Handle p2p events
-         */
-        private void handleP2pEvents(String dataString) {
-            if (dataString.startsWith(P2P_DEVICE_FOUND_STR)) {
-                mStateMachine.sendMessage(P2P_DEVICE_FOUND_EVENT, new WifiP2pDevice(dataString));
-            } else if (dataString.startsWith(P2P_DEVICE_LOST_STR)) {
-                mStateMachine.sendMessage(P2P_DEVICE_LOST_EVENT, new WifiP2pDevice(dataString));
-            } else if (dataString.startsWith(P2P_FIND_STOPPED_STR)) {
-                mStateMachine.sendMessage(P2P_FIND_STOPPED_EVENT);
-            } else if (dataString.startsWith(P2P_GO_NEG_REQUEST_STR)) {
-                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_REQUEST_EVENT,
-                        new WifiP2pConfig(dataString));
-            } else if (dataString.startsWith(P2P_GO_NEG_SUCCESS_STR)) {
-                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_SUCCESS_EVENT);
-            } else if (dataString.startsWith(P2P_GO_NEG_FAILURE_STR)) {
-                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_FAILURE_EVENT, p2pError(dataString));
-            } else if (dataString.startsWith(P2P_GROUP_FORMATION_SUCCESS_STR)) {
-                mStateMachine.sendMessage(P2P_GROUP_FORMATION_SUCCESS_EVENT);
-            } else if (dataString.startsWith(P2P_GROUP_FORMATION_FAILURE_STR)) {
-                mStateMachine.sendMessage(P2P_GROUP_FORMATION_FAILURE_EVENT, p2pError(dataString));
-            } else if (dataString.startsWith(P2P_GROUP_STARTED_STR)) {
-                mStateMachine.sendMessage(P2P_GROUP_STARTED_EVENT, new WifiP2pGroup(dataString));
-            } else if (dataString.startsWith(P2P_GROUP_REMOVED_STR)) {
-                mStateMachine.sendMessage(P2P_GROUP_REMOVED_EVENT, new WifiP2pGroup(dataString));
-            } else if (dataString.startsWith(P2P_INVITATION_RECEIVED_STR)) {
-                mStateMachine.sendMessage(P2P_INVITATION_RECEIVED_EVENT,
-                        new WifiP2pGroup(dataString));
-            } else if (dataString.startsWith(P2P_INVITATION_RESULT_STR)) {
-                mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, p2pError(dataString));
-            } else if (dataString.startsWith(P2P_PROV_DISC_PBC_REQ_STR)) {
-                mStateMachine.sendMessage(P2P_PROV_DISC_PBC_REQ_EVENT,
-                        new WifiP2pProvDiscEvent(dataString));
-            } else if (dataString.startsWith(P2P_PROV_DISC_PBC_RSP_STR)) {
-                mStateMachine.sendMessage(P2P_PROV_DISC_PBC_RSP_EVENT,
-                        new WifiP2pProvDiscEvent(dataString));
-            } else if (dataString.startsWith(P2P_PROV_DISC_ENTER_PIN_STR)) {
-                mStateMachine.sendMessage(P2P_PROV_DISC_ENTER_PIN_EVENT,
-                        new WifiP2pProvDiscEvent(dataString));
-            } else if (dataString.startsWith(P2P_PROV_DISC_SHOW_PIN_STR)) {
-                mStateMachine.sendMessage(P2P_PROV_DISC_SHOW_PIN_EVENT,
-                        new WifiP2pProvDiscEvent(dataString));
-            } else if (dataString.startsWith(P2P_PROV_DISC_FAILURE_STR)) {
-                mStateMachine.sendMessage(P2P_PROV_DISC_FAILURE_EVENT);
-            } else if (dataString.startsWith(P2P_SERV_DISC_RESP_STR)) {
-                List<WifiP2pServiceResponse> list = WifiP2pServiceResponse.newInstance(dataString);
-                if (list != null) {
-                    mStateMachine.sendMessage(P2P_SERV_DISC_RESP_EVENT, list);
                 } else {
-                    Log.e(TAG, "Null service resp " + dataString);
+                    return false;
+                }
+            }
+
+            // notify and exit
+            mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
+            return true;
+        } else if (event == EAP_FAILURE) {
+            if (eventData.startsWith(EAP_AUTH_FAILURE_STR)) {
+                mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
+            }
+        } else if (event == ASSOC_REJECT) {
+            mStateMachine.sendMessage(ASSOCIATION_REJECTION_EVENT);
+        } else {
+            handleEvent(event, eventData);
+        }
+        sRecvErrors = 0;
+        return false;
+    }
+
+    private void handleDriverEvent(String state) {
+        if (state == null) {
+            return;
+        }
+        if (state.equals("HANGED")) {
+            mStateMachine.sendMessage(DRIVER_HUNG_EVENT);
+        }
+    }
+
+    /**
+     * Handle all supplicant events except STATE-CHANGE
+     * @param event the event type
+     * @param remainder the rest of the string following the
+     * event name and &quot;&#8195;&#8212;&#8195;&quot;
+     */
+    void handleEvent(int event, String remainder) {
+        switch (event) {
+            case DISCONNECTED:
+                handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED, remainder);
+                break;
+
+            case CONNECTED:
+                handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder);
+                break;
+
+            case SCAN_RESULTS:
+                mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
+                break;
+
+            case UNKNOWN:
+                break;
+        }
+    }
+
+    private void handleWpsFailEvent(String dataString) {
+        final Pattern p = Pattern.compile(WPS_FAIL_PATTERN);
+        Matcher match = p.matcher(dataString);
+        if (match.find()) {
+            String cfgErr = match.group(1);
+            String reason = match.group(2);
+
+            if (reason != null) {
+                switch(Integer.parseInt(reason)) {
+                    case REASON_TKIP_ONLY_PROHIBITED:
+                        mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
+                                WifiManager.WPS_TKIP_ONLY_PROHIBITED, 0));
+                        return;
+                    case REASON_WEP_PROHIBITED:
+                        mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
+                                WifiManager.WPS_WEP_PROHIBITED, 0));
+                        return;
+                }
+            }
+            if (cfgErr != null) {
+                switch(Integer.parseInt(cfgErr)) {
+                    case CONFIG_AUTH_FAILURE:
+                        mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
+                                WifiManager.WPS_AUTH_FAILURE, 0));
+                        return;
+                    case CONFIG_MULTIPLE_PBC_DETECTED:
+                        mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
+                                WifiManager.WPS_OVERLAP_ERROR, 0));
+                        return;
                 }
             }
         }
+        //For all other errors, return a generic internal error
+        mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
+                WifiManager.ERROR, 0));
+    }
 
-        /**
-         * Handle hostap events
-         */
-        private void handleHostApEvents(String dataString) {
-            String[] tokens = dataString.split(" ");
-            /* AP-STA-CONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=02:90:4c:a0:92:54 */
-            if (tokens[0].equals(AP_STA_CONNECTED_STR)) {
-                mStateMachine.sendMessage(AP_STA_CONNECTED_EVENT, new WifiP2pDevice(dataString));
-            /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=02:90:4c:a0:92:54 */
-            } else if (tokens[0].equals(AP_STA_DISCONNECTED_STR)) {
-                mStateMachine.sendMessage(AP_STA_DISCONNECTED_EVENT, new WifiP2pDevice(dataString));
-            }
+    /* <event> status=<err> and the special case of <event> reason=FREQ_CONFLICT */
+    private P2pStatus p2pError(String dataString) {
+        P2pStatus err = P2pStatus.UNKNOWN;
+        String[] tokens = dataString.split(" ");
+        if (tokens.length < 2) return err;
+        String[] nameValue = tokens[1].split("=");
+        if (nameValue.length != 2) return err;
+
+        /* Handle the special case of reason=FREQ+CONFLICT */
+        if (nameValue[1].equals("FREQ_CONFLICT")) {
+            return P2pStatus.NO_COMMON_CHANNEL;
         }
-
-        /**
-         * Handle the supplicant STATE-CHANGE event
-         * @param dataString New supplicant state string in the format:
-         * id=network-id state=new-state
-         */
-        private void handleSupplicantStateChange(String dataString) {
-            WifiSsid wifiSsid = null;
-            int index = dataString.lastIndexOf("SSID=");
-            if (index != -1) {
-                wifiSsid = WifiSsid.createFromAsciiEncoded(
-                        dataString.substring(index + 5));
-            }
-            String[] dataTokens = dataString.split(" ");
-
-            String BSSID = null;
-            int networkId = -1;
-            int newState  = -1;
-            for (String token : dataTokens) {
-                String[] nameValue = token.split("=");
-                if (nameValue.length != 2) {
-                    continue;
-                }
-
-                if (nameValue[0].equals("BSSID")) {
-                    BSSID = nameValue[1];
-                    continue;
-                }
-
-                int value;
-                try {
-                    value = Integer.parseInt(nameValue[1]);
-                } catch (NumberFormatException e) {
-                    continue;
-                }
-
-                if (nameValue[0].equals("id")) {
-                    networkId = value;
-                } else if (nameValue[0].equals("state")) {
-                    newState = value;
-                }
-            }
-
-            if (newState == -1) return;
-
-            SupplicantState newSupplicantState = SupplicantState.INVALID;
-            for (SupplicantState state : SupplicantState.values()) {
-                if (state.ordinal() == newState) {
-                    newSupplicantState = state;
-                    break;
-                }
-            }
-            if (newSupplicantState == SupplicantState.INVALID) {
-                Log.w(TAG, "Invalid supplicant state: " + newState);
-            }
-            notifySupplicantStateChange(networkId, wifiSsid, BSSID, newSupplicantState);
+        try {
+            err = P2pStatus.valueOf(Integer.parseInt(nameValue[1]));
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
         }
+        return err;
+    }
 
-        private void handleNetworkStateChange(NetworkInfo.DetailedState newState, String data) {
-            String BSSID = null;
-            int networkId = -1;
-            if (newState == NetworkInfo.DetailedState.CONNECTED) {
-                Matcher match = mConnectedEventPattern.matcher(data);
-                if (!match.find()) {
-                    if (DBG) Log.d(TAG, "Could not find BSSID in CONNECTED event string");
-                } else {
-                    BSSID = match.group(1);
-                    try {
-                        networkId = Integer.parseInt(match.group(2));
-                    } catch (NumberFormatException e) {
-                        networkId = -1;
-                    }
-                }
-                notifyNetworkStateChange(newState, BSSID, networkId);
-            }
-        }
-
-        /**
-         * Send the state machine a notification that the state of Wifi connectivity
-         * has changed.
-         * @param networkId the configured network on which the state change occurred
-         * @param newState the new network state
-         * @param BSSID when the new state is {@link DetailedState#CONNECTED
-         * NetworkInfo.DetailedState.CONNECTED},
-         * this is the MAC address of the access point. Otherwise, it
-         * is {@code null}.
-         */
-        void notifyNetworkStateChange(NetworkInfo.DetailedState newState, String BSSID, int netId) {
-            if (newState == NetworkInfo.DetailedState.CONNECTED) {
-                Message m = mStateMachine.obtainMessage(NETWORK_CONNECTION_EVENT,
-                        netId, 0, BSSID);
-                mStateMachine.sendMessage(m);
+    /**
+     * Handle p2p events
+     */
+    private void handleP2pEvents(String dataString) {
+        if (dataString.startsWith(P2P_DEVICE_FOUND_STR)) {
+            mStateMachine.sendMessage(P2P_DEVICE_FOUND_EVENT, new WifiP2pDevice(dataString));
+        } else if (dataString.startsWith(P2P_DEVICE_LOST_STR)) {
+            mStateMachine.sendMessage(P2P_DEVICE_LOST_EVENT, new WifiP2pDevice(dataString));
+        } else if (dataString.startsWith(P2P_FIND_STOPPED_STR)) {
+            mStateMachine.sendMessage(P2P_FIND_STOPPED_EVENT);
+        } else if (dataString.startsWith(P2P_GO_NEG_REQUEST_STR)) {
+            mStateMachine.sendMessage(P2P_GO_NEGOTIATION_REQUEST_EVENT,
+                    new WifiP2pConfig(dataString));
+        } else if (dataString.startsWith(P2P_GO_NEG_SUCCESS_STR)) {
+            mStateMachine.sendMessage(P2P_GO_NEGOTIATION_SUCCESS_EVENT);
+        } else if (dataString.startsWith(P2P_GO_NEG_FAILURE_STR)) {
+            mStateMachine.sendMessage(P2P_GO_NEGOTIATION_FAILURE_EVENT, p2pError(dataString));
+        } else if (dataString.startsWith(P2P_GROUP_FORMATION_SUCCESS_STR)) {
+            mStateMachine.sendMessage(P2P_GROUP_FORMATION_SUCCESS_EVENT);
+        } else if (dataString.startsWith(P2P_GROUP_FORMATION_FAILURE_STR)) {
+            mStateMachine.sendMessage(P2P_GROUP_FORMATION_FAILURE_EVENT, p2pError(dataString));
+        } else if (dataString.startsWith(P2P_GROUP_STARTED_STR)) {
+            mStateMachine.sendMessage(P2P_GROUP_STARTED_EVENT, new WifiP2pGroup(dataString));
+        } else if (dataString.startsWith(P2P_GROUP_REMOVED_STR)) {
+            mStateMachine.sendMessage(P2P_GROUP_REMOVED_EVENT, new WifiP2pGroup(dataString));
+        } else if (dataString.startsWith(P2P_INVITATION_RECEIVED_STR)) {
+            mStateMachine.sendMessage(P2P_INVITATION_RECEIVED_EVENT,
+                    new WifiP2pGroup(dataString));
+        } else if (dataString.startsWith(P2P_INVITATION_RESULT_STR)) {
+            mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, p2pError(dataString));
+        } else if (dataString.startsWith(P2P_PROV_DISC_PBC_REQ_STR)) {
+            mStateMachine.sendMessage(P2P_PROV_DISC_PBC_REQ_EVENT,
+                    new WifiP2pProvDiscEvent(dataString));
+        } else if (dataString.startsWith(P2P_PROV_DISC_PBC_RSP_STR)) {
+            mStateMachine.sendMessage(P2P_PROV_DISC_PBC_RSP_EVENT,
+                    new WifiP2pProvDiscEvent(dataString));
+        } else if (dataString.startsWith(P2P_PROV_DISC_ENTER_PIN_STR)) {
+            mStateMachine.sendMessage(P2P_PROV_DISC_ENTER_PIN_EVENT,
+                    new WifiP2pProvDiscEvent(dataString));
+        } else if (dataString.startsWith(P2P_PROV_DISC_SHOW_PIN_STR)) {
+            mStateMachine.sendMessage(P2P_PROV_DISC_SHOW_PIN_EVENT,
+                    new WifiP2pProvDiscEvent(dataString));
+        } else if (dataString.startsWith(P2P_PROV_DISC_FAILURE_STR)) {
+            mStateMachine.sendMessage(P2P_PROV_DISC_FAILURE_EVENT);
+        } else if (dataString.startsWith(P2P_SERV_DISC_RESP_STR)) {
+            List<WifiP2pServiceResponse> list = WifiP2pServiceResponse.newInstance(dataString);
+            if (list != null) {
+                mStateMachine.sendMessage(P2P_SERV_DISC_RESP_EVENT, list);
             } else {
-                Message m = mStateMachine.obtainMessage(NETWORK_DISCONNECTION_EVENT,
-                        netId, 0, BSSID);
-                mStateMachine.sendMessage(m);
+                Log.e(TAG, "Null service resp " + dataString);
+            }
+        }
+    }
+
+    /**
+     * Handle hostap events
+     */
+    private void handleHostApEvents(String dataString) {
+        String[] tokens = dataString.split(" ");
+        /* AP-STA-CONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=02:90:4c:a0:92:54 */
+        if (tokens[0].equals(AP_STA_CONNECTED_STR)) {
+            mStateMachine.sendMessage(AP_STA_CONNECTED_EVENT, new WifiP2pDevice(dataString));
+            /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=02:90:4c:a0:92:54 */
+        } else if (tokens[0].equals(AP_STA_DISCONNECTED_STR)) {
+            mStateMachine.sendMessage(AP_STA_DISCONNECTED_EVENT, new WifiP2pDevice(dataString));
+        }
+    }
+
+    /**
+     * Handle the supplicant STATE-CHANGE event
+     * @param dataString New supplicant state string in the format:
+     * id=network-id state=new-state
+     */
+    private void handleSupplicantStateChange(String dataString) {
+        WifiSsid wifiSsid = null;
+        int index = dataString.lastIndexOf("SSID=");
+        if (index != -1) {
+            wifiSsid = WifiSsid.createFromAsciiEncoded(
+                    dataString.substring(index + 5));
+        }
+        String[] dataTokens = dataString.split(" ");
+
+        String BSSID = null;
+        int networkId = -1;
+        int newState  = -1;
+        for (String token : dataTokens) {
+            String[] nameValue = token.split("=");
+            if (nameValue.length != 2) {
+                continue;
+            }
+
+            if (nameValue[0].equals("BSSID")) {
+                BSSID = nameValue[1];
+                continue;
+            }
+
+            int value;
+            try {
+                value = Integer.parseInt(nameValue[1]);
+            } catch (NumberFormatException e) {
+                continue;
+            }
+
+            if (nameValue[0].equals("id")) {
+                networkId = value;
+            } else if (nameValue[0].equals("state")) {
+                newState = value;
             }
         }
 
-        /**
-         * Send the state machine a notification that the state of the supplicant
-         * has changed.
-         * @param networkId the configured network on which the state change occurred
-         * @param wifiSsid network name
-         * @param BSSID network address
-         * @param newState the new {@code SupplicantState}
-         */
-        void notifySupplicantStateChange(int networkId, WifiSsid wifiSsid, String BSSID,
-                SupplicantState newState) {
-            mStateMachine.sendMessage(mStateMachine.obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
-                    new StateChangeResult(networkId, wifiSsid, BSSID, newState)));
+        if (newState == -1) return;
+
+        SupplicantState newSupplicantState = SupplicantState.INVALID;
+        for (SupplicantState state : SupplicantState.values()) {
+            if (state.ordinal() == newState) {
+                newSupplicantState = state;
+                break;
+            }
         }
+        if (newSupplicantState == SupplicantState.INVALID) {
+            Log.w(TAG, "Invalid supplicant state: " + newState);
+        }
+        notifySupplicantStateChange(networkId, wifiSsid, BSSID, newSupplicantState);
+    }
+
+    private void handleNetworkStateChange(NetworkInfo.DetailedState newState, String data) {
+        String BSSID = null;
+        int networkId = -1;
+        if (newState == NetworkInfo.DetailedState.CONNECTED) {
+            Matcher match = mConnectedEventPattern.matcher(data);
+            if (!match.find()) {
+                if (DBG) Log.d(TAG, "Could not find BSSID in CONNECTED event string");
+            } else {
+                BSSID = match.group(1);
+                try {
+                    networkId = Integer.parseInt(match.group(2));
+                } catch (NumberFormatException e) {
+                    networkId = -1;
+                }
+            }
+            notifyNetworkStateChange(newState, BSSID, networkId);
+        }
+    }
+
+    /**
+     * Send the state machine a notification that the state of Wifi connectivity
+     * has changed.
+     * @param newState the new network state
+     * @param BSSID when the new state is {@link NetworkInfo.DetailedState#CONNECTED},
+     * this is the MAC address of the access point. Otherwise, it
+     * is {@code null}.
+     * @param netId the configured network on which the state change occurred
+     */
+    void notifyNetworkStateChange(NetworkInfo.DetailedState newState, String BSSID, int netId) {
+        if (newState == NetworkInfo.DetailedState.CONNECTED) {
+            Message m = mStateMachine.obtainMessage(NETWORK_CONNECTION_EVENT,
+                    netId, 0, BSSID);
+            mStateMachine.sendMessage(m);
+        } else {
+            Message m = mStateMachine.obtainMessage(NETWORK_DISCONNECTION_EVENT,
+                    netId, 0, BSSID);
+            mStateMachine.sendMessage(m);
+        }
+    }
+
+    /**
+     * Send the state machine a notification that the state of the supplicant
+     * has changed.
+     * @param networkId the configured network on which the state change occurred
+     * @param wifiSsid network name
+     * @param BSSID network address
+     * @param newState the new {@code SupplicantState}
+     */
+    void notifySupplicantStateChange(int networkId, WifiSsid wifiSsid, String BSSID,
+            SupplicantState newState) {
+        mStateMachine.sendMessage(mStateMachine.obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
+                new StateChangeResult(networkId, wifiSsid, BSSID, newState)));
     }
 }
diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java
index a35a34b..f8ba95d 100644
--- a/wifi/java/android/net/wifi/WifiSsid.java
+++ b/wifi/java/android/net/wifi/WifiSsid.java
@@ -16,9 +16,8 @@
 
 package android.net.wifi;
 
-import android.os.Parcelable;
 import android.os.Parcel;
-import android.util.Log;
+import android.os.Parcelable;
 
 import java.io.ByteArrayOutputStream;
 import java.nio.ByteBuffer;
@@ -42,7 +41,7 @@
 public class WifiSsid implements Parcelable {
     private static final String TAG = "WifiSsid";
 
-    public ByteArrayOutputStream octets = new ByteArrayOutputStream(32);
+    public final ByteArrayOutputStream octets = new ByteArrayOutputStream(32);
 
     private static final int HEX_RADIX = 16;
     public static final String NONE = "<unknown ssid>";
@@ -58,7 +57,6 @@
 
     public static WifiSsid createFromHex(String hexStr) {
         WifiSsid a = new WifiSsid();
-        int length = 0;
         if (hexStr == null) return a;
 
         if (hexStr.startsWith("0x") || hexStr.startsWith("0X")) {
@@ -191,8 +189,13 @@
     }
 
     /** @hide */
+    public boolean isHidden() {
+        return isArrayAllZeroes(octets.toByteArray());
+    }
+
+    /** @hide */
     public byte[] getOctets() {
-        return  octets.toByteArray();
+        return octets.toByteArray();
     }
 
     /** @hide */
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index eedd66f..49fc75d 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -56,14 +56,12 @@
 import android.net.wifi.p2p.WifiP2pManager;
 import android.net.wifi.p2p.WifiP2pService;
 import android.os.BatteryStats;
-import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.Message;
 import android.os.Messenger;
 import android.os.PowerManager;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
@@ -71,7 +69,6 @@
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.provider.Settings;
-import android.util.Log;
 import android.util.LruCache;
 import android.text.TextUtils;
 
@@ -87,7 +84,6 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.net.InetAddress;
-import java.net.Inet6Address;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
@@ -242,24 +238,24 @@
         }
 
         @Override
-        public void addressUpdated(String address, String iface, int flags, int scope) {
+        public void addressUpdated(LinkAddress address, String iface, int flags, int scope) {
             if (mWifiStateMachine.mInterfaceName.equals(iface)) {
                 if (DBG) {
                     log("addressUpdated: " + address + " on " + iface +
                         " flags " + flags + " scope " + scope);
                 }
-                mWifiStateMachine.sendMessage(CMD_IP_ADDRESS_UPDATED, new LinkAddress(address));
+                mWifiStateMachine.sendMessage(CMD_IP_ADDRESS_UPDATED, address);
             }
         }
 
         @Override
-        public void addressRemoved(String address, String iface, int flags, int scope) {
+        public void addressRemoved(LinkAddress address, String iface, int flags, int scope) {
             if (mWifiStateMachine.mInterfaceName.equals(iface)) {
                 if (DBG) {
                     log("addressRemoved: " + address + " on " + iface +
                         " flags " + flags + " scope " + scope);
                 }
-                mWifiStateMachine.sendMessage(CMD_IP_ADDRESS_REMOVED, new LinkAddress(address));
+                mWifiStateMachine.sendMessage(CMD_IP_ADDRESS_REMOVED, address);
             }
         }
     }
@@ -305,8 +301,6 @@
     static final int CMD_DELAYED_STOP_DRIVER              = BASE + 18;
     /* A delayed message sent to start driver when it fail to come up */
     static final int CMD_DRIVER_START_TIMED_OUT           = BASE + 19;
-    /* Ready to switch to network as default */
-    static final int CMD_CAPTIVE_CHECK_COMPLETE           = BASE + 20;
 
     /* Start the soft access point */
     static final int CMD_START_AP                         = BASE + 21;
@@ -543,8 +537,6 @@
     private State mObtainingIpState = new ObtainingIpState();
     /* Waiting for link quality verification to be complete */
     private State mVerifyingLinkState = new VerifyingLinkState();
-    /* Waiting for captive portal check to be complete */
-    private State mCaptivePortalCheckState = new CaptivePortalCheckState();
     /* Connected with IP addr */
     private State mConnectedState = new ConnectedState();
     /* disconnect issued, waiting for network disconnect confirmation */
@@ -790,7 +782,6 @@
                         addState(mL2ConnectedState, mConnectModeState);
                             addState(mObtainingIpState, mL2ConnectedState);
                             addState(mVerifyingLinkState, mL2ConnectedState);
-                            addState(mCaptivePortalCheckState, mL2ConnectedState);
                             addState(mConnectedState, mL2ConnectedState);
                         addState(mDisconnectingState, mConnectModeState);
                         addState(mDisconnectedState, mConnectModeState);
@@ -1345,10 +1336,6 @@
         }
     }
 
-    public void captivePortalCheckComplete() {
-        sendMessage(CMD_CAPTIVE_CHECK_COMPLETE);
-    }
-
     /**
      * TODO: doc
      */
@@ -2528,7 +2515,6 @@
                 case CMD_STOP_DRIVER:
                 case CMD_DELAYED_STOP_DRIVER:
                 case CMD_DRIVER_START_TIMED_OUT:
-                case CMD_CAPTIVE_CHECK_COMPLETE:
                 case CMD_START_AP:
                 case CMD_START_AP_SUCCESS:
                 case CMD_START_AP_FAILURE:
@@ -3808,29 +3794,17 @@
                     break;
                 case WifiWatchdogStateMachine.GOOD_LINK_DETECTED:
                     log(getName() + " GOOD_LINK_DETECTED: transition to captive portal check");
-                    transitionTo(mCaptivePortalCheckState);
-                    break;
-                default:
-                    if (DBG) log(getName() + " what=" + message.what + " NOT_HANDLED");
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
+                    // Send out a broadcast with the CAPTIVE_PORTAL_CHECK to preserve
+                    // existing behaviour. The captive portal check really happens after we
+                    // transition into DetailedState.CONNECTED.
+                    setNetworkDetailedState(DetailedState.CAPTIVE_PORTAL_CHECK);
+                    mWifiConfigStore.updateStatus(mLastNetworkId,
+                            DetailedState.CAPTIVE_PORTAL_CHECK);
+                    sendNetworkStateChangeBroadcast(mLastBssid);
 
-    class CaptivePortalCheckState extends State {
-        @Override
-        public void enter() {
-            log(getName() + " enter");
-            setNetworkDetailedState(DetailedState.CAPTIVE_PORTAL_CHECK);
-            mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.CAPTIVE_PORTAL_CHECK);
-            sendNetworkStateChangeBroadcast(mLastBssid);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_CAPTIVE_CHECK_COMPLETE:
-                    log(getName() + " CMD_CAPTIVE_CHECK_COMPLETE");
+                    // NOTE: This might look like an odd place to enable IPV6 but this is in
+                    // response to transitioning into GOOD_LINK_DETECTED. Similarly, we disable
+                    // ipv6 when we transition into POOR_LINK_DETECTED in mConnectedState.
                     try {
                         mNwService.enableIpv6(mInterfaceName);
                     } catch (RemoteException re) {
@@ -3838,12 +3812,16 @@
                     } catch (IllegalStateException e) {
                         loge("Failed to enable IPv6: " + e);
                     }
+
+                    log(getName() + " GOOD_LINK_DETECTED: transition to CONNECTED");
                     setNetworkDetailedState(DetailedState.CONNECTED);
                     mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.CONNECTED);
                     sendNetworkStateChangeBroadcast(mLastBssid);
                     transitionTo(mConnectedState);
+
                     break;
                 default:
+                    if (DBG) log(getName() + " what=" + message.what + " NOT_HANDLED");
                     return NOT_HANDLED;
             }
             return HANDLED;
@@ -3875,6 +3853,7 @@
             }
             return HANDLED;
         }
+
         @Override
         public void exit() {
             /* Request a CS wakelock during transition to mobile */
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 615c893..7ded171 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -115,14 +115,6 @@
         return true;
     }
 
-    /**
-     * Captive check is complete, switch to network
-     */
-    @Override
-    public void captivePortalCheckComplete() {
-        mWifiManager.captivePortalCheckComplete();
-    }
-
     @Override
     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
         // not implemented
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index 6278c89..c2823e8 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -29,11 +29,8 @@
 import android.os.Message;
 import android.os.SystemClock;
 import android.provider.Settings;
-import android.provider.Settings.Secure;
-import android.util.Log;
 import android.util.LruCache;
 
-import com.android.internal.R;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
diff --git a/wifi/java/android/net/wifi/WpsInfo.java b/wifi/java/android/net/wifi/WpsInfo.java
index b80df21..2ad4ad0 100644
--- a/wifi/java/android/net/wifi/WpsInfo.java
+++ b/wifi/java/android/net/wifi/WpsInfo.java
@@ -19,8 +19,6 @@
 import android.os.Parcelable;
 import android.os.Parcel;
 
-import java.util.BitSet;
-
 /**
  * A class representing Wi-Fi Protected Setup
  *
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
index 0900351..fbcf09b 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
@@ -20,7 +20,6 @@
 import android.os.Parcel;
 import android.net.wifi.p2p.WifiP2pDevice;
 import android.text.TextUtils;
-import android.util.Log;
 
 import java.util.ArrayList;
 import java.util.Collection;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 4988b92..3ed2406 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -19,8 +19,6 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
 import android.net.wifi.WpsInfo;
 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo;
 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceResponse;
@@ -29,16 +27,12 @@
 import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo;
 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceResponse;
-import android.os.Binder;
 import android.os.Bundle;
-import android.os.IBinder;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.WorkSource;
 import android.text.TextUtils;
 import android.util.Log;
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java b/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
index b3f34b4..98683cb 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
@@ -16,10 +16,6 @@
 
 package android.net.wifi.p2p;
 
-import android.os.Parcelable;
-import android.os.Parcel;
-import android.util.Log;
-
 /**
  * A class representing a Wi-Fi p2p provisional discovery request/response
  * See {@link #WifiP2pProvDiscEvent} for supported types
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 8b07208..7803f7d 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -18,27 +18,20 @@
 
 import android.app.AlertDialog;
 import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.net.IConnectivityManager;
 import android.net.ConnectivityManager;
 import android.net.DhcpResults;
 import android.net.DhcpStateMachine;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
-import android.net.LinkProperties;
 import android.net.NetworkInfo;
 import android.net.NetworkUtils;
-import android.net.wifi.WifiManager;
 import android.net.wifi.WifiMonitor;
 import android.net.wifi.WifiNative;
 import android.net.wifi.WifiStateMachine;
@@ -51,13 +44,10 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
-import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -72,7 +62,6 @@
 import android.widget.TextView;
 
 import com.android.internal.R;
-import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
@@ -1092,6 +1081,7 @@
 
         @Override
         public void exit() {
+            sendP2pDiscoveryChangedBroadcast(false);
             sendP2pStateChangedBroadcast(false);
             mNetworkInfo.setIsAvailable(false);